//----------------------------------------------------------------------------
//  pfxUpdateRigidStates
//
/// Perform update rigid states in parallel using a task manager.
///
/// @param param        Information about rigid bodies
/// @param taskManager  Pointer to the thread task manager to use
///
/// @return SCE_PFX_OK if successful, otherwise, returns an error code.
//----------------------------------------------------------------------------
PfxInt32 pfxUpdateRigidStates(PfxUpdateRigidStatesParam &param, PfxTaskManager *taskManager)
{
	PfxInt32 ret = pfxCheckParamOfUpdateRigidStates(param);
	if(ret != SCE_PFX_OK) return ret;

	SCE_PFX_PUSH_MARKER("pfxUpdateRigidStates");

	PfxUInt32 maxBatchSize = param.numRigidBodies / (PfxUInt32)(taskManager->getNumTasks());
	PfxUInt32 iEnd = maxBatchSize, iStart = 0;
	int task = 0;
	taskManager->setTaskEntry((void*)pfxUpdateRigidStatesTaskEntry);

	for (task = 0; task < taskManager->getNumTasks() - 1; task++, iStart += maxBatchSize, iEnd += maxBatchSize)
	{
		taskManager->startTask(task, static_cast<void*>(&param), iStart, iEnd, 0, 0);
	}

	// send final task
	iEnd = param.numRigidBodies;
	taskManager->startTask(taskManager->getNumTasks() - 1, static_cast<void*>(&param), iStart, iEnd, 0, 0);

	// wait for tasks to complete
	PfxUInt32 data1, data2, data3, data4;
	for (PfxUInt32 i = 0; i < taskManager->getNumTasks(); i++)
		taskManager->waitTask(task, data1, data2, data3, data4);

	SCE_PFX_POP_MARKER();
	
	return SCE_PFX_OK;
}
PfxInt32 pfxUpdateRigidStates(PfxUpdateRigidStatesParam &param)
{
	PfxInt32 ret = pfxCheckParamOfUpdateRigidStates(param);
	if(ret != SCE_PFX_OK) return ret;

	SCE_PFX_PUSH_MARKER("pfxUpdateRigidStates");

	for(PfxUInt32 i=0;i<param.numRigidBodies;i++) {
		pfxIntegrate(param.states[i],param.bodies[i],param.timeStep);
	}

	SCE_PFX_POP_MARKER();

	return SCE_PFX_OK;
}