void FPhysSubstepTask::SubstepSimulationStart()
{
    check(SubTime > 0.f);
    check(DeltaSeconds > 0.f);

    check(!CompletionEvent.GetReference());	//should be done
    CompletionEvent = FGraphEvent::CreateGraphEvent();
    PhysXCompletionTask* SubstepTask = new PhysXCompletionTask(CompletionEvent, ApexScene->getTaskManager());
    FDelegateGraphTask::CreateAndDispatchWhenReady(FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysSubstepTask::SubstepSimulationEnd), TEXT("ProcessPhysSubstepSimulation"), CompletionEvent);

    ++CurrentSubStep;
    if (CurrentSubStep < NumSubsteps)
    {

        Alpha += StepScale;
        TotalSubTime += SubTime;
        SubstepInterpolation(Alpha);
        ApexScene->simulate(SubTime, false, SubstepTask);
        SubstepTask->removeReference();
    }
    else
    {
        SubstepInterpolation(1.f);
        ApexScene->simulate(DeltaSeconds - TotalSubTime, true, SubstepTask);
        SubstepTask->removeReference();
    }
}
void FPhysSubstepTask::SubstepSimulationStart()
{
	SCOPE_CYCLE_COUNTER(STAT_TotalPhysicsTime);
	SCOPE_CYCLE_COUNTER(STAT_SubstepSimulationStart);
#if WITH_PHYSX
	check(SubTime > 0.f);
	check(DeltaSeconds > 0.f);
	
	check(!CompletionEvent.GetReference());	//should be done
	CompletionEvent = FGraphEvent::CreateGraphEvent();
	PhysXCompletionTask* SubstepTask = new PhysXCompletionTask(CompletionEvent,
		 PST_MAX //we don't care about sub-step time. The full time is recorded by FullSimulationTask
		,PAScene->getTaskManager());
	ENamedThreads::Type NamedThread = PhysSingleThreadedMode() ? ENamedThreads::GameThread : ENamedThreads::AnyThread;

	DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysSubstepSimulation"),
		STAT_FDelegateGraphTask_ProcessPhysSubstepSimulation,
		STATGROUP_TaskGraphTasks);

	FDelegateGraphTask::CreateAndDispatchWhenReady(
		FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysSubstepTask::SubstepSimulationEnd),
		GET_STATID(STAT_FDelegateGraphTask_ProcessPhysSubstepSimulation), CompletionEvent, NamedThread, NamedThread);

	++CurrentSubStep;	

	bool bLastSubstep = CurrentSubStep >= NumSubsteps;

	if (!bLastSubstep)
	{

		Alpha += StepScale;
		TotalSubTime += SubTime;
	}

	float DeltaTime = bLastSubstep ? (DeltaSeconds - TotalSubTime) : SubTime;
	float Interpolation = bLastSubstep ? 1.f : Alpha;

#if WITH_VEHICLE
	if (VehicleManager)
	{
		VehicleManager->Update(DeltaTime);
	}
#endif

	SubstepInterpolation(Interpolation, DeltaTime);

#if WITH_APEX
	PAScene->simulate(DeltaTime, bLastSubstep, SubstepTask);
#else
	PAScene->lockWrite();
	PAScene->simulate(DeltaTime, SubstepTask);
	PAScene->unlockWrite();
#endif
	SubstepTask->removeReference();
#endif
}