void ApexRenderMeshAsset::releaseActor(NxRenderMeshActor& renderMeshActor) { ApexRenderMeshActor* actor = DYNAMIC_CAST(ApexRenderMeshActor*)(&renderMeshActor); actor->destroy(); // Last one out turns out the lights if (!mActorList.getSize()) { NxUserRenderResourceManager* rrm = NiGetApexSDK()->getUserRenderResourceManager(); for (physx::PxU32 i = 0 ; i < mRuntimeSubmeshData.size() ; i++) { if (mRuntimeSubmeshData[i].staticVertexBuffer != NULL) { rrm->releaseVertexBuffer(*mRuntimeSubmeshData[i].staticVertexBuffer); mRuntimeSubmeshData[i].staticVertexBuffer = NULL; } if (mRuntimeSubmeshData[i].skinningVertexBuffer != NULL) { rrm->releaseVertexBuffer(*mRuntimeSubmeshData[i].skinningVertexBuffer); mRuntimeSubmeshData[i].skinningVertexBuffer = NULL; } if (mRuntimeSubmeshData[i].dynamicVertexBuffer != NULL) { rrm->releaseVertexBuffer(*mRuntimeSubmeshData[i].dynamicVertexBuffer); mRuntimeSubmeshData[i].dynamicVertexBuffer = NULL; } } mRuntimeSubmeshData.clear(); } }
NxParameterized::Interface* ImpactEmitterAsset::getDefaultAssetPreviewDesc() { NX_WRITE_ZONE(); NxParameterized::Traits* traits = NiGetApexSDK()->getParameterizedTraits(); PX_ASSERT(traits); if (!traits) { return NULL; } // create if not yet created if (!mDefaultPreviewParams) { const char* className = EmitterAssetPreviewParameters::staticClassName(); NxParameterized::Interface* param = traits->createNxParameterized(className); mDefaultPreviewParams = static_cast<EmitterAssetPreviewParameters*>(param); PX_ASSERT(param); if (!param) { return NULL; } } return mDefaultPreviewParams; }
ClothFactory ClothingScene::getClothFactory(bool& useCuda) { #ifdef PX_WINDOWS if (useCuda) { if (mGpuFactory.factory == NULL) { PxCudaContextManager* contextManager = NULL; PxGpuDispatcher* gpuDispatcher = mApexScene->getTaskManager()->getGpuDispatcher(); if (gpuDispatcher != NULL) { contextManager = gpuDispatcher->getCudaContextManager(); } if (contextManager != NULL) { mGpuFactory = mModule->createClothFactory(contextManager); if (mGpuFactory.factory != NULL) { NiApexSDK* apexSdk = NiGetApexSDK(); mPhysXGpuIndicator = apexSdk->registerPhysXIndicatorGpuClient(); } } } //APEX_DEBUG_INFO("Gpu Factory %p", mGpuFactory); if (mGpuFactory.factory != NULL) { return mGpuFactory; } else { APEX_DEBUG_INFO("Gpu Factory could not be created"); useCuda = false; } } if (!useCuda) #else PX_UNUSED(useCuda); #endif { if (mCpuFactory.factory == NULL) { mCpuFactory = mModule->createClothFactory(NULL); } //APEX_DEBUG_INFO("Cpu Factory %p", mCpuFactory.factory); return mCpuFactory; } #ifdef PX_WINDOWS PX_ALWAYS_ASSERT_MESSAGE("this code path is unreachable, at least it used to be."); return ClothFactory(NULL, NULL); #endif }
// Load all of our named resources (that consists of materials) if they are // not registered in the NRP physx::PxU32 ApexRenderMeshAsset::forceLoadAssets() { physx::PxU32 assetLoadedCount = 0; NiResourceProvider* nrp = NiGetApexSDK()->getInternalResourceProvider(); NxResID materialNS = NiGetApexSDK()->getMaterialNameSpace(); for (physx::PxU32 i = 0; i < mMaterialIDs.size(); i++) { if (!nrp->checkResource(materialNS, mParams->materialNames.buf[i])) { /* we know for SURE that createResource() has already been called, so just getResource() */ nrp->getResource(mMaterialIDs[i]); assetLoadedCount++; } } return assetLoadedCount; }
ApexRenderMeshAsset::~ApexRenderMeshAsset() { // this should have been cleared in releaseActor() PX_ASSERT(mRuntimeSubmeshData.empty()); // Release named resources NiResourceProvider* resourceProvider = NiGetApexSDK()->getInternalResourceProvider(); for (physx::PxU32 i = 0 ; i < mMaterialIDs.size() ; i++) { resourceProvider->releaseResource(mMaterialIDs[i]); } setSubmeshCount(0); }
NxParameterized::Interface* ImpactEmitterAsset::getDefaultActorDesc() { NX_WRITE_ZONE(); NxParameterized::ErrorType error = NxParameterized::ERROR_NONE; PX_UNUSED(error); NxParameterized::Traits* traits = NiGetApexSDK()->getParameterizedTraits(); PX_ASSERT(traits); if (!traits) { return NULL; } // create if not yet created if (!mDefaultActorParams) { const char* className = ImpactEmitterActorParameters::staticClassName(); NxParameterized::Interface* param = traits->createNxParameterized(className); mDefaultActorParams = static_cast<ImpactEmitterActorParameters*>(param); PX_ASSERT(param); if (!param) { return NULL; } } NxParameterized::Handle hDest(*mDefaultActorParams); #if NX_SDK_VERSION_MAJOR == 2 NxParameterized::Interface* explParams = 0; error = mDefaultActorParams->getParameterHandle("explosionEnv", hDest); PX_ASSERT(NxParameterized::ERROR_NONE == error); mDefaultActorParams->initParamRef(hDest, hDest.parameterDefinition()->refVariantVal(0), true); mDefaultActorParams->getParamRef(hDest, explParams); PX_ASSERT(explParams); if (explParams) { explParams->initDefaults(); } #endif return mDefaultActorParams; }
ImpactEmitterAsset::ImpactEmitterAsset(ModuleEmitter* m, NxResourceList& list, const char* name) : mModule(m), mName(name), mIofxAssetTracker(m->mSdk, NX_IOFX_AUTHORING_TYPE_NAME), mIosAssetTracker(m->mSdk), #if NX_SDK_VERSION_MAJOR == 2 mExplosionAssetTracker(m->mSdk, NX_EXPLOSION_AUTHORING_TYPE_NAME), #endif mDefaultActorParams(NULL), mDefaultPreviewParams(NULL) { NxParameterized::Traits* traits = NiGetApexSDK()->getParameterizedTraits(); mParams = (ImpactEmitterAssetParameters*)traits->createNxParameterized(ImpactEmitterAssetParameters::staticClassName()); PX_ASSERT(mParams); mParams->setSerializationCallback(this); list.add(*this); }
void ApexRenderMeshAsset::createLocalData() { mMaterialIDs.resize((physx::PxU32)mParams->materialNames.arraySizes[0]); NiResourceProvider* resourceProvider = NiGetApexSDK()->getInternalResourceProvider(); NxResID materialNS = NiGetApexSDK()->getMaterialNameSpace(); NxResID customVBNS = NiGetApexSDK()->getCustomVBNameSpace(); // Resolve material names using the NRP... for (physx::PxU32 i = 0; i < (physx::PxU32)mParams->materialNames.arraySizes[0]; ++i) { if (resourceProvider) { mMaterialIDs[i] = resourceProvider->createResource(materialNS, mParams->materialNames.buf[i]); } else { mMaterialIDs[i] = INVALID_RESOURCE_ID; } } // Resolve custom vertex buffer semantics using the NRP... mRuntimeCustomSubmeshData.resize(getSubmeshCount()); //JPB memset(mRuntimeCustomSubmeshData.begin(), 0, sizeof(CustomSubmeshData) * mRuntimeCustomSubmeshData.size()); for (physx::PxU32 i = 0; i < getSubmeshCount(); ++i) { const NxVertexFormat& fmt = getSubmesh(i).getVertexBuffer().getFormat(); mRuntimeCustomSubmeshData[i].customBufferFormats.resize(fmt.getCustomBufferCount()); mRuntimeCustomSubmeshData[i].customBufferVoidPtrs.resize(fmt.getCustomBufferCount()); physx::PxU32 customBufferIndex = 0; for (physx::PxU32 j = 0; j < fmt.getBufferCount(); ++j) { if (fmt.getBufferSemantic(j) != NxRenderVertexSemantic::CUSTOM) { continue; } NxRenderDataFormat::Enum f = fmt.getBufferFormat(j); const char* name = fmt.getBufferName(j); mRuntimeCustomSubmeshData[i].customBufferFormats[customBufferIndex] = f; mRuntimeCustomSubmeshData[i].customBufferVoidPtrs[customBufferIndex] = 0; if (resourceProvider) { NxResID id = resourceProvider->createResource(customVBNS, name, true); mRuntimeCustomSubmeshData[i].customBufferVoidPtrs[customBufferIndex] = NiGetApexSDK()->getInternalResourceProvider()->getResource(id); } ++customBufferIndex; } } // find the bone count // LRR - required for new deserialize path // PH - mBoneCount is now serialized if (mParams->boneCount == 0) { for (physx::PxU32 i = 0; i < getSubmeshCount(); i++) { NxRenderDataFormat::Enum format; const NxVertexBuffer& vb = mSubmeshes[i]->getVertexBuffer(); const NxVertexFormat& vf = vb.getFormat(); physx::PxU32 bufferIndex = (physx::PxU32)vf.getBufferIndexFromID(vf.getSemanticID(physx::NxRenderVertexSemantic::BONE_INDEX)); physx::PxU16* boneIndices = (physx::PxU16*)vb.getBufferAndFormat(format, bufferIndex); if (boneIndices == NULL) { continue; } if (!vertexSemanticFormatValid(NxRenderVertexSemantic::BONE_INDEX, format)) { continue; } const PxU32 bonesPerVert = vertexSemanticFormatElementCount(NxRenderVertexSemantic::BONE_INDEX, format); PX_ASSERT(format == NxRenderDataFormat::USHORT1 || format == NxRenderDataFormat::USHORT2 || format == NxRenderDataFormat::USHORT3 || format == NxRenderDataFormat::USHORT4); const PxU32 numVertices = vb.getVertexCount(); for (PxU32 v = 0; v < numVertices; v++) { for (PxU32 b = 0; b < bonesPerVert; b++) { mParams->boneCount = physx::PxMax(mParams->boneCount, (physx::PxU32)(boneIndices[v * bonesPerVert + b] + 1)); } } } } // PH - have one bone at all times, if it's just one, it is used as current pose (see ApexRenderMeshActor::dispatchRenderResources) if (mParams->boneCount == 0) { mParams->boneCount = 1; } }
void ClothingScene::destroy() { for (PxU32 i = 0; i < mActorArray.size(); i++) { ClothingActor* clothingActor = static_cast<ClothingActor*>(mActorArray[i]); clothingActor->waitForFetchResults(); } removeAllActors(); mClothingAssetsMutex.lock(); for (physx::PxU32 i = 0 ; i < mClothingAssets.size(); i++) { if (mPhysXScene != NULL) { mClothingAssets[i]->hintSceneDeletion(mPhysXScene); } // for PhysX3: making sure that fabrics (in assets) are released before the factories (in mSimulationTask) mClothingAssets[i]->releaseCookedInstances(); } mClothingAssets.clear(); mClothingAssetsMutex.unlock(); // clear render list for(HashMap<NiApexRenderMeshAsset*, Array<ClothingRenderProxy*> >::Iterator iter = mRenderProxies.getIterator(); !iter.done(); ++iter) { Array<ClothingRenderProxy*>& renderProxies = iter->second; for (PxI32 i = (physx::PxI32)renderProxies.size()-1; i >= 0 ; --i) { PxU32 timeInPool = renderProxies[(physx::PxU32)i]->getTimeInPool(); if (timeInPool > 0) { PX_DELETE(renderProxies[(physx::PxU32)i]); renderProxies.replaceWithLast((physx::PxU32)i); } else { // actually the scene is released, but we just want to make sure // that the render proxy deletes itself when it's returned next time renderProxies[(physx::PxU32)i]->notifyAssetRelease(); } } renderProxies.clear(); } //mRenderProxies.clear(); while (mCurrentCookingTask != NULL) { submitCookingTask(NULL); physx::Thread::sleep(0); // wait for remaining cooking tasks to finish } if (mSimulationTask != NULL) { setModulePhysXScene(NULL); // does some cleanup necessary here. Only needed when module gets deleted without the apex scene being deleted before! PX_DELETE(mSimulationTask); mSimulationTask = NULL; } if (mWaitForSolverTask != NULL) { PX_DELETE(mWaitForSolverTask); mWaitForSolverTask = NULL; } { if (mCpuFactory.factory != NULL) { mModule->releaseClothFactory(NULL); mCpuFactory.clear(); } #ifdef PX_WINDOWS PX_ASSERT(mGpuFactory.factory == NULL); NiApexSDK* apexSdk = NiGetApexSDK(); apexSdk->unregisterPhysXIndicatorGpuClient(mPhysXGpuIndicator); mPhysXGpuIndicator = NULL; #endif } mApexScene->moduleReleased(*this); delete this; }