void PhysXSimulateTask::run()
{
	// record the pretick APEX time
	StatValue dataVal;
	uint64_t qpc = Time::getCurrentCounterValue();
	dataVal.Float = ApexScene::ticksToMilliseconds(mScene->mApexSimulateTickCount, qpc);
	APEX_CHECK_STAT_TIMER("--------- ApexBeforeTickTime (mApexSimulateTickCount)");
	
	APEX_CHECK_STAT_TIMER("--------- Set mApexSimulateTickCount");
	mScene->mApexSimulateTickCount = qpc;

	mScene->setApexStatValue(ApexScene::ApexBeforeTickTime, dataVal);

	// start the PhysX simulation time timer
	APEX_CHECK_STAT_TIMER("--------- Set mPhysXSimulateTickCount");
	mScene->mPhysXSimulateTickCount = Time::getCurrentCounterValue();

#if PX_PHYSICS_VERSION_MAJOR == 3
	if (mScene->mPhysXScene)
	{
		PX_ASSERT(mElapsedTime >= 0.0f);
		SCOPED_PHYSX_LOCK_WRITE(mScene);
		mScene->mPhysXScene->simulate(mElapsedTime, &mCheckResultsTask, mScratchBlock, mScratchBlockSize, false);
	}
#endif

#if PX_PHYSICS_VERSION_MAJOR == 0
	if (mFollowingTask != NULL)
	{
		mFollowingTask->removeReference();
	}
#endif
}
void DuringTickCompleteTask::run()
{
	// mark the end of the "during tick" simulation time
	StatValue dataVal;
	uint64_t qpc = Time::getCurrentCounterValue();
	dataVal.Float = ApexScene::ticksToMilliseconds(mScene->mApexSimulateTickCount, qpc);
	APEX_CHECK_STAT_TIMER("--------- ApexDuringTickTime (mApexSimulateTickCount)");

	APEX_CHECK_STAT_TIMER("--------- Set mApexSimulateTickCount");
	mScene->mApexSimulateTickCount = qpc;
	
	mScene->setApexStatValue(ApexScene::ApexDuringTickTime, dataVal);
}
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 CheckResultsTask::run()
{
#if !APEX_DURING_TICK_TIMING_FIX
	{
		// mark the end of the "during tick" simulation time
		StatValue dataVal;
		{
			uint64_t qpc = Time::getCurrentCounterValue();
			dataVal.Float = ApexScene::ticksToSeconds(mScene->mApexSimulateTickCount, qpc);
			APEX_CHECK_STAT_TIMER("--------- ApexDuringTickTime (mApexSimulateTickCount)");

			APEX_CHECK_STAT_TIMER("--------- Set mApexSimulateTickCount");
			mScene->mApexSimulateTickCount = qpc;
		}
		mScene->setApexStatValue(ApexScene::ApexDuringTickTime, dataVal);
	}
#endif

#if PX_PHYSICS_VERSION_MAJOR == 3
	{
		SCOPED_PHYSX_LOCK_WRITE(mScene);
		if (mScene->mPhysXScene)
		{
			mScene->mPhysXScene->checkResults(true);
		}
	}
#endif

	// get the PhysX simulation time and add it to the ApexStats
	{
		StatValue dataVal;
		{
			uint64_t qpc = Time::getCurrentCounterValue();
			dataVal.Float = ApexScene::ticksToMilliseconds(mScene->mPhysXSimulateTickCount, qpc);
			APEX_CHECK_STAT_TIMER("--------- PhysXSimulationTime (mPhysXSimulateTickCount)");
		}

		mScene->setApexStatValue(ApexScene::PhysXSimulationTime, dataVal);
	}
}