void ApexResourceProvider::destroy()
{
	if (mUserCallback)
	{
		for (uint32_t i = 0 ; i < mResources.size() ; i++)
		{
			ApexResourceProvider::resource& res = mResources[i];
			if (res.refCount != 0 && res.valueIsSet && res.ptr != NULL)
			{
				ResID resIndex = mNSNames.getOrCreateID(res.nameSpace, "NameSpace");
				PX_ASSERT(mResources[resIndex].ptr);
				uint32_t nsIndex = getNSIndex((ResID)(size_t)mResources[resIndex].ptr);
				if (nsIndex < mNameSpaces.size() &&
					mNameSpaces[nsIndex]->releaseAtExit())
				{
					if (res.usedGetResource) // this check added for PhysXLab DE4349
				{
					mUserCallback->releaseResource(res.nameSpace, res.name, res.ptr);
				}
					else
					{
						APEX_DEBUG_WARNING("Unreleased resource found during teardown: Namespace <%s>, Name <%s>", res.nameSpace, res.name);
					}
				}
			}
		}
	}
	mResources.clear();
	for (uint32_t i = 0 ; i < mNameSpaces.size() ; i++)
	{
		PX_DELETE(mNameSpaces[i]);
	}
	mNameSpaces.clear();
	delete this;
}
void ImpactEmitterAsset::buildEventNameIndexMap()
{
	// destroy old mappings
	for (physx::PxU32 j = 0; j < mEventNameIndexMaps.size(); j++)
	{
		if (mEventNameIndexMaps[j])
		{
			delete mEventNameIndexMaps[j];
		}
	}

	// loop through all event sets, build a mapping for each new name found
	// and store all indices for that event set
	NxParamArray<NxParameterized::Interface*> assetEventSets(mParams,
	        "eventSetList",
	        (NxParamDynamicArrayStruct*) & (mParams->eventSetList));

	for (physx::PxU32 i = 0; i < assetEventSets.size(); i++)
	{
		NxParameterized::Handle hEventSetName(*assetEventSets[i]);
		const char* paramEventSetName = 0;

		NxParameterized::getParamString(*(assetEventSets[i]), "eventSetName", paramEventSetName);
		if (!paramEventSetName)
		{
			APEX_DEBUG_WARNING("Invalid eventSetName from Impact Emitter event sets");
			continue;
		}

		/* first see if the name is already here */
		bool foundEventSet = false;
		for (physx::PxU32 j = 0; j < mEventNameIndexMaps.size(); j++)
		{
			if (mEventNameIndexMaps[j]->eventSetName == paramEventSetName)
			{
				// add index to list
				mEventNameIndexMaps[j]->eventIndices.pushBack((physx::PxU16)i);
				foundEventSet = true;
			}
		}

		if (!foundEventSet)
		{
			/* now add it to the list */
			EventNameIndexMap* newMap = PX_NEW(EventNameIndexMap)();
			newMap->eventSetName = paramEventSetName;
			newMap->eventIndices.pushBack((physx::PxU16)i);
			mEventNameIndexMaps.pushBack(newMap);
		}
	}
}
void ClothingScene::setSceneRunning(bool on)
{
#ifndef _DEBUG
	PxI32 newValue;
	if (on)
	{
		APEX_CHECK_STAT_TIMER("--------- Start ClothingSimulationTime");
		mClothingSimulationTime.getElapsedSeconds();

		newValue = shdfnd::atomicIncrement(&mSceneRunning);
	}
	else
	{
		ApexStatValue dataVal;
		dataVal.Float = (PxF32)(1000.0f * mClothingSimulationTime.getElapsedSeconds());
		APEX_CHECK_STAT_TIMER("--------- Stop ClothingSimulationTime");
		mApexScene->setApexStatValue(NiApexScene::ClothingSimulationTime, dataVal);

		// Warn if simulation time was bigger than timestep for 10 or more consecutive frames
		PxF32 simulatedTime = 1000.0f * mApexScene->getElapsedTime();
		if (simulatedTime < dataVal.Float)
		{
			mFramesCount++;
			mSimulatedTime	+= simulatedTime;
			mTimestep		+= dataVal.Float;
		}

		if (mFramesCount >= 10)
		{
			float averageSimulatedTime = mSimulatedTime / (PxF32)mFramesCount;
			float averageTimestep = mTimestep / (PxF32)mFramesCount;
			APEX_DEBUG_WARNING("Cloth complexity in scene is too high to be simulated in real time for 10 consecutive frames. (Average Delta Time: %f ms, Average Simulation Time: %f ms)", 
								averageSimulatedTime, averageTimestep);
			mFramesCount	= 0;
			mSimulatedTime	= 0.f;
			mTimestep		= 0.f;
		}

		newValue = shdfnd::atomicDecrement(&mSceneRunning);
	}

	if (newValue != (on ? 1 : 0))
	{
		APEX_INTERNAL_ERROR("scene running state was not tracked properly!: on = %s, prevValue = %d", on ? "true" : "false", newValue);
	}
#else
	PX_UNUSED(on);
#endif
}
void ImpactEmitterAsset::initializeAssetNameTable()
{
	/* initialize the exlosion, iofx, and ios asset names to resID tables */
	NxParameterized::Handle eventSetHandle(*mParams);
	int numSets;

	mParams->getParameterHandle("eventSetList", eventSetHandle);
	PX_ASSERT(eventSetHandle.isValid());

	mParams->getArraySize(eventSetHandle, numSets);
	for (int i = 0; i < numSets; i++)
	{
		NxParameterized::Handle ih(*mParams);
		NxParameterized::Interface* eventPtr = 0;

		eventSetHandle.getChildHandle(i, ih);
		PX_ASSERT(ih.isValid());

		mParams->getParamRef(ih, eventPtr);
		PX_ASSERT(eventPtr);

		ApexSimpleString tmpClassName(eventPtr->className());


		if (tmpClassName == "ImpactExplosionEvent")
		{
#if NX_SDK_VERSION_MAJOR == 2
			ImpactExplosionEvent* paramPtr = (ImpactExplosionEvent*)eventPtr;
			mExplosionAssetTracker.addAssetName(paramPtr->parameters().explosionAssetName->name(), false);
#elif NX_SDK_VERSION_MAJOR == 3
			APEX_DEBUG_WARNING("Invalid asset. ImpactExplosionEvent is not supported under PhysX 3.");
			PX_ALWAYS_ASSERT();
#endif
		}
		else if (tmpClassName == "ImpactObjectEvent")
		{
			ImpactObjectEvent* paramPtr = (ImpactObjectEvent*)eventPtr;

			mIofxAssetTracker.addAssetName(paramPtr->parameters().iofxAssetName->name(), false);
			mIosAssetTracker.addAssetName(paramPtr->parameters().iosAssetName->className(),
			                              paramPtr->parameters().iosAssetName->name());
		}
	}
}