diff options
Diffstat (limited to 'APEX_1.4/module/fieldsampler/src')
10 files changed, 3185 insertions, 0 deletions
diff --git a/APEX_1.4/module/fieldsampler/src/FieldBoundaryWrapper.cpp b/APEX_1.4/module/fieldsampler/src/FieldBoundaryWrapper.cpp new file mode 100644 index 00000000..ebeedc80 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/FieldBoundaryWrapper.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" +#include "Apex.h" +#include "FieldBoundaryWrapper.h" +#include "FieldSamplerManager.h" + + +namespace nvidia +{ +namespace fieldsampler +{ + +FieldBoundaryWrapper::FieldBoundaryWrapper(ResourceList& list, FieldSamplerManager* manager, FieldBoundaryIntl* fieldBoundary, const FieldBoundaryDescIntl& fieldBoundaryDesc) + : mManager(manager) + , mFieldBoundary(fieldBoundary) + , mFieldBoundaryDesc(fieldBoundaryDesc) + , mFieldShapesChanged(false) +{ + list.add(*this); + +} + +void FieldBoundaryWrapper::release() +{ + delete this; +} + +void FieldBoundaryWrapper::update() +{ + mFieldShapesChanged = mFieldBoundary->updateFieldBoundary(mFieldShapes); +} + +} +} // end namespace nvidia::apex + diff --git a/APEX_1.4/module/fieldsampler/src/FieldSamplerManager.cpp b/APEX_1.4/module/fieldsampler/src/FieldSamplerManager.cpp new file mode 100644 index 00000000..a7c83f88 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/FieldSamplerManager.cpp @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" +#include "Apex.h" + +#include "FieldSamplerManager.h" + +#include "FieldSamplerQuery.h" +#include "FieldSamplerSceneWrapper.h" +#include "FieldSamplerWrapper.h" +#include "FieldBoundaryWrapper.h" + +#include "SceneIntl.h" + +namespace nvidia +{ +namespace fieldsampler +{ + +FieldSamplerManager::FieldSamplerManager(FieldSamplerScene* scene) + : mScene(scene) + , mFieldSamplerGroupsFilteringChanged(true) +{ + mWeightedCallback = NULL; +} + + +PX_INLINE void FieldSamplerManager::addFieldSamplerToQuery(FieldSamplerWrapper* fieldSamplerWrapper, FieldSamplerQuery* query) +{ + if (query->addFieldSampler(fieldSamplerWrapper)) + { + fieldSamplerWrapper->mQueryRefCount += 1; + } +} + +void FieldSamplerManager::addAllFieldSamplersToQuery(FieldSamplerQuery* query) const +{ + for (uint32_t i = 0; i < mFieldSamplerWrapperList.getSize(); ++i) + { + addFieldSamplerToQuery(static_cast<FieldSamplerWrapper*>(mFieldSamplerWrapperList.getResource(i)), query); + } +} + +void FieldSamplerManager::submitTasks() +{ + if (mFieldSamplerGroupsFilteringChanged) + { + mFieldSamplerGroupsFilteringChanged = false; + + //clear queryRefCounts + for (uint32_t i = 0; i < mFieldSamplerWrapperList.getSize(); ++i) + { + FieldSamplerWrapper* fieldSamplerWrapper = static_cast<FieldSamplerWrapper*>(mFieldSamplerWrapperList.getResource(i)); + fieldSamplerWrapper->mQueryRefCount = 0; + } + + //rebuild all connection based on changed collision checking + for (uint32_t i = 0; i < mFieldSamplerQueryList.getSize(); ++i) + { + FieldSamplerQuery* query = DYNAMIC_CAST(FieldSamplerQuery*)(mFieldSamplerQueryList.getResource(i)); + query->clearAllFieldSamplers(); + addAllFieldSamplersToQuery(query); + } + } + + for (uint32_t i = 0; i < mFieldSamplerQueryList.getSize(); ++i) + { + FieldSamplerQuery* query = DYNAMIC_CAST(FieldSamplerQuery*)(mFieldSamplerQueryList.getResource(i)); + query->submitTasks(); + } +} + +void FieldSamplerManager::setTaskDependencies() +{ + for (uint32_t i = 0; i < mFieldSamplerQueryList.getSize(); ++i) + { + FieldSamplerQuery* query = DYNAMIC_CAST(FieldSamplerQuery*)(mFieldSamplerQueryList.getResource(i)); + query->setTaskDependencies(); + } + + //update + for (uint32_t i = 0; i < mFieldBoundaryWrapperList.getSize(); ++i) + { + FieldBoundaryWrapper* wrapper = DYNAMIC_CAST(FieldBoundaryWrapper*)(mFieldBoundaryWrapperList.getResource(i)); + wrapper->update(); + } + for (uint32_t i = 0; i < mFieldSamplerWrapperList.getSize(); ++i) + { + FieldSamplerWrapper* wrapper = DYNAMIC_CAST(FieldSamplerWrapper*)(mFieldSamplerWrapperList.getResource(i)); + wrapper->update(); + } + for (uint32_t i = 0; i < mFieldSamplerSceneWrapperList.getSize(); ++i) + { + FieldSamplerSceneWrapper* wrapper = DYNAMIC_CAST(FieldSamplerSceneWrapper*)(mFieldSamplerSceneWrapperList.getResource(i)); + wrapper->update(); + } + for (uint32_t i = 0; i < mFieldSamplerQueryList.getSize(); ++i) + { + FieldSamplerQuery* query = DYNAMIC_CAST(FieldSamplerQuery*)(mFieldSamplerQueryList.getResource(i)); + query->update(); + } + + //postUpdate + for (uint32_t i = 0; i < mFieldSamplerSceneWrapperList.getSize(); ++i) + { + FieldSamplerSceneWrapper* wrapper = DYNAMIC_CAST(FieldSamplerSceneWrapper*)(mFieldSamplerSceneWrapperList.getResource(i)); + wrapper->postUpdate(); + } +} + +void FieldSamplerManager::fetchResults() +{ + for (uint32_t i = 0; i < mFieldSamplerQueryList.getSize(); ++i) + { + FieldSamplerQuery* query = DYNAMIC_CAST(FieldSamplerQuery*)(mFieldSamplerQueryList.getResource(i)); + query->fetchResults(); + } +} + + +FieldSamplerQueryIntl* FieldSamplerManager::createFieldSamplerQuery(const FieldSamplerQueryDescIntl& desc) +{ + FieldSamplerQuery* query = allocateFieldSamplerQuery(desc); + if (query) + { + addAllFieldSamplersToQuery(query); + } + return query; +} + +void FieldSamplerManager::registerFieldSampler(FieldSamplerIntl* fieldSampler, const FieldSamplerDescIntl& fieldSamplerDesc, FieldSamplerSceneIntl* fieldSamplerScene) +{ + FieldSamplerSceneWrapper* fieldSamplerSceneWrapper = NULL; + //find FieldSamplerSceneWrapper + for (uint32_t i = 0; i < mFieldSamplerSceneWrapperList.getSize(); ++i) + { + FieldSamplerSceneWrapper* wrapper = DYNAMIC_CAST(FieldSamplerSceneWrapper*)(mFieldSamplerSceneWrapperList.getResource(i)); + if (wrapper->getInternalFieldSamplerScene() == fieldSamplerScene) + { + fieldSamplerSceneWrapper = wrapper; + break; + } + } + if (fieldSamplerSceneWrapper == NULL) + { + fieldSamplerSceneWrapper = allocateFieldSamplerSceneWrapper(fieldSamplerScene); + } + PX_ASSERT(fieldSamplerSceneWrapper != NULL); + + FieldSamplerWrapper* fieldSamplerWrapper = allocateFieldSamplerWrapper(fieldSampler, fieldSamplerDesc, fieldSamplerSceneWrapper); + PX_ASSERT(fieldSamplerWrapper != NULL); + + // add all mFieldBoundaryWrapperList + for (uint32_t i = 0; i < mFieldBoundaryWrapperList.getSize(); ++i) + { + FieldBoundaryWrapper* wrapper = DYNAMIC_CAST(FieldBoundaryWrapper*)(mFieldBoundaryWrapperList.getResource(i)); + fieldSamplerWrapper->addFieldBoundary(wrapper); + } + + for (uint32_t i = 0; i < mFieldSamplerQueryList.getSize(); ++i) + { + FieldSamplerQuery* query = DYNAMIC_CAST(FieldSamplerQuery*)(mFieldSamplerQueryList.getResource(i)); + addFieldSamplerToQuery(fieldSamplerWrapper, query); + } +} + +void FieldSamplerManager::unregisterFieldSampler(FieldSamplerIntl* fieldSampler) +{ + FieldSamplerWrapper* fieldSamplerWrapper = NULL; + //find FieldSamplerWrapper + for (uint32_t i = 0; i < mFieldSamplerWrapperList.getSize(); ++i) + { + FieldSamplerWrapper* wrapper = static_cast<FieldSamplerWrapper*>(mFieldSamplerWrapperList.getResource(i)); + if (wrapper->getInternalFieldSampler() == fieldSampler) + { + fieldSamplerWrapper = wrapper; + break; + } + } + if (fieldSamplerWrapper != NULL) + { + for (uint32_t i = 0; i < mFieldSamplerQueryList.getSize(); ++i) + { + FieldSamplerQuery* query = DYNAMIC_CAST(FieldSamplerQuery*)(mFieldSamplerQueryList.getResource(i)); + query->removeFieldSampler(fieldSamplerWrapper); + } + fieldSamplerWrapper->release(); + } +} + +void FieldSamplerManager::registerFieldBoundary(FieldBoundaryIntl* fieldBoundary, const FieldBoundaryDescIntl& fieldBoundaryDesc) +{ + FieldBoundaryWrapper* fieldBoundaryWrapper = PX_NEW(FieldBoundaryWrapper)(mFieldBoundaryWrapperList, this, fieldBoundary, fieldBoundaryDesc); + if (fieldBoundaryWrapper) + { + for (uint32_t i = 0; i < mFieldSamplerWrapperList.getSize(); ++i) + { + static_cast<FieldSamplerWrapper*>(mFieldSamplerWrapperList.getResource(i))->addFieldBoundary(fieldBoundaryWrapper); + } + } +} +void FieldSamplerManager::unregisterFieldBoundary(FieldBoundaryIntl* fieldBoundary) +{ + FieldBoundaryWrapper* fieldBoundaryWrapper = 0; + for (uint32_t i = 0; i < mFieldBoundaryWrapperList.getSize(); ++i) + { + FieldBoundaryWrapper* wrapper = static_cast<FieldBoundaryWrapper*>(mFieldBoundaryWrapperList.getResource(i)); + if (wrapper->getInternalFieldBoundary() == fieldBoundary) + { + fieldBoundaryWrapper = wrapper; + break; + } + } + if (fieldBoundaryWrapper != 0) + { + for (uint32_t i = 0; i < mFieldSamplerWrapperList.getSize(); ++i) + { + static_cast<FieldSamplerWrapper*>(mFieldSamplerWrapperList.getResource(i))->removeFieldBoundary(fieldBoundaryWrapper); + } + fieldBoundaryWrapper->release(); + } +} + +void FieldSamplerManager::registerUnhandledParticleSystem(physx::PxActor* actor) +{ + if (!isUnhandledParticleSystem(actor)) + { + mUnhandledParticleSystems.pushBack(actor); + } +} + +void FieldSamplerManager::unregisterUnhandledParticleSystem(physx::PxActor* actor) +{ + mUnhandledParticleSystems.findAndReplaceWithLast(actor); +} + +bool FieldSamplerManager::isUnhandledParticleSystem(physx::PxActor* actor) +{ + for (uint32_t i = 0; i < mUnhandledParticleSystems.size(); i++) + if (mUnhandledParticleSystems[i] == actor) + { + return true; + } + return false; +} + +bool FieldSamplerManager::getFieldSamplerGroupsFiltering(const PxFilterData &o1,const PxFilterData &o2,float &weight) const +{ + bool ret = true; + + weight = 1.0f; + if ( mScene ) + { + if ( mWeightedCallback ) + { + ret = mWeightedCallback->fieldSamplerWeightedCollisionFilter(o1,o2,weight); + } + else + { + physx::PxScene *scene = mScene->getModulePhysXScene(); + scene->lockRead(__FILE__,__LINE__); + physx::PxSimulationFilterShader shader = scene->getFilterShader(); + scene->unlockRead(); + if ( shader ) + { + physx::PxFilterObjectAttributes atr0 = 0; + physx::PxFilterObjectAttributes atr1 = 0; + physx::PxPairFlags pairFlags; + physx::PxFilterFlags result = (*shader)(atr0,o1,atr1,o2,pairFlags,NULL,0); + if ( result & (physx::PxFilterFlag::eKILL | physx::PxFilterFlag::eSUPPRESS) ) + { + ret = false; + } + } + } + } + return ret; +} + + + + +/******************************** CPU Version ********************************/ + +FieldSamplerQuery* FieldSamplerManagerCPU::allocateFieldSamplerQuery(const FieldSamplerQueryDescIntl& desc) +{ + return PX_NEW(FieldSamplerQueryCPU)(desc, mFieldSamplerQueryList, this); +} +FieldSamplerSceneWrapper* FieldSamplerManagerCPU::allocateFieldSamplerSceneWrapper(FieldSamplerSceneIntl* fieldSamplerScene) +{ + return PX_NEW(FieldSamplerSceneWrapperCPU)(mFieldSamplerSceneWrapperList, this, fieldSamplerScene); +} +FieldSamplerWrapper* FieldSamplerManagerCPU::allocateFieldSamplerWrapper(FieldSamplerIntl* fieldSampler, const FieldSamplerDescIntl& fieldSamplerDesc, FieldSamplerSceneWrapper* fieldSamplerSceneWrapper) +{ + return PX_NEW(FieldSamplerWrapperCPU)(mFieldSamplerWrapperList, this, fieldSampler, fieldSamplerDesc, fieldSamplerSceneWrapper); +} + +/******************************** GPU Version ********************************/ + +#if APEX_CUDA_SUPPORT + +FieldSamplerQuery* FieldSamplerManagerGPU::allocateFieldSamplerQuery(const FieldSamplerQueryDescIntl& desc) +{ + return PX_NEW(FieldSamplerQueryGPU)(desc, mFieldSamplerQueryList, this); +} +FieldSamplerSceneWrapper* FieldSamplerManagerGPU::allocateFieldSamplerSceneWrapper(FieldSamplerSceneIntl* fieldSamplerScene) +{ + return PX_NEW(FieldSamplerSceneWrapperGPU)(mFieldSamplerSceneWrapperList, this, fieldSamplerScene); +} +FieldSamplerWrapper* FieldSamplerManagerGPU::allocateFieldSamplerWrapper(FieldSamplerIntl* fieldSampler, const FieldSamplerDescIntl& fieldSamplerDesc, FieldSamplerSceneWrapper* fieldSamplerSceneWrapper) +{ + return PX_NEW(FieldSamplerWrapperGPU)(mFieldSamplerWrapperList, this, fieldSampler, fieldSamplerDesc, fieldSamplerSceneWrapper); +} + +#endif // APEX_CUDA_SUPPORT + +} +} // end namespace nvidia::apex + + diff --git a/APEX_1.4/module/fieldsampler/src/FieldSamplerPhysXMonitor.cpp b/APEX_1.4/module/fieldsampler/src/FieldSamplerPhysXMonitor.cpp new file mode 100644 index 00000000..e75c8700 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/FieldSamplerPhysXMonitor.cpp @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" + +#if PX_PHYSICS_VERSION_MAJOR == 3 + +#include "ScopedPhysXLock.h" + +#include "PsSort.h" +#include "FieldSamplerPhysXMonitor.h" +#include "FieldSamplerScene.h" +#include "FieldSamplerManager.h" +#include "FieldSamplerQueryIntl.h" + +#include "extensions/PxShapeExt.h" + +namespace nvidia +{ +namespace fieldsampler +{ + + using namespace physx; + +#pragma warning(disable: 4355) // 'this' : used in base member initializer list + +FieldSamplerPhysXMonitor::FieldSamplerPhysXMonitor(FieldSamplerScene& scene) + : mFieldSamplerScene(&scene) + , mNumPS(0) + , mNumRB(0) + , mEnable(false) + , mTaskRunAfterActorUpdate(*this) +{ + mFilterData.setToDefault(); + + mScene = mFieldSamplerScene->getModulePhysXScene(); + mParams = static_cast<FieldSamplerPhysXMonitorParams*>(GetInternalApexSDK()->getParameterizedTraits()->createNvParameterized(FieldSamplerPhysXMonitorParams::staticClassName())); + mFieldSamplerManager = DYNAMIC_CAST(FieldSamplerManager*)(mFieldSamplerScene->getManager()); + + mRBIndex.reserve(mParams->maxRBCount); + mParticleSystems.resize(mParams->maxPSCount); + + mPSOutField.resize(mParams->maxParticleCount); + mOutVelocities.resize(mParams->maxParticleCount); + mOutIndices.resize(mParams->maxParticleCount); + + mRBOutField.resize(mParams->maxRBCount); + + mRBActors.resize(mParams->maxRBCount); +} + + +FieldSamplerPhysXMonitor::~FieldSamplerPhysXMonitor() +{ + for (uint32_t i = 0; i < mPSFieldSamplerQuery.size(); i++) + { + if (mPSFieldSamplerQuery[i]) + { + mPSFieldSamplerQuery[i]->release(); + } + } + for (uint32_t i = 0; i < mRBFieldSamplerQuery.size(); i++) + { + if (mRBFieldSamplerQuery[i]) + { + mRBFieldSamplerQuery[i]->release(); + } + } + if(mParams) + { + mParams->destroy(); + } +} + + +void FieldSamplerPhysXMonitor::setPhysXScene(PxScene* scene) +{ + mScene = scene; +} + + +void FieldSamplerPhysXMonitor::getParticles(uint32_t taskId) +{ + SCOPED_PHYSX_LOCK_READ(&mFieldSamplerScene->getApexScene()); + float deltaTime = mFieldSamplerScene->getApexScene().getPhysXSimulateTime(); + mPCount = 0; + mNumPS = mScene->getActors(physx::PxActorTypeFlag::ePARTICLE_SYSTEM, &mParticleSystems[0], mParams->maxPSCount); + for(uint32_t i = 0; i < mNumPS; i++) + if (!mFieldSamplerManager->isUnhandledParticleSystem(mParticleSystems[i]) && mParticleSystems[i]->is<PxParticleBase>()) + { + if (mPSFieldSamplerQuery.size() == i) + { + FieldSamplerQueryDescIntl queryDesc; + queryDesc.maxCount = mParams->maxParticleCount; + queryDesc.samplerFilterData = mFilterData; + mPSFieldSamplerQuery.pushBack( mFieldSamplerManager->createFieldSamplerQuery(queryDesc) ); + mPSFieldSamplerTaskID.pushBack(0); + mParticleReadData.pushBack(0); + mPSMass.pushBack(0.f); + } + + PxParticleSystem* particleSystem = DYNAMIC_CAST(PxParticleSystem*)((mParticleSystems[i])); + mParticleReadData[i] = particleSystem->lockParticleReadData(); + uint32_t numParticles; + if (mParticleReadData[i]) + { + numParticles = mParticleReadData[i]->validParticleRange; + if(mPCount + numParticles >= mParams->maxParticleCount) break; + + FieldSamplerQueryDataIntl queryData; + queryData.timeStep = deltaTime; + queryData.count = numParticles; + queryData.isDataOnDevice = false; + + //hack for PhysX particle stride calculation + physx::PxStrideIterator<const PxVec3> positionIt(mParticleReadData[i]->positionBuffer); +#ifdef WIN64 + queryData.positionStrideBytes = (uint32_t)(-(int64_t)&*positionIt + (int64_t)&*(++positionIt)); +#else + queryData.positionStrideBytes = (uint32_t)(-(int32_t)&*positionIt + (int32_t)&*(++positionIt)); +#endif + queryData.velocityStrideBytes = queryData.positionStrideBytes; + queryData.massStrideBytes = 0; + queryData.pmaInPosition = (float*)&*(mParticleReadData[i]->positionBuffer); + queryData.pmaInVelocity = (float*)&*(mParticleReadData[i]->velocityBuffer); + queryData.pmaInIndices = 0; + mPSMass[i] = particleSystem->getParticleMass(); + queryData.pmaInMass = &mPSMass[i]; + queryData.pmaOutField = &mPSOutField[mPCount]; + mPSFieldSamplerTaskID[i] = mPSFieldSamplerQuery[i]->submitFieldSamplerQuery(queryData, taskId); + + mPCount += numParticles; + } + } +} + + +void FieldSamplerPhysXMonitor::updateParticles() +{ + uint32_t pCount = 0; + SCOPED_PHYSX_LOCK_WRITE(mFieldSamplerScene->getApexScene().getPhysXScene()); + for(uint32_t i = 0; i < mNumPS; i++) + if (!mFieldSamplerManager->isUnhandledParticleSystem(mParticleSystems[i])) + { + PxParticleSystem* particleSystem = DYNAMIC_CAST(PxParticleSystem*)((mParticleSystems[i])); + uint32_t numParticles = PxMin(mParticleReadData[i]->validParticleRange, mParams->maxParticleCount); + + uint32_t numUpdates = 0; + + if (numParticles > 0) + { + for (uint32_t w = 0; w <= (mParticleReadData[i]->validParticleRange-1) >> 5; w++) + { + for (uint32_t b = mParticleReadData[i]->validParticleBitmap[w]; b; b &= b-1) + { + uint32_t index = (w << 5 | shdfnd::lowestSetBit(b)); + + PxVec3 diffVel = mPSOutField[pCount + index].getXYZ(); + if (!diffVel.isZero()) + { + const PxVec3& sourceVelocity = mParticleReadData[i]->velocityBuffer[index]; + mOutVelocities[numUpdates] = sourceVelocity + diffVel; + mOutIndices[numUpdates] = index; + numUpdates++; + } + } + } + } + pCount += numParticles; + // return ownership of the buffers back to the SDK + mParticleReadData[i]->unlock(); + + if(pCount <= mParams->maxParticleCount && numUpdates > 0) + { + physx::PxStrideIterator<uint32_t> indices(&mOutIndices[0]); + physx::PxStrideIterator<PxVec3> outVelocities(&mOutVelocities[0]); + particleSystem->setVelocities(numUpdates, indices, outVelocities); + } + } +} + + +void FieldSamplerPhysXMonitor::getRigidBodies(uint32_t taskId) +{ + SCOPED_PHYSX_LOCK_READ(&mFieldSamplerScene->getApexScene()); + float deltaTime = mFieldSamplerScene->getApexScene().getPhysXSimulateTime(); + + FieldSamplerQueryDataIntl queryData; + queryData.timeStep = deltaTime; + queryData.pmaInIndices = 0; + + uint32_t rbCount = mScene->getActors(physx::PxActorTypeFlag::eRIGID_DYNAMIC, &mRBActors[0], mParams->maxRBCount); + Array<PxShape*> shapes; + mNumRB = 0; + mRBIndex.clear(); + float weight = 1.f; + + for (uint32_t i = 0; i < rbCount; i++) + { + physx::PxRigidDynamic* rb = (physx::PxRigidDynamic*)mRBActors[i]; + if (rb->getRigidBodyFlags() == PxRigidBodyFlag::eKINEMATIC) + { + continue; + } + const PxVec3& cmPos = rb->getGlobalPose().p; + const PxVec3& velocity = rb->getLinearVelocity(); + const PxVec3& rotation = rb->getAngularVelocity(); + float mass = rb->getMass(); + + const uint32_t numShapes = rb->getNbShapes(); + shapes.resize(numShapes); + if (numShapes == 0) + { + continue; + } + rb->getShapes(&shapes[0], numShapes); + for (uint32_t j = 0; j < numShapes && mNumRB < mParams->maxRBCount; j++) + { + PxFilterData filterData = shapes[j]->getQueryFilterData(); + if (mFieldSamplerManager->getFieldSamplerGroupsFiltering(mFilterData, filterData, weight)) + { + PxFilterData* current = mRBFilterData.find(filterData); + if (current == mRBFilterData.end()) + { + mRBFilterData.pushBack(filterData); + current = &mRBFilterData.back(); + FieldSamplerQueryDescIntl queryDesc; + queryDesc.maxCount = mParams->maxParticleCount; + queryDesc.samplerFilterData = filterData; + mRBFieldSamplerQuery.pushBack( mFieldSamplerManager->createFieldSamplerQuery(queryDesc) ); + } + + ShapeData* sd = PX_NEW(ShapeData)(); + sd->fdIndex = (uint32_t)(current - &mRBFilterData[0]); + sd->rbIndex = i; + sd->mass = mass / numShapes; + sd->pos = PxShapeExt::getWorldBounds(*shapes[j], *rb).getCenter(); + sd->vel = velocity + rotation.cross(sd->pos - cmPos); + mRBIndex.pushBack(sd); + ++mNumRB; + } + } + } + + if (mNumRB == 0) + { + return; + } + + + sort(&mRBIndex[0], mNumRB, ShapeData::sortPredicate); + + mRBInPosition.resize(mNumRB); + mRBInVelocity.resize(mNumRB); + + uint32_t current(mRBIndex[0]->fdIndex); + uint32_t currentCount = 0; + uint32_t fdCount = 0; + for (uint32_t i = 0; i <= mNumRB; i++) + { + if (i == mNumRB || current != mRBIndex[i]->fdIndex) + { + queryData.count = currentCount; + queryData.isDataOnDevice = false; + queryData.massStrideBytes = sizeof(PxVec4); + queryData.positionStrideBytes = sizeof(PxVec4); + queryData.velocityStrideBytes = queryData.positionStrideBytes; + + queryData.pmaInPosition = (float*)(&mRBInPosition[fdCount]); + queryData.pmaInVelocity = (float*)(&mRBInVelocity[fdCount]); + queryData.pmaInMass = &(mRBInPosition[fdCount].w); + queryData.pmaOutField = &mRBOutField[fdCount]; + + mRBFieldSamplerQuery[current]->submitFieldSamplerQuery(queryData, taskId); + + fdCount += currentCount; + if (i != mNumRB) + { + current = mRBIndex[i]->fdIndex; + currentCount = 1; + } + } + else + { + currentCount++; + } + if (i < mNumRB) + { + mRBInPosition[i] = PxVec4 (mRBIndex[i]->pos, mRBIndex[i]->mass); + mRBInVelocity[i] = PxVec4 (mRBIndex[i]->vel, 0.f); + } + } +} + +void FieldSamplerPhysXMonitor::updateRigidBodies() +{ + SCOPED_PHYSX_LOCK_WRITE(&mFieldSamplerScene->getApexScene()); + + for(uint32_t i = 0; i < mNumRB; i++) + { + physx::PxRigidDynamic* rb = (physx::PxRigidDynamic*)mRBActors[mRBIndex[i]->rbIndex]; + const PxVec3 velocity = mRBOutField[i].getXYZ(); + const PxVec3 rotation = mRBOutField[i].getXYZ().cross(mRBInPosition[i].getXYZ() - rb->getGlobalPose().p); + if (!velocity.isZero() || !rotation.isZero()) + { + rb->setLinearVelocity(rb->getLinearVelocity() + velocity); + rb->setAngularVelocity(rb->getAngularVelocity() + rotation); + } + + PX_DELETE(mRBIndex[i]); + } +} + + +void FieldSamplerPhysXMonitor::update() +{ + PxTaskManager* tm = mFieldSamplerScene->getApexScene().getTaskManager(); + uint32_t taskId = tm->getNamedTask(FSST_PHYSX_MONITOR_LOAD); + if(mScene) + { + getParticles(taskId); + + getRigidBodies(taskId); + + //getCloth(task); + } + if(mNumPS > 0 || mNumRB > 0) + { + tm->submitNamedTask(&mTaskRunAfterActorUpdate, FSST_PHYSX_MONITOR_UPDATE); + mTaskRunAfterActorUpdate.startAfter(tm->getNamedTask(FSST_PHYSX_MONITOR_FETCH)); + mTaskRunAfterActorUpdate.finishBefore(tm->getNamedTask(AST_PHYSX_SIMULATE)); + } +} + +void FieldSamplerPhysXMonitor::updatePhysX() +{ + updateParticles(); + updateRigidBodies(); +} + + +} +} // end namespace nvidia::apex + +#endif + diff --git a/APEX_1.4/module/fieldsampler/src/FieldSamplerQuery.cpp b/APEX_1.4/module/fieldsampler/src/FieldSamplerQuery.cpp new file mode 100644 index 00000000..bada10fc --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/FieldSamplerQuery.cpp @@ -0,0 +1,876 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" +#include "Apex.h" +#include "FieldSamplerQuery.h" +#include "FieldSamplerManager.h" +#include "FieldSamplerWrapper.h" +#include "FieldSamplerSceneWrapper.h" +#include "FieldBoundaryWrapper.h" + +#include "SceneIntl.h" + +#if APEX_CUDA_SUPPORT +#include "PxGpuTask.h" +#endif + +#include "FieldSamplerCommon.h" + + +namespace nvidia +{ +namespace fieldsampler +{ + + +FieldSamplerQuery::FieldSamplerQuery(const FieldSamplerQueryDescIntl& desc, ResourceList& list, FieldSamplerManager* manager) + : mManager(manager) + , mQueryDesc(desc) + , mAccumVelocity(manager->getApexScene(), PX_ALLOC_INFO("mAccumVelocity", PARTICLES)) + , mOnStartCallback(NULL) + , mOnFinishCallback(NULL) +{ + list.add(*this); +} + +void FieldSamplerQuery::release() +{ + if (mInRelease) + { + return; + } + mInRelease = true; + destroy(); +} + +void FieldSamplerQuery::destroy() +{ + delete this; +} + + +FieldSamplerQuery::SceneInfo* FieldSamplerQuery::findSceneInfo(FieldSamplerSceneWrapper* sceneWrapper) const +{ + for (uint32_t i = 0; i < mSceneList.getSize(); ++i) + { + SceneInfo* sceneInfo = DYNAMIC_CAST(SceneInfo*)(mSceneList.getResource(i)); + if (sceneInfo->getSceneWrapper() == sceneWrapper) + { + return sceneInfo; + } + } + return NULL; +} + + +bool FieldSamplerQuery::addFieldSampler(FieldSamplerWrapper* fieldSamplerWrapper) +{ + const FieldSamplerDescIntl& fieldSamplerDesc = fieldSamplerWrapper->getInternalFieldSamplerDesc(); + float multiplier = 1.0f; + bool result = mManager->getFieldSamplerGroupsFiltering(mQueryDesc.samplerFilterData, fieldSamplerDesc.samplerFilterData, multiplier); + if (result) + { + FieldSamplerSceneWrapper* sceneWrapper = fieldSamplerWrapper->getFieldSamplerSceneWrapper(); + SceneInfo* sceneInfo = findSceneInfo(sceneWrapper); + if (sceneInfo == NULL) + { + sceneInfo = createSceneInfo(sceneWrapper); + } + sceneInfo->addFieldSampler(fieldSamplerWrapper, multiplier); + } + return result; +} + +bool FieldSamplerQuery::removeFieldSampler(FieldSamplerWrapper* fieldSamplerWrapper) +{ + FieldSamplerSceneWrapper* sceneWrapper = fieldSamplerWrapper->getFieldSamplerSceneWrapper(); + SceneInfo* sceneInfo = findSceneInfo(sceneWrapper); + return (sceneInfo != NULL) ? sceneInfo->removeFieldSampler(fieldSamplerWrapper) : false; +} + +void FieldSamplerQuery::clearAllFieldSamplers() +{ + for (uint32_t i = 0; i < mSceneList.getSize(); ++i) + { + SceneInfo* sceneInfo = DYNAMIC_CAST(SceneInfo*)(mSceneList.getResource(i)); + sceneInfo->clearAllFieldSamplers(); + } +} + +void FieldSamplerQuery::submitFieldSamplerQuery(const FieldSamplerQueryDataIntl& data, PxTask* task, PxTask* readyTask) +{ + PX_UNUSED(readyTask); + for (uint32_t i = 0; i < mSceneList.getSize(); ++i) + { + SceneInfo* sceneInfo = DYNAMIC_CAST(SceneInfo*)(mSceneList.getResource(i)); + FieldSamplerSceneIntl* niFieldSamplerScene = sceneInfo->getSceneWrapper()->getInternalFieldSamplerScene(); + const PxTask* fieldSamplerReadyTask = niFieldSamplerScene->onSubmitFieldSamplerQuery(data, readyTask); + if (fieldSamplerReadyTask != 0) + { + task->startAfter(fieldSamplerReadyTask->getTaskID()); + } + } +} + +void FieldSamplerQuery::update() +{ + mPrimarySceneList.clear(); + mSecondarySceneList.clear(); + + for (uint32_t i = 0; i < mSceneList.getSize(); ++i) + { + SceneInfo* sceneInfo = DYNAMIC_CAST(SceneInfo*)(mSceneList.getResource(i)); + sceneInfo->update(); + + if (sceneInfo->getEnabledFieldSamplerCount() > 0 && (sceneInfo->getSceneWrapper()->getInternalFieldSamplerScene() != mQueryDesc.ownerFieldSamplerScene)) + { + ((sceneInfo->getSceneWrapper()->getInternalFieldSamplerSceneDesc().isPrimary) ? mPrimarySceneList : mSecondarySceneList).pushBack(sceneInfo); + } + } +} + +bool FieldSamplerQuery::SceneInfo::update() +{ + mEnabledFieldSamplerCount = 0; + for (uint32_t i = 0; i < mFieldSamplerArray.size(); ++i) + { + if (mFieldSamplerArray[i].mFieldSamplerWrapper->isEnabled()) + { + ++mEnabledFieldSamplerCount; + } + if (mFieldSamplerArray[i].mFieldSamplerWrapper->isEnabledChanged()) + { + mFieldSamplerArrayChanged = true; + } + } + + if (mFieldSamplerArrayChanged) + { + mFieldSamplerArrayChanged = false; + return true; + } + return false; +} +/******************************** CPU Version ********************************/ +class TaskExecute : public PxTask, public UserAllocated +{ +public: + TaskExecute(FieldSamplerQueryCPU* query) : mQuery(query) {} + + const char* getName() const + { + return "FieldSamplerQueryCPU::TaskExecute"; + } + void run() + { + mQuery->execute(); + } + +protected: + FieldSamplerQueryCPU* mQuery; +}; + +FieldSamplerQueryCPU::FieldSamplerQueryCPU(const FieldSamplerQueryDescIntl& desc, ResourceList& list, FieldSamplerManager* manager) + : FieldSamplerQuery(desc, list, manager) +{ + mTaskExecute = PX_NEW(TaskExecute)(this); + + mExecuteCount = 256; +} + +FieldSamplerQueryCPU::~FieldSamplerQueryCPU() +{ + delete mTaskExecute; +} + +PxTaskID FieldSamplerQueryCPU::submitFieldSamplerQuery(const FieldSamplerQueryDataIntl& data, PxTaskID taskID) +{ + PX_ASSERT(data.isDataOnDevice == false); + PX_ASSERT(data.count <= mQueryDesc.maxCount); + if (data.count == 0) + { + return taskID; + } + mQueryData = data; + + mResultField.resize(mExecuteCount); + mWeights.resize(mExecuteCount); + mAccumVelocity.reserve(mQueryDesc.maxCount); + + PxTaskManager* tm = mManager->getApexScene().getTaskManager(); + tm->submitUnnamedTask(*mTaskExecute); + + FieldSamplerQuery::submitFieldSamplerQuery(data, mTaskExecute, NULL); + + mTaskExecute->finishBefore(taskID); + return mTaskExecute->getTaskID(); +} + +void FieldSamplerQueryCPU::execute() +{ + if (mOnStartCallback) + { + (*mOnStartCallback)(NULL); + } + + FieldSamplerIntl::ExecuteData executeData; + + executeData.position = mQueryData.pmaInPosition; + executeData.velocity = mQueryData.pmaInVelocity; + executeData.mass = mQueryData.pmaInMass;// + massOffset; + executeData.resultField = mResultField.begin(); + executeData.positionStride = mQueryData.positionStrideBytes; + executeData.velocityStride = mQueryData.velocityStrideBytes; + executeData.massStride = mQueryData.massStrideBytes; + executeData.indicesMask = 0; + + uint32_t beginIndex; + uint32_t* indices = &beginIndex; + if (mQueryData.pmaInIndices) + { + indices = mQueryData.pmaInIndices; + executeData.indicesMask = ~executeData.indicesMask; + } + + for (uint32_t executeOffset = 0; executeOffset < mQueryData.count; executeOffset += mExecuteCount) + { + const uint32_t positionStride = mQueryData.positionStrideBytes / 4; + const uint32_t velocityStride = mQueryData.velocityStrideBytes / 4; + const uint32_t massStride = mQueryData.massStrideBytes / 4; + //const uint32_t offset = executeOffset * stride; + //const uint32_t massOffset = executeOffset * massStride; + + beginIndex = executeOffset; + executeData.count = PxMin(mExecuteCount, mQueryData.count - executeOffset); + executeData.indices = indices + (executeOffset & executeData.indicesMask); + + PxVec4* accumField = (PxVec4*)(mQueryData.pmaOutField); + PxVec4* accumVelocity = mAccumVelocity.getPtr() + executeOffset; + //clear accum + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + accumField[j] = PxVec4(0.0f); + accumVelocity[i] = PxVec4(0.0f); + } + for (uint32_t sceneIdx = 0; sceneIdx < mPrimarySceneList.size(); ++sceneIdx) + { + executeScene(mPrimarySceneList[sceneIdx], executeData, accumField, accumVelocity, positionStride, velocityStride, massStride); + } + + //setup weights for secondary scenes + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + accumField[j].w = accumVelocity[i].w; + accumVelocity[i].w = 0.0f; + } + for (uint32_t sceneIdx = 0; sceneIdx < mSecondarySceneList.size(); ++sceneIdx) + { + executeScene(mSecondarySceneList[sceneIdx], executeData, accumField, accumVelocity, positionStride, velocityStride, massStride); + } + + //compose accum field + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + float blend = accumField[j].w; + float velW = accumVelocity[i].w; + float weight = blend + velW * (1 - blend); + if (weight >= VELOCITY_WEIGHT_THRESHOLD) + { + PxVec3 result = accumField[j].getXYZ(); + const PxVec3& velocity = *(PxVec3*)(executeData.velocity + j * velocityStride); + result += (accumVelocity[i].getXYZ() - weight * velocity); + accumField[j] = PxVec4(result, 0); + } + } + } + + if (mOnFinishCallback) + { + (*mOnFinishCallback)(NULL); + } +} + +void FieldSamplerQueryCPU::executeScene(const SceneInfo* sceneInfo, + const FieldSamplerIntl::ExecuteData& executeData, + PxVec4* accumField, + PxVec4* accumVelocity, + uint32_t positionStride, + uint32_t velocityStride, + uint32_t massStride) +{ + FieldSamplerExecuteArgs execArgs; + execArgs.elapsedTime = mQueryData.timeStep; + execArgs.totalElapsedMS = mManager->getApexScene().getTotalElapsedMS(); + + const nvidia::Array<FieldSamplerInfo>& fieldSamplerArray = sceneInfo->getFieldSamplerArray(); + for (uint32_t fieldSamplerIdx = 0; fieldSamplerIdx < fieldSamplerArray.size(); ++fieldSamplerIdx) + { + const FieldSamplerWrapperCPU* fieldSampler = DYNAMIC_CAST(FieldSamplerWrapperCPU*)(fieldSamplerArray[fieldSamplerIdx].mFieldSamplerWrapper); + if (fieldSampler->isEnabled()) + { + const float multiplier = fieldSamplerArray[fieldSamplerIdx].mMultiplier; + PX_UNUSED(multiplier); + + const FieldSamplerDescIntl& desc = fieldSampler->getInternalFieldSamplerDesc(); + if (desc.cpuSimulationSupport) + { + const FieldShapeDescIntl& shapeDesc = fieldSampler->getInternalFieldSamplerShape(); + PX_ASSERT(shapeDesc.weight >= 0.0f && shapeDesc.weight <= 1.0f); + + for (uint32_t i = 0; i < executeData.count; ++i) + { + mWeights[i] = 0; + } + + uint32_t boundaryCount = fieldSampler->getFieldBoundaryCount(); + for (uint32_t boundaryIndex = 0; boundaryIndex < boundaryCount; ++boundaryIndex) + { + FieldBoundaryWrapper* fieldBoundaryWrapper = fieldSampler->getFieldBoundaryWrapper(boundaryIndex); + + const nvidia::Array<FieldShapeDescIntl>& fieldShapes = fieldBoundaryWrapper->getFieldShapes(); + for (uint32_t shapeIndex = 0; shapeIndex < fieldShapes.size(); ++shapeIndex) + { + const FieldShapeDescIntl& boundaryShapeDesc = fieldShapes[shapeIndex]; + PX_ASSERT(boundaryShapeDesc.weight >= 0.0f && boundaryShapeDesc.weight <= 1.0f); + + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + PxVec3* pos = (PxVec3*)(executeData.position + j * positionStride); + const float excludeWeight = evalFade(evalDistInShape(boundaryShapeDesc, *pos), 0.0f) * boundaryShapeDesc.weight; + mWeights[i] = PxMax(mWeights[i], excludeWeight); + } + } + } + + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + PxVec3* pos = (PxVec3*)(executeData.position + j * positionStride); + const float includeWeight = evalFade(evalDistInShape(shapeDesc, *pos), desc.boundaryFadePercentage) * shapeDesc.weight; + const float excludeWeight = mWeights[i]; + mWeights[i] = includeWeight * (1.0f - excludeWeight); +#if FIELD_SAMPLER_MULTIPLIER == FIELD_SAMPLER_MULTIPLIER_WEIGHT + mWeights[i] *= multiplier; +#endif + } + + //execute field + fieldSampler->getInternalFieldSampler()->executeFieldSampler(executeData); + +#if FIELD_SAMPLER_MULTIPLIER == FIELD_SAMPLER_MULTIPLIER_VALUE + const float multiplier = fieldSamplerArray[fieldSamplerIdx].mMultiplier; + for (uint32_t i = 0; i < executeData.count; ++i) + { + executeData.resultField[i] *= multiplier; + } +#endif + + //accum field + switch (desc.type) + { + case FieldSamplerTypeIntl::FORCE: + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + execArgs.position = *(PxVec3*)(executeData.position + j * positionStride); + execArgs.velocity = *(PxVec3*)(executeData.velocity + j * velocityStride); + execArgs.mass = *(executeData.mass + massStride * j); + + accumFORCE(execArgs, executeData.resultField[i], mWeights[i], accumField[j], accumVelocity[i]); + } + break; + case FieldSamplerTypeIntl::ACCELERATION: + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + execArgs.position = *(PxVec3*)(executeData.position + j * positionStride); + execArgs.velocity = *(PxVec3*)(executeData.velocity + j * velocityStride); + execArgs.mass = *(executeData.mass + massStride * j); + + accumACCELERATION(execArgs, executeData.resultField[i], mWeights[i], accumField[j], accumVelocity[i]); + } + break; + case FieldSamplerTypeIntl::VELOCITY_DRAG: + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + execArgs.position = *(PxVec3*)(executeData.position + j * positionStride); + execArgs.velocity = *(PxVec3*)(executeData.velocity + j * velocityStride); + execArgs.mass = *(executeData.mass + massStride * j); + + accumVELOCITY_DRAG(execArgs, desc.dragCoeff, executeData.resultField[i], mWeights[i], accumField[j], accumVelocity[i]); + } + break; + case FieldSamplerTypeIntl::VELOCITY_DIRECT: + for (uint32_t i = 0; i < executeData.count; ++i) + { + uint32_t j = executeData.indices[i & executeData.indicesMask] + (i & ~executeData.indicesMask); + execArgs.position = *(PxVec3*)(executeData.position + j * positionStride); + execArgs.velocity = *(PxVec3*)(executeData.velocity + j * velocityStride); + execArgs.mass = *(executeData.mass + massStride * j); + + accumVELOCITY_DIRECT(execArgs, executeData.resultField[i], mWeights[i], accumField[j], accumVelocity[i]); + } + break; + }; + } + } + } + +} + + +/******************************** GPU Version ********************************/ +#if APEX_CUDA_SUPPORT + +class FieldSamplerQueryLaunchTask : public PxGpuTask, public UserAllocated +{ +public: + FieldSamplerQueryLaunchTask(FieldSamplerQueryGPU* query) : mQuery(query) {} + const char* getName() const + { + return "FieldSamplerQueryLaunchTask"; + } + void run() + { + PX_ALWAYS_ASSERT(); + } + bool launchInstance(CUstream stream, int kernelIndex) + { + return mQuery->launch(stream, kernelIndex); + } + PxGpuTaskHint::Enum getTaskHint() const + { + return PxGpuTaskHint::Kernel; + } + +protected: + FieldSamplerQueryGPU* mQuery; +}; + +class FieldSamplerQueryPrepareTask : public PxTask, public UserAllocated +{ +public: + FieldSamplerQueryPrepareTask(FieldSamplerQueryGPU* query) : mQuery(query) {} + + const char* getName() const + { + return "FieldSamplerQueryPrepareTask"; + } + void run() + { + mQuery->prepare(); + } + +protected: + FieldSamplerQueryGPU* mQuery; +}; + +class FieldSamplerQueryCopyTask : public PxGpuTask, public UserAllocated +{ +public: + FieldSamplerQueryCopyTask(FieldSamplerQueryGPU* query) : mQuery(query) {} + const char* getName() const + { + return "FieldSamplerQueryCopyTask"; + } + void run() + { + PX_ALWAYS_ASSERT(); + } + bool launchInstance(CUstream stream, int kernelIndex) + { + return mQuery->copy(stream, kernelIndex); + } + PxGpuTaskHint::Enum getTaskHint() const + { + return PxGpuTaskHint::Kernel; + } + +protected: + FieldSamplerQueryGPU* mQuery; +}; + +class FieldSamplerQueryFetchTask : public PxTask, public UserAllocated +{ +public: + FieldSamplerQueryFetchTask(FieldSamplerQueryGPU* query) : mQuery(query) {} + + const char* getName() const + { + return "FieldSamplerQueryFetchTask"; + } + void run() + { + mQuery->fetch(); + } + +protected: + FieldSamplerQueryGPU* mQuery; +}; + + +FieldSamplerQueryGPU::FieldSamplerQueryGPU(const FieldSamplerQueryDescIntl& desc, ResourceList& list, FieldSamplerManager* manager) + : FieldSamplerQueryCPU(desc, list, manager) + , mPositionMass(manager->getApexScene(), PX_ALLOC_INFO("mPositionMass", PARTICLES)) + , mVelocity(manager->getApexScene(), PX_ALLOC_INFO("mVelocity", PARTICLES)) + , mAccumField(manager->getApexScene(), PX_ALLOC_INFO("mAccumField", PARTICLES)) + , mCopyQueue(*manager->getApexScene().getTaskManager()->getGpuDispatcher()) +{ + mTaskLaunch = PX_NEW(FieldSamplerQueryLaunchTask)(this); + mTaskPrepare = PX_NEW(FieldSamplerQueryPrepareTask)(this); + mTaskCopy = PX_NEW(FieldSamplerQueryCopyTask)(this); + mTaskFetch = PX_NEW(FieldSamplerQueryFetchTask)(this); +} + +FieldSamplerQueryGPU::~FieldSamplerQueryGPU() +{ + PX_DELETE(mTaskFetch); + PX_DELETE(mTaskCopy); + PX_DELETE(mTaskPrepare); + PX_DELETE(mTaskLaunch); +} + +PxTaskID FieldSamplerQueryGPU::submitFieldSamplerQuery(const FieldSamplerQueryDataIntl& data, PxTaskID taskID) +{ + PX_ASSERT(data.count <= mQueryDesc.maxCount); + if (data.count == 0) + { + return taskID; + } + mQueryData = data; + + if (!data.isDataOnDevice) + { + bool isWorkOnCPU = true; + // try to find FieldSampler which has no CPU implemntation (Turbulence for example) + for (uint32_t sceneIdx = 0; (sceneIdx < mPrimarySceneList.size() + mSecondarySceneList.size()) && isWorkOnCPU; ++sceneIdx) + { + const nvidia::Array<FieldSamplerInfo>& fsArray = sceneIdx < mPrimarySceneList.size() + ? mPrimarySceneList[sceneIdx]->getFieldSamplerArray() + : mSecondarySceneList[sceneIdx-mPrimarySceneList.size()]->getFieldSamplerArray(); + for (uint32_t fsIdx = 0; fsIdx < fsArray.size() && isWorkOnCPU; fsIdx++) + { + if (fsArray[fsIdx].mFieldSamplerWrapper->isEnabled()) + { + isWorkOnCPU = fsArray[fsIdx].mFieldSamplerWrapper->getInternalFieldSamplerDesc().cpuSimulationSupport; + } + } + } + + // if all FSs can work on CPU we will execute FieldSamplerQuery on CPU + if (isWorkOnCPU) + { + return FieldSamplerQueryCPU::submitFieldSamplerQuery(data, taskID); + } + + mPositionMass.reserve(mQueryDesc.maxCount, ApexMirroredPlace::CPU_GPU); + mVelocity.reserve(mQueryDesc.maxCount, ApexMirroredPlace::CPU_GPU); + mAccumField.reserve(mQueryDesc.maxCount, ApexMirroredPlace::CPU_GPU); + } + mAccumVelocity.reserve(mQueryDesc.maxCount, ApexMirroredPlace::CPU_GPU); + + // if data on device or some FS can't work on CPU we will launch FieldSamplerQuery on GPU + PxTaskManager* tm = mManager->getApexScene().getTaskManager(); + tm->submitUnnamedTask(*mTaskLaunch, PxTaskType::TT_GPU); + + if (data.isDataOnDevice) + { + FieldSamplerQuery::submitFieldSamplerQuery(data, mTaskLaunch, NULL); + + mTaskLaunch->finishBefore(taskID); + return mTaskLaunch->getTaskID(); + } + else + { + FieldSamplerQueryDataIntl data4Device; + data4Device.timeStep = data.timeStep; + data4Device.count = data.count; + data4Device.isDataOnDevice = true; + data4Device.positionStrideBytes = sizeof(PxVec4); + data4Device.velocityStrideBytes = sizeof(PxVec4); + data4Device.massStrideBytes = sizeof(PxVec4); + data4Device.pmaInPosition = (float*)mPositionMass.getGpuPtr(); + data4Device.pmaInVelocity = (float*)mVelocity.getGpuPtr(); + data4Device.pmaInMass = &mPositionMass.getGpuPtr()->w; + data4Device.pmaOutField = mAccumField.getGpuPtr(); + data4Device.pmaInIndices = 0; + + FieldSamplerQuery::submitFieldSamplerQuery(data4Device, mTaskLaunch, mTaskCopy); + + tm->submitUnnamedTask(*mTaskPrepare); + tm->submitUnnamedTask(*mTaskCopy, PxTaskType::TT_GPU); + tm->submitUnnamedTask(*mTaskFetch); + + mTaskPrepare->finishBefore(mTaskCopy->getTaskID()); + mTaskCopy->finishBefore(mTaskLaunch->getTaskID()); + mTaskLaunch->finishBefore(mTaskFetch->getTaskID()); + mTaskFetch->finishBefore(taskID); + return mTaskPrepare->getTaskID(); + } +} + +void FieldSamplerQueryGPU::prepare() +{ + const uint32_t positionStride = mQueryData.positionStrideBytes / sizeof(float); + const uint32_t velocityStride = mQueryData.velocityStrideBytes / sizeof(float); + const uint32_t massStride = mQueryData.massStrideBytes / sizeof(float); + for (uint32_t idx = 0; idx < mQueryData.count; idx++) + { + mPositionMass[idx] = PxVec4(*(PxVec3*)(mQueryData.pmaInPosition + idx * positionStride), *(mQueryData.pmaInMass + idx * massStride)); + mVelocity[idx] = PxVec4(*(PxVec3*)(mQueryData.pmaInVelocity + idx * velocityStride), 0.f); + } +} + +void FieldSamplerQueryGPU::fetch() +{ + for (uint32_t idx = 0; idx < mQueryData.count; idx++) + { + mQueryData.pmaOutField[idx] = mAccumField[idx]; + } +} + +bool FieldSamplerQueryGPU::copy(CUstream stream, int kernelIndex) +{ + if (kernelIndex == 0) + { + mCopyQueue.reset(stream, 4); + mPositionMass.copyHostToDeviceQ(mCopyQueue, mQueryData.count); + mVelocity.copyHostToDeviceQ(mCopyQueue, mQueryData.count); + mCopyQueue.flushEnqueued(); + } + return false; +} + +bool FieldSamplerQueryGPU::launch(CUstream stream, int kernelIndex) +{ + FieldSamplerPointsKernelArgs args; + args.elapsedTime = mQueryData.timeStep; + args.totalElapsedMS = mManager->getApexScene().getTotalElapsedMS(); + if (mQueryData.isDataOnDevice) + { + args.positionMass = (float4*)mQueryData.pmaInPosition; + args.velocity = (float4*)mQueryData.pmaInVelocity; + args.accumField = (float4*)mQueryData.pmaOutField; + } + else + { + args.positionMass = (float4*)mPositionMass.getGpuPtr(); + args.velocity = (float4*)mVelocity.getGpuPtr(); + args.accumField = (float4*)mAccumField.getGpuPtr(); + } + args.accumVelocity = (float4*)mAccumVelocity.getGpuPtr(); + + FieldSamplerPointsKernelLaunchDataIntl launchData; + launchData.stream = stream; + launchData.kernelType = FieldSamplerKernelType::POINTS; + launchData.kernelArgs = &args; + launchData.threadCount = mQueryData.count; + launchData.memRefSize = mQueryData.count; + + if (kernelIndex == 0 && mOnStartCallback) + { + (*mOnStartCallback)(stream); + } + + if (kernelIndex == 0) + { + CUDA_OBJ(clearKernel)(stream, mQueryData.count, + createApexCudaMemRef(args.accumField, launchData.memRefSize, ApexCudaMemFlags::OUT), + createApexCudaMemRef(args.accumVelocity, launchData.memRefSize, ApexCudaMemFlags::OUT)); + return true; + } + --kernelIndex; + + const uint32_t bothSceneCount = mPrimarySceneList.size() + mSecondarySceneList.size(); + if (kernelIndex < (int) bothSceneCount) + { + SceneInfo* sceneInfo = (kernelIndex < (int) mPrimarySceneList.size()) + ? mPrimarySceneList[(uint32_t)kernelIndex] + : mSecondarySceneList[(uint32_t)kernelIndex - mPrimarySceneList.size()]; + SceneInfoGPU* sceneInfoGPU = DYNAMIC_CAST(SceneInfoGPU*)(sceneInfo); + + launchData.kernelMode = FieldSamplerKernelMode::DEFAULT; + if (kernelIndex == (int) mPrimarySceneList.size() - 1) + { + launchData.kernelMode = FieldSamplerKernelMode::FINISH_PRIMARY; + } + if ((kernelIndex == (int) bothSceneCount - 1)) + { + launchData.kernelMode = FieldSamplerKernelMode::FINISH_SECONDARY; + } + + FieldSamplerSceneWrapperGPU* sceneWrapper = DYNAMIC_CAST(FieldSamplerSceneWrapperGPU*)(sceneInfo->getSceneWrapper()); + + launchData.queryParamsHandle = sceneInfoGPU->getQueryParamsHandle(); + launchData.paramsExArrayHandle = sceneInfoGPU->getParamsHandle(); + launchData.fieldSamplerArray = &sceneInfo->getFieldSamplerArray(); + launchData.activeFieldSamplerCount = sceneInfo->getEnabledFieldSamplerCount(); + + sceneWrapper->getInternalFieldSamplerScene()->launchFieldSamplerCudaKernel(launchData); + return true; + } + kernelIndex -= bothSceneCount; + + if (kernelIndex == 0) + { + CUDA_OBJ(composeKernel)(stream, mQueryData.count, + createApexCudaMemRef(args.accumField, launchData.memRefSize, ApexCudaMemFlags::IN_OUT), + createApexCudaMemRef((const float4*)args.accumVelocity, launchData.memRefSize, ApexCudaMemFlags::IN), + createApexCudaMemRef(args.velocity, launchData.memRefSize, ApexCudaMemFlags::IN), + args.elapsedTime); + return true; + } + --kernelIndex; + + if (!mQueryData.isDataOnDevice) + { + mAccumField.copyDeviceToHostQ(mCopyQueue, mQueryData.count); + mCopyQueue.flushEnqueued(); + + PxTaskManager* tm = mManager->getApexScene().getTaskManager(); + tm->getGpuDispatcher()->addCompletionPrereq(*mTaskFetch); + } + + if (mOnFinishCallback) + { + (*mOnFinishCallback)(stream); + } + return false; +} + +FieldSamplerQueryGPU::SceneInfoGPU::SceneInfoGPU(ResourceList& list, FieldSamplerQuery* query, FieldSamplerSceneWrapper* sceneWrapper) + : SceneInfo(list, query, sceneWrapper) + , mConstMemGroup(DYNAMIC_CAST(FieldSamplerSceneWrapperGPU*)(sceneWrapper)->getConstStorage()) +{ + APEX_CUDA_CONST_MEM_GROUP_SCOPE(mConstMemGroup); + + mQueryParamsHandle.alloc(_storage_); +} + +bool FieldSamplerQueryGPU::SceneInfoGPU::update() +{ + if (FieldSamplerQuery::SceneInfo::update()) + { + APEX_CUDA_CONST_MEM_GROUP_SCOPE(mConstMemGroup); + + FieldSamplerParamsExArray paramsExArray; + mParamsExArrayHandle.allocOrFetch(_storage_, paramsExArray); + if (paramsExArray.resize(_storage_, mEnabledFieldSamplerCount)) + { + for (uint32_t i = 0, enabledIdx = 0; i < mFieldSamplerArray.size(); ++i) + { + FieldSamplerWrapperGPU* fieldSamplerWrapper = DYNAMIC_CAST(FieldSamplerWrapperGPU*)(mFieldSamplerArray[i].mFieldSamplerWrapper); + if (fieldSamplerWrapper->isEnabled()) + { + FieldSamplerParamsEx fsParamsEx; + fsParamsEx.paramsHandle = fieldSamplerWrapper->getParamsHandle(); + fsParamsEx.multiplier = mFieldSamplerArray[i].mMultiplier; + PX_ASSERT(enabledIdx < mEnabledFieldSamplerCount); + paramsExArray.updateElem(_storage_, fsParamsEx, enabledIdx++); + } + } + mParamsExArrayHandle.update(_storage_, paramsExArray); + } + return true; + } + return false; +} + +PxVec3 FieldSamplerQueryGPU::executeFieldSamplerQueryOnGrid(const FieldSamplerQueryGridDataIntl& data) +{ + FieldSamplerGridKernelArgs args; + + args.numX = data.numX; + args.numY = data.numY; + args.numZ = data.numZ; + + args.gridToWorld = data.gridToWorld; + + args.mass = data.mass; + args.elapsedTime = data.timeStep; + args.cellSize = data.cellSize; + args.totalElapsedMS = mManager->getApexScene().getTotalElapsedMS(); + + FieldSamplerGridKernelLaunchDataIntl launchData; + launchData.stream = data.stream; + launchData.kernelType = FieldSamplerKernelType::GRID; + launchData.kernelArgs = &args; + launchData.threadCountX = data.numX; + launchData.threadCountY = data.numY; + launchData.threadCountZ = data.numZ; + launchData.accumArray = data.resultVelocity; + + + { + APEX_CUDA_SURFACE_SCOPE_BIND(surfRefGridAccum, *launchData.accumArray, ApexCudaMemFlags::OUT); + + CUDA_OBJ(clearGridKernel)(data.stream, launchData.threadCountX, launchData.threadCountY, launchData.threadCountZ, + args.numX, args.numY, args.numZ); + } + + PxVec3 velocity(0.0f); + for (uint32_t i = 0; i < mSecondarySceneList.size(); ++i) + { + SceneInfoGPU* sceneInfo = DYNAMIC_CAST(SceneInfoGPU*)(mSecondarySceneList[i]); + FieldSamplerSceneWrapperGPU* sceneWrapper = DYNAMIC_CAST(FieldSamplerSceneWrapperGPU*)(sceneInfo->getSceneWrapper()); + + launchData.activeFieldSamplerCount = 0; + + const nvidia::Array<FieldSamplerInfo>& fieldSamplerArray = sceneInfo->getFieldSamplerArray(); + for (uint32_t fieldSamplerIdx = 0; fieldSamplerIdx < fieldSamplerArray.size(); ++fieldSamplerIdx) + { + const FieldSamplerWrapperGPU* wrapper = static_cast<const FieldSamplerWrapperGPU* >( fieldSamplerArray[fieldSamplerIdx].mFieldSamplerWrapper ); + if (wrapper->isEnabled()) + { + switch (wrapper->getInternalFieldSamplerDesc().gridSupportType) + { + case FieldSamplerGridSupportTypeIntl::SINGLE_VELOCITY: + { + const FieldSamplerIntl* fieldSampler = wrapper->getInternalFieldSampler(); + velocity += fieldSampler->queryFieldSamplerVelocity(); + } + break; + case FieldSamplerGridSupportTypeIntl::VELOCITY_PER_CELL: + { + launchData.activeFieldSamplerCount += 1; + } + break; + default: + break; + } + } + } + + if (launchData.activeFieldSamplerCount > 0) + { + launchData.queryParamsHandle = sceneInfo->getQueryParamsHandle(); + launchData.paramsExArrayHandle = sceneInfo->getParamsHandle(); + launchData.fieldSamplerArray = &sceneInfo->getFieldSamplerArray(); + launchData.kernelMode = FieldSamplerKernelMode::DEFAULT; + + sceneWrapper->getInternalFieldSamplerScene()->launchFieldSamplerCudaKernel(launchData); + } + } + return velocity; +} + + +#endif + +} +} // end namespace nvidia::apex + diff --git a/APEX_1.4/module/fieldsampler/src/FieldSamplerScene.cpp b/APEX_1.4/module/fieldsampler/src/FieldSamplerScene.cpp new file mode 100644 index 00000000..58c74ed7 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/FieldSamplerScene.cpp @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" +#include "Apex.h" + +#include "FieldSamplerScene.h" +#include "FieldSamplerManager.h" +#include "FieldSamplerQuery.h" +#include "FieldSamplerPhysXMonitor.h" +#include "SceneIntl.h" +#include "RenderDebugInterface.h" +#include "ModulePerfScope.h" + +#if APEX_CUDA_SUPPORT +#include "PxGpuTask.h" +#include "ApexCudaSource.h" +#endif + +#include "Lock.h" + +namespace nvidia +{ +namespace fieldsampler +{ + +FieldSamplerScene::FieldSamplerScene(ModuleFieldSamplerImpl& module, SceneIntl& scene, RenderDebugInterface* debugRender, ResourceList& list) + : mModule(&module) + , mApexScene(&scene) + , mDebugRender(debugRender) + , mManager(NULL) + , mPhysXScene(NULL) + , mForceSampleBatchBufferPos(0) + , mForceSampleBatchBufferSize(0) +{ + list.add(*this); // Add self to module's list of FieldSamplerScenes +} + +FieldSamplerScene::~FieldSamplerScene() +{ +} + +void FieldSamplerScene::visualize() +{ +#ifndef WITHOUT_DEBUG_VISUALIZE +#endif +} + +void FieldSamplerScene::destroy() +{ +#if PX_PHYSICS_VERSION_MAJOR == 3 + PX_DELETE(mPhysXMonitor); +#endif + PX_DELETE(mManager); + + removeAllActors(); + mApexScene->moduleReleased(*this); + delete this; +} + +FieldSamplerManagerIntl* FieldSamplerScene::getManager() +{ + if (mManager == NULL) + { + mManager = createManager(); + PX_ASSERT(mManager != NULL); + } + return mManager; +} + + + +void FieldSamplerScene::setModulePhysXScene(PxScene* s) +{ + if (s) + { + mPhysXMonitor->setPhysXScene(s); + } + mPhysXScene = s; +} + + +void FieldSamplerScene::submitTasks(float /*elapsedTime*/, float /*substepSize*/, uint32_t /*numSubSteps*/) +{ +#if PX_PHYSICS_VERSION_MAJOR == 3 + PxTaskManager* tm; + { + READ_LOCK(*mApexScene); + tm = mApexScene->getTaskManager(); + } + tm->submitNamedTask(&mPhysXMonitorFetchTask, FSST_PHYSX_MONITOR_FETCH); + tm->submitNamedTask(&mPhysXMonitorLoadTask, FSST_PHYSX_MONITOR_LOAD); +#endif + if (mManager != NULL) + { + mManager->submitTasks(); + } +} + +void FieldSamplerScene::setTaskDependencies() +{ +#if PX_PHYSICS_VERSION_MAJOR == 3 + for (uint32_t i = 0; i < mForceSampleBatchQuery.size(); i++) + { + if (mForceSampleBatchQuery[i] && mForceSampleBatchQueryData[i].count > 0) + { + static_cast<FieldSamplerQueryIntl*>(mForceSampleBatchQuery[i])->submitFieldSamplerQuery(mForceSampleBatchQueryData[i], mApexScene->getTaskManager()->getNamedTask(FSST_PHYSX_MONITOR_LOAD)); + mForceSampleBatchQueryData[i].count = 0; + } + mForceSampleBatchBufferPos = 0; + } + if (mPhysXMonitor->isEnable()) + { + mPhysXMonitor->update(); + } +#endif + if (mManager != NULL) + { + mManager->setTaskDependencies(); + } + +#if PX_PHYSICS_VERSION_MAJOR == 3 + // Just in case one of the scene conditions doesn't set a bounding dependency, let's not let these dangle + PxTaskManager* tm; + { + READ_LOCK(*mApexScene); + tm = mApexScene->getTaskManager(); + } + mPhysXMonitorFetchTask.finishBefore(tm->getNamedTask(AST_PHYSX_FETCH_RESULTS)); + mPhysXMonitorLoadTask.finishBefore(tm->getNamedTask(AST_PHYSX_FETCH_RESULTS)); +#endif +} + +void FieldSamplerScene::fetchResults() +{ + if (mManager != NULL) + { + mManager->fetchResults(); + } +} + +#if PX_PHYSICS_VERSION_MAJOR == 3 +void FieldSamplerScene::enablePhysXMonitor(bool enable) +{ + PX_UNUSED(enable); + mPhysXMonitor->enablePhysXMonitor(enable); +} + +void FieldSamplerScene::setPhysXFilterData(physx::PxFilterData filterData) +{ + mPhysXMonitor->setPhysXFilterData(filterData); +} + + +uint32_t FieldSamplerScene::createForceSampleBatch(uint32_t maxCount, const physx::PxFilterData filterData) +{ + mForceSampleBatchBufferSize += maxCount; + mForceSampleBatchPosition.resize(mForceSampleBatchBufferSize); + mForceSampleBatchVelocity.resize(mForceSampleBatchBufferSize); + mForceSampleBatchMass.resize(mForceSampleBatchBufferSize); + + FieldSamplerQueryDescIntl desc; + desc.maxCount = maxCount; + desc.samplerFilterData = filterData; + //SceneInfo* sceneInfo = DYNAMIC_CAST(SceneInfo*)(mSceneList.getResource(i)); + //InternalFieldSamplerScene* niFieldSamplerScene = sceneInfo->getSceneWrapper()->getInternalFieldSamplerScene(); + //desc.ownerFieldSamplerScene = this; + + + uint32_t id = 0; + while (id < mForceSampleBatchQuery.size() && mForceSampleBatchQuery[id]) + { + id++; + } + if (id == mForceSampleBatchQuery.size()) + { + mForceSampleBatchQuery.pushBack(0); + FieldSamplerQueryDataIntl data; + data.count = 0; + mForceSampleBatchQueryData.pushBack(data); + } + mForceSampleBatchQuery[id] = static_cast<FieldSamplerQuery*>(mManager->createFieldSamplerQuery(desc)); + return id; +} + + +void FieldSamplerScene::releaseForceSampleBatch(uint32_t batchId) +{ + if (batchId < mForceSampleBatchQuery.size() && mForceSampleBatchQuery[batchId]) + { + mForceSampleBatchBufferSize -= mForceSampleBatchQuery[batchId]->getQueryDesc().maxCount; + mForceSampleBatchPosition.resize(mForceSampleBatchBufferSize); + mForceSampleBatchVelocity.resize(mForceSampleBatchBufferSize); + mForceSampleBatchMass.resize(mForceSampleBatchBufferSize); + + mForceSampleBatchQuery[batchId]->release(); + mForceSampleBatchQuery[batchId] = 0; + } +} + + +void FieldSamplerScene::submitForceSampleBatch( uint32_t batchId, PxVec4* forces, const uint32_t forcesStride, + const PxVec3* positions, const uint32_t positionsStride, + const PxVec3* velocities, const uint32_t velocitiesStride, + const float* mass, const uint32_t massStride, + const uint32_t* indices, const uint32_t numIndices) +{ + PX_UNUSED(forcesStride); + PX_ASSERT(forcesStride == sizeof(PxVec4)); + PX_ASSERT(indices); + if (batchId >= mForceSampleBatchQuery.size() || mForceSampleBatchQuery[batchId] == 0) return; + + uint32_t maxIndices = indices[numIndices - 1] + 1; //supposed that indices are sorted + for (uint32_t i = 0; i < maxIndices; i++) + { + mForceSampleBatchPosition[mForceSampleBatchBufferPos + i] = *(PxVec4*)((uint8_t*)positions + i * positionsStride); + mForceSampleBatchVelocity[mForceSampleBatchBufferPos + i] = *(PxVec4*)((uint8_t*)velocities + i * velocitiesStride); + mForceSampleBatchMass[mForceSampleBatchBufferPos + i] = *(float*)((uint8_t*)mass + i * massStride); + } + + FieldSamplerQueryDataIntl& data = mForceSampleBatchQueryData[batchId]; + data.count = numIndices; + data.isDataOnDevice = false; + data.positionStrideBytes = sizeof(PxVec4); + data.velocityStrideBytes = sizeof(PxVec4); + data.massStrideBytes = massStride ? sizeof(float) : 0; + data.pmaInMass = (float*)&mForceSampleBatchMass[mForceSampleBatchBufferPos]; + data.pmaInPosition = (float*)&mForceSampleBatchPosition[mForceSampleBatchBufferPos]; + data.pmaInVelocity = (float*)&mForceSampleBatchVelocity[mForceSampleBatchBufferPos]; + data.pmaInIndices = (uint32_t*)indices; + data.pmaOutField = forces; + data.timeStep = getApexScene().getPhysXSimulateTime(); + + mForceSampleBatchBufferPos += maxIndices; +} + +#endif + +/******************************** CPU Version ********************************/ + + +FieldSamplerSceneCPU::FieldSamplerSceneCPU(ModuleFieldSamplerImpl& module, SceneIntl& scene, RenderDebugInterface* debugRender, ResourceList& list) : + FieldSamplerScene(module, scene, debugRender, list) +{ +#if PX_PHYSICS_VERSION_MAJOR == 3 + mPhysXMonitor = PX_NEW(FieldSamplerPhysXMonitor)(*this); +#endif +} + +FieldSamplerSceneCPU::~FieldSamplerSceneCPU() +{ +} + +FieldSamplerManager* FieldSamplerSceneCPU::createManager() +{ + return PX_NEW(FieldSamplerManagerCPU)(this); +} + +/******************************** GPU Version ********************************/ + +#if APEX_CUDA_SUPPORT + +FieldSamplerSceneGPU::FieldSamplerSceneGPU(ModuleFieldSamplerImpl& module, SceneIntl& scene, RenderDebugInterface* debugRender, ResourceList& list) + : FieldSamplerScene(module, scene, debugRender, list) + , CudaModuleScene(scene, *mModule, APEX_CUDA_TO_STR(APEX_CUDA_MODULE_PREFIX)) +{ +#if PX_PHYSICS_VERSION_MAJOR == 3 + mPhysXMonitor = PX_NEW(FieldSamplerPhysXMonitor)(*this); +#endif + { + PxGpuDispatcher* gd = mApexScene->getTaskManager()->getGpuDispatcher(); + PX_ASSERT(gd != NULL); + mCtxMgr = gd->getCudaContextManager(); + PxScopedCudaLock _lock_(*mCtxMgr); + +//CUDA module objects +#include "../cuda/include/fieldsampler.h" + } +} + +FieldSamplerSceneGPU::~FieldSamplerSceneGPU() +{ + CudaModuleScene::destroy(*mApexScene); +} + +FieldSamplerManager* FieldSamplerSceneGPU::createManager() +{ + return PX_NEW(FieldSamplerManagerGPU)(this); +} + +#endif + +} +} // end namespace nvidia::apex + + diff --git a/APEX_1.4/module/fieldsampler/src/FieldSamplerSceneWrapper.cpp b/APEX_1.4/module/fieldsampler/src/FieldSamplerSceneWrapper.cpp new file mode 100644 index 00000000..405462e7 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/FieldSamplerSceneWrapper.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" +#include "Apex.h" +#include "FieldSamplerSceneWrapper.h" +#include "FieldSamplerManager.h" +#include "FieldBoundaryWrapper.h" +#include "FieldSamplerWrapper.h" + + +namespace nvidia +{ +namespace fieldsampler +{ + +FieldSamplerSceneWrapper::FieldSamplerSceneWrapper(ResourceList& list, FieldSamplerManager* manager, FieldSamplerSceneIntl* fieldSamplerScene) + : mManager(manager) + , mFieldSamplerScene(fieldSamplerScene) + , mFieldBoundaryListChanged(false) +{ + mFieldSamplerScene->getFieldSamplerSceneDesc(mFieldSamplerSceneDesc); + + list.add(*this); +} + +void FieldSamplerSceneWrapper::release() +{ + delete this; +} + +FieldSamplerSceneWrapper::FieldBoundaryInfo* FieldSamplerSceneWrapper::addFieldBoundary(FieldBoundaryWrapper* fieldBoundaryWrapper) +{ + FieldBoundaryInfo* fieldBoundaryInfo = NULL; + for (uint32_t i = 0; i < mFieldBoundaryList.getSize(); ++i) + { + FieldBoundaryInfo* info = DYNAMIC_CAST(FieldBoundaryInfo*)(mFieldBoundaryList.getResource(i)); + if (info->getFieldBoundaryWrapper() == fieldBoundaryWrapper) + { + fieldBoundaryInfo = info; + break; + } + } + if (fieldBoundaryInfo == NULL) + { + fieldBoundaryInfo = createFieldBoundaryInfo(fieldBoundaryWrapper); + mFieldBoundaryListChanged = true; + } + fieldBoundaryInfo->addRef(); + return fieldBoundaryInfo; +} + +void FieldSamplerSceneWrapper::removeFieldBoundary(FieldBoundaryInfo* fieldBoundaryInfo) +{ + if (fieldBoundaryInfo->releaseRef()) + { + mFieldBoundaryListChanged = true; + } +} + +void FieldSamplerSceneWrapper::update() +{ + for (uint32_t i = 0; i < mFieldBoundaryList.getSize(); ++i) + { + FieldBoundaryInfo* info = DYNAMIC_CAST(FieldBoundaryInfo*)(mFieldBoundaryList.getResource(i)); + info->update(); + } +} + +/******************************** CPU Version ********************************/ +FieldSamplerSceneWrapperCPU::FieldSamplerSceneWrapperCPU(ResourceList& list, FieldSamplerManager* manager, FieldSamplerSceneIntl* fieldSamplerScene) + : FieldSamplerSceneWrapper(list, manager, fieldSamplerScene) +{ +} + +/******************************** GPU Version ********************************/ +#if APEX_CUDA_SUPPORT + +FieldSamplerSceneWrapperGPU::FieldSamplerSceneWrapperGPU(ResourceList& list, FieldSamplerManager* manager, FieldSamplerSceneIntl* fieldSamplerScene) + : FieldSamplerSceneWrapper(list, manager, fieldSamplerScene) + , mConstStorage(*fieldSamplerScene->getFieldSamplerCudaConstStorage()) +{ +} + +void FieldSamplerSceneWrapperGPU::postUpdate() +{ + PxCudaContextManager* ctx = DYNAMIC_CAST(FieldSamplerSceneGPU*)(mManager->getScene())->getCudaContext(); + PxScopedCudaLock _lock_(*ctx); + + getConstStorage().copyToDevice(ctx, 0); +} + + +FieldSamplerSceneWrapperGPU::FieldBoundaryInfoGPU::FieldBoundaryInfoGPU(ResourceList& list, FieldBoundaryWrapper* fieldBoundaryWrapper, ApexCudaConstStorage& constStorage) + : FieldBoundaryInfo(list, fieldBoundaryWrapper) + , mConstMemGroup(constStorage) +{ + APEX_CUDA_CONST_MEM_GROUP_SCOPE(mConstMemGroup); + mFieldShapeGroupParamsHandle.alloc(_storage_); +} + +void FieldSamplerSceneWrapperGPU::FieldBoundaryInfoGPU::update() +{ + if (mFieldBoundaryWrapper->getFieldShapesChanged()) + { + APEX_CUDA_CONST_MEM_GROUP_SCOPE(mConstMemGroup); + + FieldShapeGroupParams shapeGroupParams; + mFieldShapeGroupParamsHandle.fetch(_storage_, shapeGroupParams); + + const nvidia::Array<FieldShapeDescIntl>& shapes = mFieldBoundaryWrapper->getFieldShapes(); + uint32_t shapeCount = shapes.size(); + shapeGroupParams.shapeArray.resize(_storage_, shapeCount); + for (uint32_t i = 0; i < shapeCount; ++i) + { + FieldShapeParams elem; + elem.type = shapes[i].type; + elem.dimensions = shapes[i].dimensions; + elem.worldToShape = shapes[i].worldToShape; + PX_ASSERT(shapes[i].weight >= 0.0f && shapes[i].weight <= 1.0f); + elem.weight = PxClamp(shapes[i].weight, 0.0f, 1.0f); + elem.fade = 0; + + shapeGroupParams.shapeArray.updateElem(_storage_, elem, i); + } + + mFieldShapeGroupParamsHandle.update(_storage_, shapeGroupParams); + } +} + +#endif // APEX_CUDA_SUPPORT + +} +} // end namespace nvidia::apex + diff --git a/APEX_1.4/module/fieldsampler/src/FieldSamplerWrapper.cpp b/APEX_1.4/module/fieldsampler/src/FieldSamplerWrapper.cpp new file mode 100644 index 00000000..94d18a76 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/FieldSamplerWrapper.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" +#include "Apex.h" +#include "FieldSamplerWrapper.h" +#include "FieldBoundaryWrapper.h" +#include "FieldSamplerManager.h" +#include "FieldSamplerSceneWrapper.h" + + +namespace nvidia +{ +namespace fieldsampler +{ + + +FieldSamplerWrapper::FieldSamplerWrapper(ResourceList& list, FieldSamplerManager* manager, FieldSamplerIntl* fieldSampler, const FieldSamplerDescIntl& fieldSamplerDesc, FieldSamplerSceneWrapper* fieldSamplerSceneWrapper) + : mManager(manager) + , mFieldSampler(fieldSampler) + , mFieldSamplerDesc(fieldSamplerDesc) + , mFieldSamplerShapeChanged(false) + , mSceneWrapper(fieldSamplerSceneWrapper) + , mQueryRefCount(0) + , mFieldBoundaryInfoArrayChanged(true) + , mIsEnabled(false) + , mIsEnabledLast(false) +{ + list.add(*this); + + //set default shape weight to 1 + mFieldSamplerShape.weight = 1; +} + +void FieldSamplerWrapper::release() +{ + for (uint32_t i = 0; i < mFieldBoundaryInfoArray.size(); ++i) + { + FieldSamplerSceneWrapper::FieldBoundaryInfo* fieldBoundaryInfo = mFieldBoundaryInfoArray[i]; + mSceneWrapper->removeFieldBoundary(fieldBoundaryInfo); + } + + delete this; +} + +bool FieldSamplerWrapper::addFieldBoundary(FieldBoundaryWrapper* fieldBoundaryWrapper) +{ + const FieldBoundaryDescIntl& fieldBoundaryDesc = fieldBoundaryWrapper->getInternalFieldBoundaryDesc(); + + float weight; + if (mManager->getFieldSamplerGroupsFiltering(fieldBoundaryDesc.boundaryFilterData, mFieldSamplerDesc.boundaryFilterData,weight)) + { + FieldSamplerSceneWrapper::FieldBoundaryInfo* fieldBoundaryInfo = + mSceneWrapper->addFieldBoundary(fieldBoundaryWrapper); + + mFieldBoundaryInfoArray.pushBack(fieldBoundaryInfo); + mFieldBoundaryInfoArrayChanged = true; + return true; + } + return false; +} + +bool FieldSamplerWrapper::removeFieldBoundary(FieldBoundaryWrapper* fieldBoundaryWrapper) +{ + for (uint32_t i = 0; i < mFieldBoundaryInfoArray.size(); ++i) + { + FieldSamplerSceneWrapper::FieldBoundaryInfo* fieldBoundaryInfo = mFieldBoundaryInfoArray[i]; + if (fieldBoundaryInfo->getFieldBoundaryWrapper() == fieldBoundaryWrapper) + { + mSceneWrapper->removeFieldBoundary(fieldBoundaryInfo); + + mFieldBoundaryInfoArray.replaceWithLast(i); + mFieldBoundaryInfoArrayChanged = true; + return true; + } + } + return false; +} + +void FieldSamplerWrapper::update() +{ + mIsEnabledLast = mIsEnabled; + mFieldSamplerShapeChanged = mFieldSampler->updateFieldSampler(mFieldSamplerShape, mIsEnabled); + if (!mIsEnabledLast && mIsEnabled) + { + mFieldSamplerShapeChanged = true; + } + else if (!mIsEnabled) + { + mFieldSamplerShapeChanged = false; + } +} + +/******************************** CPU Version ********************************/ + +FieldSamplerWrapperCPU::FieldSamplerWrapperCPU(ResourceList& list, FieldSamplerManager* manager, FieldSamplerIntl* fieldSampler, const FieldSamplerDescIntl& fieldSamplerDesc, FieldSamplerSceneWrapper* fieldSamplerSceneWrapper) + : FieldSamplerWrapper(list, manager, fieldSampler, fieldSamplerDesc, fieldSamplerSceneWrapper) +{ +} + +/******************************** GPU Version ********************************/ +#if APEX_CUDA_SUPPORT + +FieldSamplerWrapperGPU::FieldSamplerWrapperGPU(ResourceList& list, FieldSamplerManager* manager, FieldSamplerIntl* fieldSampler, const FieldSamplerDescIntl& fieldSamplerDesc, FieldSamplerSceneWrapper* fieldSamplerSceneWrapper) + : FieldSamplerWrapperCPU(list, manager, fieldSampler, fieldSamplerDesc, fieldSamplerSceneWrapper) + , mConstMemGroup(DYNAMIC_CAST(FieldSamplerSceneWrapperGPU*)(fieldSamplerSceneWrapper)->getConstStorage()) +{ +} + +void FieldSamplerWrapperGPU::update() +{ + FieldSamplerWrapper::update(); + if (mFieldSamplerShapeChanged || mFieldBoundaryInfoArrayChanged) + { + APEX_CUDA_CONST_MEM_GROUP_SCOPE(mConstMemGroup); + + FieldSamplerParams params; + if (mFieldSamplerParamsHandle.allocOrFetch(_storage_, params)) + { + //only on alloc + params.type = mFieldSamplerDesc.type; + params.gridSupportType = mFieldSamplerDesc.gridSupportType; + params.dragCoeff = mFieldSamplerDesc.dragCoeff; + + params.includeShape.fade = PxClamp(mFieldSamplerDesc.boundaryFadePercentage, 0.0f, 1.0f); + } + + if (mFieldSamplerShapeChanged) + { + FieldSamplerIntl::CudaExecuteInfo executeInfo; + mFieldSampler->getFieldSamplerCudaExecuteInfo(executeInfo); + + params.executeType = executeInfo.executeType; + params.executeParamsHandle = executeInfo.executeParamsHandle; + + params.includeShape.type = mFieldSamplerShape.type; + params.includeShape.dimensions = mFieldSamplerShape.dimensions; + params.includeShape.worldToShape = mFieldSamplerShape.worldToShape; + PX_ASSERT(mFieldSamplerShape.weight >= 0.0f && mFieldSamplerShape.weight <= 1.0f); + params.includeShape.weight = PxClamp(mFieldSamplerShape.weight, 0.0f, 1.0f); + } + + if (mFieldBoundaryInfoArrayChanged) + { + uint32_t shapeGroupCount = mFieldBoundaryInfoArray.size(); + if (params.excludeShapeGroupHandleArray.resize(_storage_, shapeGroupCount)) + { + for (uint32_t shapeGroupIndex = 0; shapeGroupIndex < shapeGroupCount; ++shapeGroupIndex) + { + FieldSamplerSceneWrapperGPU::FieldBoundaryInfoGPU* fieldBoundaryInfo = + static_cast<FieldSamplerSceneWrapperGPU::FieldBoundaryInfoGPU*>(mFieldBoundaryInfoArray[shapeGroupIndex]); + + InplaceHandle<FieldShapeGroupParams> elem = fieldBoundaryInfo->getShapeGroupParamsHandle(); + params.excludeShapeGroupHandleArray.updateElem(_storage_, elem, shapeGroupIndex); + } + } + + mFieldBoundaryInfoArrayChanged = false; + } + + mFieldSamplerParamsHandle.update(_storage_, params); + } +} + +#endif + +} +} // end namespace nvidia::apex + diff --git a/APEX_1.4/module/fieldsampler/src/ModuleFieldSamplerImpl.cpp b/APEX_1.4/module/fieldsampler/src/ModuleFieldSamplerImpl.cpp new file mode 100644 index 00000000..7634c180 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/ModuleFieldSamplerImpl.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, 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. + */ + + +#include "ApexDefs.h" +#include "Apex.h" +#include "ModuleFieldSamplerImpl.h" +#include "ModuleFieldSamplerRegistration.h" +#include "FieldSamplerScene.h" +#include "FieldSamplerManager.h" +#include "SceneIntl.h" +#include "PsMemoryBuffer.h" +#include "ModulePerfScope.h" +using namespace fieldsampler; + +#include "ApexSDKIntl.h" +#include "ApexUsingNamespace.h" + +#include "Lock.h" + +#include "ReadCheck.h" +#include "WriteCheck.h" + +namespace nvidia +{ +namespace apex +{ + +#if defined(_USRDLL) + +/* Modules don't have to link against the framework, they keep their own */ +ApexSDKIntl* gApexSdk = 0; +ApexSDK* GetApexSDK() +{ + return gApexSdk; +} +ApexSDKIntl* GetInternalApexSDK() +{ + return gApexSdk; +} + +APEX_API Module* CALL_CONV createModule( + ApexSDKIntl* inSdk, + ModuleIntl** niRef, + uint32_t APEXsdkVersion, + uint32_t PhysXsdkVersion, + ApexCreateError* errorCode) +{ + if (APEXsdkVersion != APEX_SDK_VERSION) + { + if (errorCode) + { + *errorCode = APEX_CE_WRONG_VERSION; + } + return NULL; + } + + if (PhysXsdkVersion != PX_PHYSICS_VERSION) + { + if (errorCode) + { + *errorCode = APEX_CE_WRONG_VERSION; + } + return NULL; + } + + gApexSdk = inSdk; + ModuleFieldSamplerImpl* impl = PX_NEW(ModuleFieldSampler)(inSdk); + *niRef = (ModuleIntl*) impl; + return (Module*) impl; +} + +#else +/* Statically linking entry function */ +void instantiateModuleFieldSampler() +{ + ApexSDKIntl* sdk = GetInternalApexSDK(); + nvidia::fieldsampler::ModuleFieldSamplerImpl* impl = PX_NEW(fieldsampler::ModuleFieldSamplerImpl)(sdk); + sdk->registerExternalModule((Module*) impl, (ModuleIntl*) impl); +} +#endif // `defined(_USRDLL) +} + +namespace fieldsampler +{ +/* === ModuleFieldSamplerImpl Implementation === */ +ModuleFieldSamplerImpl::ModuleFieldSamplerImpl(ApexSDKIntl* sdk) +{ + mName = "FieldSampler"; + mSdk = sdk; + mApiProxy = this; + mModuleParams = NULL; + + /* Register the NvParameterized factories */ + NvParameterized::Traits* traits = mSdk->getParameterizedTraits(); + ModuleFieldSamplerRegistration::invokeRegistration(traits); +} + +ModuleFieldSamplerImpl::~ModuleFieldSamplerImpl() +{ +} + +void ModuleFieldSamplerImpl::destroy() +{ + NvParameterized::Traits* traits = mSdk->getParameterizedTraits(); + + if (mModuleParams) + { + mModuleParams->destroy(); + mModuleParams = NULL; + } + + ModuleBase::destroy(); + + if (traits) + { + /* Remove the NvParameterized factories */ + ModuleFieldSamplerRegistration::invokeUnregistration(traits); + } + + delete this; +} + +void ModuleFieldSamplerImpl::init(NvParameterized::Interface&) +{ +} + +NvParameterized::Interface* ModuleFieldSamplerImpl::getDefaultModuleDesc() +{ + NvParameterized::Traits* traits = mSdk->getParameterizedTraits(); + + if (!mModuleParams) + { + mModuleParams = DYNAMIC_CAST(FieldSamplerModuleParameters*) + (traits->createNvParameterized("FieldSamplerModuleParameters")); + PX_ASSERT(mModuleParams); + } + else + { + mModuleParams->initDefaults(); + } + + return mModuleParams; +} + +FieldSamplerManagerIntl* ModuleFieldSamplerImpl::getInternalFieldSamplerManager(const Scene& apexScene) +{ + FieldSamplerScene* scene = ModuleFieldSamplerImpl::getFieldSamplerScene(apexScene); + return scene->getManager(); +} + + +AuthObjTypeID ModuleFieldSamplerImpl::getModuleID() const +{ + return 0; +} + + +/* == Example Scene methods == */ +ModuleSceneIntl* ModuleFieldSamplerImpl::createInternalModuleScene(SceneIntl& scene, RenderDebugInterface* debugRender) +{ +#if APEX_CUDA_SUPPORT + READ_LOCK(scene); + if (scene.getTaskManager()->getGpuDispatcher() && scene.isUsingCuda()) + { + return PX_NEW(FieldSamplerSceneGPU)(*this, scene, debugRender, mFieldSamplerScenes); + } + else +#endif + return PX_NEW(FieldSamplerSceneCPU)(*this, scene, debugRender, mFieldSamplerScenes); +} + +void ModuleFieldSamplerImpl::releaseModuleSceneIntl(ModuleSceneIntl& scene) +{ + FieldSamplerScene* es = DYNAMIC_CAST(FieldSamplerScene*)(&scene); + es->destroy(); +} + +nvidia::fieldsampler::FieldSamplerScene* ModuleFieldSamplerImpl::getFieldSamplerScene(const Scene& apexScene) const +{ + for (uint32_t i = 0 ; i < mFieldSamplerScenes.getSize() ; i++) + { + FieldSamplerScene* es = DYNAMIC_CAST(FieldSamplerScene*)(mFieldSamplerScenes.getResource(i)); + if (es->mApexScene == &apexScene) + { + return es; + } + } + + PX_ASSERT(!"Unable to locate an appropriate FieldSamplerScene"); + return NULL; +} + +RenderableIterator* ModuleFieldSamplerImpl::createRenderableIterator(const Scene& apexScene) +{ + FieldSamplerScene* es = getFieldSamplerScene(apexScene); + if (es) + { + return es->createRenderableIterator(); + } + + return NULL; +} + + + +bool ModuleFieldSamplerImpl::setFieldSamplerWeightedCollisionFilterCallback(const Scene& apexScene,FieldSamplerWeightedCollisionFilterCallback *callback) +{ + WRITE_ZONE(); + FieldSamplerScene* scene = getFieldSamplerScene(apexScene); + if (scene != NULL) + { + DYNAMIC_CAST(FieldSamplerManager*)(scene->getManager())->setFieldSamplerWeightedCollisionFilterCallback(callback); + return true; + } + return false; + +} + +#if PX_PHYSICS_VERSION_MAJOR == 3 +void ModuleFieldSamplerImpl::enablePhysXMonitor(const Scene& apexScene, bool enable) +{ + WRITE_ZONE(); + getFieldSamplerScene(apexScene)->enablePhysXMonitor(enable); +} + +void ModuleFieldSamplerImpl::setPhysXMonitorFilterData(const Scene& apexScene, physx::PxFilterData filterData) +{ + WRITE_ZONE(); + getFieldSamplerScene(apexScene)->setPhysXFilterData(filterData); +} +#endif + +uint32_t ModuleFieldSamplerImpl::createForceSampleBatch(const Scene& apexScene, uint32_t maxCount, const physx::PxFilterData filterData) +{ + WRITE_ZONE(); + FieldSamplerScene* fsScene = getFieldSamplerScene(apexScene); + if (fsScene) + { + return fsScene->createForceSampleBatch(maxCount, filterData); + } + return (uint32_t)~0; +} + + +void ModuleFieldSamplerImpl::releaseForceSampleBatch(const Scene& apexScene, uint32_t batchId) +{ + WRITE_ZONE(); + FieldSamplerScene* fsScene = getFieldSamplerScene(apexScene); + if (fsScene) + { + fsScene->releaseForceSampleBatch(batchId); + } +} + + +void ModuleFieldSamplerImpl::submitForceSampleBatch(const Scene& apexScene, uint32_t batchId, + PxVec4* forces, const uint32_t forcesStride, + const PxVec3* positions, const uint32_t positionsStride, + const PxVec3* velocities, const uint32_t velocitiesStride, + const float* mass, const uint32_t massStride, + const uint32_t* indices, const uint32_t numIndices) +{ + WRITE_ZONE(); + FieldSamplerScene* fsScene = getFieldSamplerScene(apexScene); + if (fsScene) + { + fsScene->submitForceSampleBatch(batchId, forces, forcesStride, positions, positionsStride, velocities, velocitiesStride, mass, massStride, indices, numIndices); + } +} + + +} +} // end namespace nvidia::apex diff --git a/APEX_1.4/module/fieldsampler/src/autogen/FieldSamplerModuleParameters.cpp b/APEX_1.4/module/fieldsampler/src/autogen/FieldSamplerModuleParameters.cpp new file mode 100644 index 00000000..2b76ff70 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/autogen/FieldSamplerModuleParameters.cpp @@ -0,0 +1,318 @@ +// 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-2015 NVIDIA Corporation. All rights reserved. + +// This file was generated by NvParameterized/scripts/GenParameterized.pl + + +#include "FieldSamplerModuleParameters.h" +#include <string.h> +#include <stdlib.h> + +using namespace NvParameterized; + +namespace nvidia +{ +namespace fieldsampler +{ + +using namespace FieldSamplerModuleParametersNS; + +const char* const FieldSamplerModuleParametersFactory::vptr = + NvParameterized::getVptr<FieldSamplerModuleParameters, FieldSamplerModuleParameters::ClassAlignment>(); + +const uint32_t NumParamDefs = 2; +static NvParameterized::DefinitionImpl* ParamDefTable; // now allocated in buildTree [NumParamDefs]; + + +static const size_t ParamLookupChildrenTable[] = +{ + 1, +}; + +#define TENUM(type) nvidia::##type +#define CHILDREN(index) &ParamLookupChildrenTable[index] +static const NvParameterized::ParamLookupNode ParamLookupTable[NumParamDefs] = +{ + { TYPE_STRUCT, false, 0, CHILDREN(0), 1 }, + { TYPE_U32, false, (size_t)(&((ParametersStruct*)0)->unused), NULL, 0 }, // unused +}; + + +bool FieldSamplerModuleParameters::mBuiltFlag = false; +NvParameterized::MutexType FieldSamplerModuleParameters::mBuiltFlagMutex; + +FieldSamplerModuleParameters::FieldSamplerModuleParameters(NvParameterized::Traits* traits, void* buf, int32_t* refCount) : + NvParameters(traits, buf, refCount) +{ + //mParameterizedTraits->registerFactory(className(), &FieldSamplerModuleParametersFactoryInst); + + if (!buf) //Do not init data if it is inplace-deserialized + { + initDynamicArrays(); + initStrings(); + initReferences(); + initDefaults(); + } +} + +FieldSamplerModuleParameters::~FieldSamplerModuleParameters() +{ + freeStrings(); + freeReferences(); + freeDynamicArrays(); +} + +void FieldSamplerModuleParameters::destroy() +{ + // We cache these fields here to avoid overwrite in destructor + bool doDeallocateSelf = mDoDeallocateSelf; + NvParameterized::Traits* traits = mParameterizedTraits; + int32_t* refCount = mRefCount; + void* buf = mBuffer; + + this->~FieldSamplerModuleParameters(); + + NvParameters::destroy(this, traits, doDeallocateSelf, refCount, buf); +} + +const NvParameterized::DefinitionImpl* FieldSamplerModuleParameters::getParameterDefinitionTree(void) +{ + if (!mBuiltFlag) // Double-checked lock + { + NvParameterized::MutexType::ScopedLock lock(mBuiltFlagMutex); + if (!mBuiltFlag) + { + buildTree(); + } + } + + return(&ParamDefTable[0]); +} + +const NvParameterized::DefinitionImpl* FieldSamplerModuleParameters::getParameterDefinitionTree(void) const +{ + FieldSamplerModuleParameters* tmpParam = const_cast<FieldSamplerModuleParameters*>(this); + + if (!mBuiltFlag) // Double-checked lock + { + NvParameterized::MutexType::ScopedLock lock(mBuiltFlagMutex); + if (!mBuiltFlag) + { + tmpParam->buildTree(); + } + } + + return(&ParamDefTable[0]); +} + +NvParameterized::ErrorType FieldSamplerModuleParameters::getParameterHandle(const char* long_name, Handle& handle) const +{ + ErrorType Ret = NvParameters::getParameterHandle(long_name, handle); + if (Ret != ERROR_NONE) + { + return(Ret); + } + + size_t offset; + void* ptr; + + getVarPtr(handle, ptr, offset); + + if (ptr == NULL) + { + return(ERROR_INDEX_OUT_OF_RANGE); + } + + return(ERROR_NONE); +} + +NvParameterized::ErrorType FieldSamplerModuleParameters::getParameterHandle(const char* long_name, Handle& handle) +{ + ErrorType Ret = NvParameters::getParameterHandle(long_name, handle); + if (Ret != ERROR_NONE) + { + return(Ret); + } + + size_t offset; + void* ptr; + + getVarPtr(handle, ptr, offset); + + if (ptr == NULL) + { + return(ERROR_INDEX_OUT_OF_RANGE); + } + + return(ERROR_NONE); +} + +void FieldSamplerModuleParameters::getVarPtr(const Handle& handle, void*& ptr, size_t& offset) const +{ + ptr = getVarPtrHelper(&ParamLookupTable[0], const_cast<FieldSamplerModuleParameters::ParametersStruct*>(¶meters()), handle, offset); +} + + +/* Dynamic Handle Indices */ + +void FieldSamplerModuleParameters::freeParameterDefinitionTable(NvParameterized::Traits* traits) +{ + if (!traits) + { + return; + } + + if (!mBuiltFlag) // Double-checked lock + { + return; + } + + NvParameterized::MutexType::ScopedLock lock(mBuiltFlagMutex); + + if (!mBuiltFlag) + { + return; + } + + for (uint32_t i = 0; i < NumParamDefs; ++i) + { + ParamDefTable[i].~DefinitionImpl(); + } + + traits->free(ParamDefTable); + + mBuiltFlag = false; +} + +#define PDEF_PTR(index) (&ParamDefTable[index]) + +void FieldSamplerModuleParameters::buildTree(void) +{ + + uint32_t allocSize = sizeof(NvParameterized::DefinitionImpl) * NumParamDefs; + ParamDefTable = (NvParameterized::DefinitionImpl*)(mParameterizedTraits->alloc(allocSize)); + memset(ParamDefTable, 0, allocSize); + + for (uint32_t i = 0; i < NumParamDefs; ++i) + { + NV_PARAM_PLACEMENT_NEW(ParamDefTable + i, NvParameterized::DefinitionImpl)(*mParameterizedTraits); + } + + // Initialize DefinitionImpl node: nodeIndex=0, longName="" + { + NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[0]; + ParamDef->init("", TYPE_STRUCT, "STRUCT", true); + +#ifdef NV_PARAMETERIZED_HIDE_DESCRIPTIONS + +#else + + static HintImpl HintTable[1]; + static Hint* HintPtrTable[1] = { &HintTable[0], }; + HintTable[0].init("shortDescription", "This class is used for initializing the ModuleFieldSampler.", true); + ParamDefTable[0].setHints((const NvParameterized::Hint**)HintPtrTable, 1); + +#endif /* NV_PARAMETERIZED_HIDE_DESCRIPTIONS */ + + + + + + } + + // Initialize DefinitionImpl node: nodeIndex=1, longName="unused" + { + NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[1]; + ParamDef->init("unused", TYPE_U32, NULL, true); + +#ifdef NV_PARAMETERIZED_HIDE_DESCRIPTIONS + +#else + + static HintImpl HintTable[1]; + static Hint* HintPtrTable[1] = { &HintTable[0], }; + HintTable[0].init("shortDescription", "No parameters necessary", true); + ParamDefTable[1].setHints((const NvParameterized::Hint**)HintPtrTable, 1); + +#endif /* NV_PARAMETERIZED_HIDE_DESCRIPTIONS */ + + + + + + } + + // SetChildren for: nodeIndex=0, longName="" + { + static Definition* Children[1]; + Children[0] = PDEF_PTR(1); + + ParamDefTable[0].setChildren(Children, 1); + } + + mBuiltFlag = true; + +} +void FieldSamplerModuleParameters::initStrings(void) +{ +} + +void FieldSamplerModuleParameters::initDynamicArrays(void) +{ +} + +void FieldSamplerModuleParameters::initDefaults(void) +{ + + freeStrings(); + freeReferences(); + freeDynamicArrays(); + unused = uint32_t(0); + + initDynamicArrays(); + initStrings(); + initReferences(); +} + +void FieldSamplerModuleParameters::initReferences(void) +{ +} + +void FieldSamplerModuleParameters::freeDynamicArrays(void) +{ +} + +void FieldSamplerModuleParameters::freeStrings(void) +{ +} + +void FieldSamplerModuleParameters::freeReferences(void) +{ +} + +} // namespace fieldsampler +} // namespace nvidia diff --git a/APEX_1.4/module/fieldsampler/src/autogen/FieldSamplerPhysXMonitorParams.cpp b/APEX_1.4/module/fieldsampler/src/autogen/FieldSamplerPhysXMonitorParams.cpp new file mode 100644 index 00000000..06762a63 --- /dev/null +++ b/APEX_1.4/module/fieldsampler/src/autogen/FieldSamplerPhysXMonitorParams.cpp @@ -0,0 +1,358 @@ +// 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-2015 NVIDIA Corporation. All rights reserved. + +// This file was generated by NvParameterized/scripts/GenParameterized.pl + + +#include "FieldSamplerPhysXMonitorParams.h" +#include <string.h> +#include <stdlib.h> + +using namespace NvParameterized; + +namespace nvidia +{ +namespace fieldsampler +{ + +using namespace FieldSamplerPhysXMonitorParamsNS; + +const char* const FieldSamplerPhysXMonitorParamsFactory::vptr = + NvParameterized::getVptr<FieldSamplerPhysXMonitorParams, FieldSamplerPhysXMonitorParams::ClassAlignment>(); + +const uint32_t NumParamDefs = 4; +static NvParameterized::DefinitionImpl* ParamDefTable; // now allocated in buildTree [NumParamDefs]; + + +static const size_t ParamLookupChildrenTable[] = +{ + 1, 2, 3, +}; + +#define TENUM(type) nvidia::##type +#define CHILDREN(index) &ParamLookupChildrenTable[index] +static const NvParameterized::ParamLookupNode ParamLookupTable[NumParamDefs] = +{ + { TYPE_STRUCT, false, 0, CHILDREN(0), 3 }, + { TYPE_U32, false, (size_t)(&((ParametersStruct*)0)->maxRBCount), NULL, 0 }, // maxRBCount + { TYPE_U32, false, (size_t)(&((ParametersStruct*)0)->maxPSCount), NULL, 0 }, // maxPSCount + { TYPE_U32, false, (size_t)(&((ParametersStruct*)0)->maxParticleCount), NULL, 0 }, // maxParticleCount +}; + + +bool FieldSamplerPhysXMonitorParams::mBuiltFlag = false; +NvParameterized::MutexType FieldSamplerPhysXMonitorParams::mBuiltFlagMutex; + +FieldSamplerPhysXMonitorParams::FieldSamplerPhysXMonitorParams(NvParameterized::Traits* traits, void* buf, int32_t* refCount) : + NvParameters(traits, buf, refCount) +{ + //mParameterizedTraits->registerFactory(className(), &FieldSamplerPhysXMonitorParamsFactoryInst); + + if (!buf) //Do not init data if it is inplace-deserialized + { + initDynamicArrays(); + initStrings(); + initReferences(); + initDefaults(); + } +} + +FieldSamplerPhysXMonitorParams::~FieldSamplerPhysXMonitorParams() +{ + freeStrings(); + freeReferences(); + freeDynamicArrays(); +} + +void FieldSamplerPhysXMonitorParams::destroy() +{ + // We cache these fields here to avoid overwrite in destructor + bool doDeallocateSelf = mDoDeallocateSelf; + NvParameterized::Traits* traits = mParameterizedTraits; + int32_t* refCount = mRefCount; + void* buf = mBuffer; + + this->~FieldSamplerPhysXMonitorParams(); + + NvParameters::destroy(this, traits, doDeallocateSelf, refCount, buf); +} + +const NvParameterized::DefinitionImpl* FieldSamplerPhysXMonitorParams::getParameterDefinitionTree(void) +{ + if (!mBuiltFlag) // Double-checked lock + { + NvParameterized::MutexType::ScopedLock lock(mBuiltFlagMutex); + if (!mBuiltFlag) + { + buildTree(); + } + } + + return(&ParamDefTable[0]); +} + +const NvParameterized::DefinitionImpl* FieldSamplerPhysXMonitorParams::getParameterDefinitionTree(void) const +{ + FieldSamplerPhysXMonitorParams* tmpParam = const_cast<FieldSamplerPhysXMonitorParams*>(this); + + if (!mBuiltFlag) // Double-checked lock + { + NvParameterized::MutexType::ScopedLock lock(mBuiltFlagMutex); + if (!mBuiltFlag) + { + tmpParam->buildTree(); + } + } + + return(&ParamDefTable[0]); +} + +NvParameterized::ErrorType FieldSamplerPhysXMonitorParams::getParameterHandle(const char* long_name, Handle& handle) const +{ + ErrorType Ret = NvParameters::getParameterHandle(long_name, handle); + if (Ret != ERROR_NONE) + { + return(Ret); + } + + size_t offset; + void* ptr; + + getVarPtr(handle, ptr, offset); + + if (ptr == NULL) + { + return(ERROR_INDEX_OUT_OF_RANGE); + } + + return(ERROR_NONE); +} + +NvParameterized::ErrorType FieldSamplerPhysXMonitorParams::getParameterHandle(const char* long_name, Handle& handle) +{ + ErrorType Ret = NvParameters::getParameterHandle(long_name, handle); + if (Ret != ERROR_NONE) + { + return(Ret); + } + + size_t offset; + void* ptr; + + getVarPtr(handle, ptr, offset); + + if (ptr == NULL) + { + return(ERROR_INDEX_OUT_OF_RANGE); + } + + return(ERROR_NONE); +} + +void FieldSamplerPhysXMonitorParams::getVarPtr(const Handle& handle, void*& ptr, size_t& offset) const +{ + ptr = getVarPtrHelper(&ParamLookupTable[0], const_cast<FieldSamplerPhysXMonitorParams::ParametersStruct*>(¶meters()), handle, offset); +} + + +/* Dynamic Handle Indices */ + +void FieldSamplerPhysXMonitorParams::freeParameterDefinitionTable(NvParameterized::Traits* traits) +{ + if (!traits) + { + return; + } + + if (!mBuiltFlag) // Double-checked lock + { + return; + } + + NvParameterized::MutexType::ScopedLock lock(mBuiltFlagMutex); + + if (!mBuiltFlag) + { + return; + } + + for (uint32_t i = 0; i < NumParamDefs; ++i) + { + ParamDefTable[i].~DefinitionImpl(); + } + + traits->free(ParamDefTable); + + mBuiltFlag = false; +} + +#define PDEF_PTR(index) (&ParamDefTable[index]) + +void FieldSamplerPhysXMonitorParams::buildTree(void) +{ + + uint32_t allocSize = sizeof(NvParameterized::DefinitionImpl) * NumParamDefs; + ParamDefTable = (NvParameterized::DefinitionImpl*)(mParameterizedTraits->alloc(allocSize)); + memset(ParamDefTable, 0, allocSize); + + for (uint32_t i = 0; i < NumParamDefs; ++i) + { + NV_PARAM_PLACEMENT_NEW(ParamDefTable + i, NvParameterized::DefinitionImpl)(*mParameterizedTraits); + } + + // Initialize DefinitionImpl node: nodeIndex=0, longName="" + { + NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[0]; + ParamDef->init("", TYPE_STRUCT, "STRUCT", true); + + + + + + + } + + // Initialize DefinitionImpl node: nodeIndex=1, longName="maxRBCount" + { + NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[1]; + ParamDef->init("maxRBCount", TYPE_U32, NULL, true); + +#ifdef NV_PARAMETERIZED_HIDE_DESCRIPTIONS + +#else + + static HintImpl HintTable[1]; + static Hint* HintPtrTable[1] = { &HintTable[0], }; + HintTable[0].init("shortDescription", "Maximum number of rigid bodies in scene", true); + ParamDefTable[1].setHints((const NvParameterized::Hint**)HintPtrTable, 1); + +#endif /* NV_PARAMETERIZED_HIDE_DESCRIPTIONS */ + + + + + + } + + // Initialize DefinitionImpl node: nodeIndex=2, longName="maxPSCount" + { + NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[2]; + ParamDef->init("maxPSCount", TYPE_U32, NULL, true); + +#ifdef NV_PARAMETERIZED_HIDE_DESCRIPTIONS + +#else + + static HintImpl HintTable[1]; + static Hint* HintPtrTable[1] = { &HintTable[0], }; + HintTable[0].init("shortDescription", "Maximum number of particle systems in scene", true); + ParamDefTable[2].setHints((const NvParameterized::Hint**)HintPtrTable, 1); + +#endif /* NV_PARAMETERIZED_HIDE_DESCRIPTIONS */ + + + + + + } + + // Initialize DefinitionImpl node: nodeIndex=3, longName="maxParticleCount" + { + NvParameterized::DefinitionImpl* ParamDef = &ParamDefTable[3]; + ParamDef->init("maxParticleCount", TYPE_U32, NULL, true); + +#ifdef NV_PARAMETERIZED_HIDE_DESCRIPTIONS + +#else + + static HintImpl HintTable[1]; + static Hint* HintPtrTable[1] = { &HintTable[0], }; + HintTable[0].init("shortDescription", "Maximum number of particles in scene", true); + ParamDefTable[3].setHints((const NvParameterized::Hint**)HintPtrTable, 1); + +#endif /* NV_PARAMETERIZED_HIDE_DESCRIPTIONS */ + + + + + + } + + // SetChildren for: nodeIndex=0, longName="" + { + static Definition* Children[3]; + Children[0] = PDEF_PTR(1); + Children[1] = PDEF_PTR(2); + Children[2] = PDEF_PTR(3); + + ParamDefTable[0].setChildren(Children, 3); + } + + mBuiltFlag = true; + +} +void FieldSamplerPhysXMonitorParams::initStrings(void) +{ +} + +void FieldSamplerPhysXMonitorParams::initDynamicArrays(void) +{ +} + +void FieldSamplerPhysXMonitorParams::initDefaults(void) +{ + + freeStrings(); + freeReferences(); + freeDynamicArrays(); + maxRBCount = uint32_t(10000); + maxPSCount = uint32_t(128); + maxParticleCount = uint32_t(100000); + + initDynamicArrays(); + initStrings(); + initReferences(); +} + +void FieldSamplerPhysXMonitorParams::initReferences(void) +{ +} + +void FieldSamplerPhysXMonitorParams::freeDynamicArrays(void) +{ +} + +void FieldSamplerPhysXMonitorParams::freeStrings(void) +{ +} + +void FieldSamplerPhysXMonitorParams::freeReferences(void) +{ +} + +} // namespace fieldsampler +} // namespace nvidia |