// This code contains NVIDIA Confidential Information and is disclosed to you // under a form of NVIDIA software license agreement provided separately to you. // // Notice // NVIDIA Corporation and its licensors retain all intellectual property and // proprietary rights in and to this software and related documentation and // any modifications thereto. Any use, reproduction, disclosure, or // distribution of this software and related documentation without an express // license agreement from NVIDIA Corporation is strictly prohibited. // // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. // // Information and code furnished is believed to be accurate and reliable. // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such // information or for any infringement of patents or other rights of third parties that may // result from its use. No license is granted by implication or otherwise under any patent // or patent rights of NVIDIA Corporation. Details are subject to change without notice. // This code supersedes and replaces all information previously supplied. // NVIDIA Corporation products are not authorized for use as critical // components in life support devices or systems without express written approval of // NVIDIA Corporation. // // Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #include #include "SnippetVehicleSceneQuery.h" #include "PxPhysicsAPI.h" namespace snippetvehicle { using namespace physx; void setupDrivableSurface(PxFilterData& filterData) { filterData.word3 = static_cast(DRIVABLE_SURFACE); } void setupNonDrivableSurface(PxFilterData& filterData) { filterData.word3 = UNDRIVABLE_SURFACE; } PxQueryHitType::Enum WheelSceneQueryPreFilterBlocking (PxFilterData filterData0, PxFilterData filterData1, const void* constantBlock, PxU32 constantBlockSize, PxHitFlags& queryFlags) { //filterData0 is the vehicle suspension query. //filterData1 is the shape potentially hit by the query. PX_UNUSED(filterData0); PX_UNUSED(constantBlock); PX_UNUSED(constantBlockSize); PX_UNUSED(queryFlags); return ((0 == (filterData1.word3 & DRIVABLE_SURFACE)) ? PxQueryHitType::eNONE : PxQueryHitType::eBLOCK); } PxQueryHitType::Enum WheelSceneQueryPostFilterBlocking (PxFilterData filterData0, PxFilterData filterData1, const void* constantBlock, PxU32 constantBlockSize, const PxQueryHit& hit) { PX_UNUSED(filterData0); PX_UNUSED(filterData1); PX_UNUSED(constantBlock); PX_UNUSED(constantBlockSize); if((static_cast(hit)).hadInitialOverlap()) return PxQueryHitType::eNONE; return PxQueryHitType::eBLOCK; } PxQueryHitType::Enum WheelSceneQueryPreFilterNonBlocking (PxFilterData filterData0, PxFilterData filterData1, const void* constantBlock, PxU32 constantBlockSize, PxHitFlags& queryFlags) { //filterData0 is the vehicle suspension query. //filterData1 is the shape potentially hit by the query. PX_UNUSED(filterData0); PX_UNUSED(constantBlock); PX_UNUSED(constantBlockSize); PX_UNUSED(queryFlags); return ((0 == (filterData1.word3 & DRIVABLE_SURFACE)) ? PxQueryHitType::eNONE : PxQueryHitType::eTOUCH); } PxQueryHitType::Enum WheelSceneQueryPostFilterNonBlocking (PxFilterData filterData0, PxFilterData filterData1, const void* constantBlock, PxU32 constantBlockSize, const PxQueryHit& hit) { PX_UNUSED(filterData0); PX_UNUSED(filterData1); PX_UNUSED(constantBlock); PX_UNUSED(constantBlockSize); if ((static_cast(hit)).hadInitialOverlap()) return PxQueryHitType::eNONE; return PxQueryHitType::eTOUCH; } VehicleSceneQueryData::VehicleSceneQueryData() : mNumQueriesPerBatch(0), mNumHitResultsPerQuery(0), mRaycastResults(NULL), mRaycastHitBuffer(NULL), mPreFilterShader(NULL), mPostFilterShader(NULL) { } VehicleSceneQueryData::~VehicleSceneQueryData() { } VehicleSceneQueryData* VehicleSceneQueryData::allocate (const PxU32 maxNumVehicles, const PxU32 maxNumWheelsPerVehicle, const PxU32 maxNumHitPointsPerWheel, const PxU32 numVehiclesInBatch, PxBatchQueryPreFilterShader preFilterShader, PxBatchQueryPostFilterShader postFilterShader, PxAllocatorCallback& allocator) { const PxU32 sqDataSize = ((sizeof(VehicleSceneQueryData) + 15) & ~15); const PxU32 maxNumWheels = maxNumVehicles*maxNumWheelsPerVehicle; const PxU32 raycastResultSize = ((sizeof(PxRaycastQueryResult)*maxNumWheels + 15) & ~15); const PxU32 sweepResultSize = ((sizeof(PxSweepQueryResult)*maxNumWheels + 15) & ~15); const PxU32 maxNumHitPoints = maxNumWheels*maxNumHitPointsPerWheel; const PxU32 raycastHitSize = ((sizeof(PxRaycastHit)*maxNumHitPoints + 15) & ~15); const PxU32 sweepHitSize = ((sizeof(PxSweepHit)*maxNumHitPoints + 15) & ~15); const PxU32 size = sqDataSize + raycastResultSize + raycastHitSize + sweepResultSize + sweepHitSize; PxU8* buffer = static_cast(allocator.allocate(size, NULL, NULL, 0)); VehicleSceneQueryData* sqData = new(buffer) VehicleSceneQueryData(); sqData->mNumQueriesPerBatch = numVehiclesInBatch*maxNumWheelsPerVehicle; sqData->mNumHitResultsPerQuery = maxNumHitPointsPerWheel; buffer += sqDataSize; sqData->mRaycastResults = reinterpret_cast(buffer); buffer += raycastResultSize; sqData->mRaycastHitBuffer = reinterpret_cast(buffer); buffer += raycastHitSize; sqData->mSweepResults = reinterpret_cast(buffer); buffer += sweepResultSize; sqData->mSweepHitBuffer = reinterpret_cast(buffer); buffer += sweepHitSize; for (PxU32 i = 0; i < maxNumWheels; i++) { new(sqData->mRaycastResults + i) PxRaycastQueryResult(); new(sqData->mSweepResults + i) PxSweepQueryResult(); } for (PxU32 i = 0; i < maxNumHitPoints; i++) { new(sqData->mRaycastHitBuffer + i) PxRaycastHit(); new(sqData->mSweepHitBuffer + i) PxSweepHit(); } sqData->mPreFilterShader = preFilterShader; sqData->mPostFilterShader = postFilterShader; return sqData; } void VehicleSceneQueryData::free(PxAllocatorCallback& allocator) { allocator.deallocate(this); } PxBatchQuery* VehicleSceneQueryData::setUpBatchedSceneQuery(const PxU32 batchId, const VehicleSceneQueryData& vehicleSceneQueryData, PxScene* scene) { const PxU32 maxNumQueriesInBatch = vehicleSceneQueryData.mNumQueriesPerBatch; const PxU32 maxNumHitResultsInBatch = vehicleSceneQueryData.mNumQueriesPerBatch*vehicleSceneQueryData.mNumHitResultsPerQuery; PxBatchQueryDesc sqDesc(maxNumQueriesInBatch, maxNumQueriesInBatch, 0); sqDesc.queryMemory.userRaycastResultBuffer = vehicleSceneQueryData.mRaycastResults + batchId*maxNumQueriesInBatch; sqDesc.queryMemory.userRaycastTouchBuffer = vehicleSceneQueryData.mRaycastHitBuffer + batchId*maxNumHitResultsInBatch; sqDesc.queryMemory.raycastTouchBufferSize = maxNumHitResultsInBatch; sqDesc.queryMemory.userSweepResultBuffer = vehicleSceneQueryData.mSweepResults + batchId*maxNumQueriesInBatch; sqDesc.queryMemory.userSweepTouchBuffer = vehicleSceneQueryData.mSweepHitBuffer + batchId*maxNumHitResultsInBatch; sqDesc.queryMemory.sweepTouchBufferSize = maxNumHitResultsInBatch; sqDesc.preFilterShader = vehicleSceneQueryData.mPreFilterShader; sqDesc.postFilterShader = vehicleSceneQueryData.mPostFilterShader; return scene->createBatchQuery(sqDesc); } PxRaycastQueryResult* VehicleSceneQueryData::getRaycastQueryResultBuffer(const PxU32 batchId) { return (mRaycastResults + batchId*mNumQueriesPerBatch); } PxSweepQueryResult* VehicleSceneQueryData::getSweepQueryResultBuffer(const PxU32 batchId) { return (mSweepResults + batchId*mNumQueriesPerBatch); } PxU32 VehicleSceneQueryData::getQueryResultBufferSize() const { return mNumQueriesPerBatch; } } // namespace snippetvehicle