void CShadowController::AttachObject( void )
{
	IVP_Real_Object *pivp = m_pObject->GetObject();
	IVP_Core *pCore = pivp->get_core();
	m_saveRot = pCore->rot_speed_damp_factor;
	m_savedRI = *pCore->get_rot_inertia();
	m_savedMass = pCore->get_mass();
	m_savedMaterialIndex = m_pObject->GetMaterialIndexInternal();
	
	m_pObject->SetMaterialIndex( MATERIAL_INDEX_SHADOW );

	pCore->rot_speed_damp_factor = IVP_U_Float_Point( 100, 100, 100 );

	if ( !m_allowPhysicsRotation )
	{
		IVP_U_Float_Point ri( 1e15f, 1e15f, 1e15f );
		pCore->set_rotation_inertia( &ri );
	}
	if ( !m_allowPhysicsMovement )
	{
		m_pObject->SetMass( 1e6f );
		//pCore->inv_rot_inertia.hesse_val = 0.0f;
		m_pObject->EnableGravity( false );
	}

	pCore->calc_calc();
	pivp->get_environment()->get_controller_manager()->add_controller_to_core( this, pCore );
	m_shadow.lastPosition.set_to_zero();
}
//-----------------------------------------------------------------------------
// Purpose: Main raycast airboat simulation.
//-----------------------------------------------------------------------------
void IVP_Controller_Raycast_Airboat::do_simulation_controller( IVP_Event_Sim *pEventSim, IVP_U_Vector<IVP_Core> * )
{
    IVP_Raycast_Airboat_Pontoon_Temp	pontoonsTemp[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];
    IVP_Ray_Solver_Template				raySolverTemplates[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];
	IVP_Raycast_Airboat_Impact			impacts[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];

	IVP_Core *pAirboatCore = m_pAirboatBody->get_core();
    const IVP_U_Matrix *matWorldFromCore = pAirboatCore->get_m_world_f_core_PSI();
    
	// Raycasts.
	PreRaycasts( raySolverTemplates, matWorldFromCore, pontoonsTemp );
	do_raycasts_gameside( n_wheels, raySolverTemplates, impacts );
	if ( !PostRaycasts( raySolverTemplates, matWorldFromCore, pontoonsTemp, impacts, pAirboatCore ) )
		return;

    // Pontoons.
	DoSimulationPontoons( pontoonsTemp, impacts, pEventSim, pAirboatCore );

	// Drag (Water)
	DoSimulationDrag( pontoonsTemp, pEventSim, pAirboatCore );

	// Turbine (fan).
	DoSimulationTurbine( pontoonsTemp, pEventSim, pAirboatCore );

	// Steering.
	DoSimulationSteering( pontoonsTemp, pAirboatCore, pEventSim );	
}
void CPhysicsObject::CalculateVelocityOffset( const Vector &forceVector, const Vector &worldPosition, Vector &centerVelocity, AngularImpulse &centerAngularVelocity )
{
	IVP_U_Point pos;
	IVP_U_Float_Point force;

	ConvertForceImpulseToIVP( forceVector, force );
	ConvertPositionToIVP( worldPosition, pos );

	IVP_Core *core = m_pObject->get_core();

    const IVP_U_Matrix *m_world_f_core = core->get_m_world_f_core_PSI();

    IVP_U_Float_Point point_d_ws;
	point_d_ws.subtract(&pos, m_world_f_core->get_position());

    IVP_U_Float_Point cross_point_dir;

    cross_point_dir.calc_cross_product( &point_d_ws, &force);
    m_world_f_core->inline_vimult3( &cross_point_dir, &cross_point_dir);

    cross_point_dir.set_pairwise_mult( &cross_point_dir, core->get_inv_rot_inertia());
	ConvertAngularImpulseToHL( cross_point_dir, centerAngularVelocity );
    force.set_multiple( &force, core->get_inv_mass() );
	ConvertForceImpulseToHL( force, centerVelocity );
}
//-----------------------------------------------------------------------------
// Purpose: Main raycast airboat simulation.
//-----------------------------------------------------------------------------
void IVP_Controller_Raycast_Airboat::do_simulation_controller( IVP_Event_Sim *pEventSim, IVP_U_Vector<IVP_Core> * )
{
    IVP_Raycast_Airboat_Pontoon_Temp	pontoonsTemp[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];
    IVP_Ray_Solver_Template				raySolverTemplates[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];
	IVP_Raycast_Airboat_Impact			impacts[IVP_RAYCAST_AIRBOAT_MAX_WHEELS];

	IVP_Core *pAirboatCore = m_pAirboatBody->get_core();
    const IVP_U_Matrix *matWorldFromCore = pAirboatCore->get_m_world_f_core_PSI();
	matWorldFromCore->vimult3(&(pAirboatCore->speed), &m_LocalVelocity);
    
	// Raycasts.
	PreRaycasts( raySolverTemplates, matWorldFromCore, pontoonsTemp );
	do_raycasts_gameside( n_wheels, raySolverTemplates, impacts );
	if ( !PostRaycasts( raySolverTemplates, matWorldFromCore, pontoonsTemp, impacts ) )
		return;

	// Airborne state;
	UpdateAirborneState(impacts, pEventSim);

    // Pontoons.
	DoSimulationPontoons(pontoonsTemp, impacts, pEventSim);

	// Drag (Water)
	DoSimulationDrag(pontoonsTemp, impacts, pEventSim);

	// Turbine (fan).
	DoSimulationTurbine(pEventSim);

	// Steering.
	DoSimulationSteering(pEventSim);

	// Keep upright.
	DoSimulationKeepUprightPitch(impacts, pEventSim);
	DoSimulationKeepUprightRoll(impacts, pEventSim);
}
	// wakes up all attached objects
	virtual void WakeObjects( void )
	{
		for ( int i = 0; i < m_coreList.Count(); i++ )
		{
			IVP_Core *pCore = m_coreList[i];
			pCore->ensure_core_to_be_in_simulation();
		}
	}
void CPlayerController::AttachObject( void )
{
	IVP_Real_Object *pivp = m_pObject->GetObject();
	IVP_Core *pCore = pivp->get_core();
	m_saveRot = pCore->rot_speed_damp_factor;
	pCore->rot_speed_damp_factor = IVP_U_Float_Point( 100, 100, 100 );
	pCore->calc_calc();
	pivp->get_environment()->get_controller_manager()->add_controller_to_core( this, pCore );
}
void CShadowController::DetachObject( void )
{
	IVP_Real_Object *pivp = m_pObject->GetObject();
	IVP_Core *pCore = pivp->get_core();
	pCore->rot_speed_damp_factor = m_saveRot;
	pCore->set_mass( m_savedMass );
	pCore->set_rotation_inertia( &m_savedRI ); // this calls calc_calc()
	m_pObject = NULL;
	pivp->get_environment()->get_controller_manager()->remove_controller_from_core( this, pCore );
}
void CPlayerController::do_simulation_controller( IVP_Event_Sim *es,IVP_U_Vector<IVP_Core> *)
{
	if ( !m_enable )
		return;

	IVP_Real_Object *pivp = m_pObject->GetObject();
	IVP_Environment *pIVPEnv = pivp->get_environment();
	CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pIVPEnv->client_data;

	float psiScale = pVEnv->GetInvPSIScale();
	if ( !psiScale )
		return;

	IVP_Core *pCore = pivp->get_core();
	// current situation
	const IVP_U_Matrix *m_world_f_core = pCore->get_m_world_f_core_PSI();
	const IVP_U_Point *cur_pos_ws = m_world_f_core->get_position();

	// ---------------------------------------------------------
	// Translation
	// ---------------------------------------------------------

	IVP_U_Float_Point delta_position;  delta_position.subtract( &m_targetPosition, cur_pos_ws);


	if (!pivp->flags.shift_core_f_object_is_zero)
	{
		IVP_U_Float_Point shift_cs_os_ws;
		m_world_f_core->vmult3( pivp->get_shift_core_f_object(), &shift_cs_os_ws);
		delta_position.subtract( &shift_cs_os_ws );
	}


	IVP_DOUBLE qdist = delta_position.quad_length();

	// UNDONE: This is totally bogus!  Measure error using last known estimate
	// not current position!
	if ( qdist > m_maxDeltaPosition * m_maxDeltaPosition )
	{
		if ( TryTeleportObject() )
			return;
	}

	// float to allow stepping
	if ( m_onground )
	{
		const IVP_U_Point *pgrav = es->environment->get_gravity();
		IVP_U_Float_Point gravSpeed;
		gravSpeed.set_multiple( pgrav, es->delta_time );
		pCore->speed.subtract( &gravSpeed );
	}

	ComputeController( pCore->speed, delta_position, m_maxSpeed, psiScale / es->delta_time, m_dampFactor );
}
// convert square velocity magnitude from IVP to HL
float CPhysicsObject::GetEnergy()
{
	IVP_Core *pCore = m_pObject->get_core();
	IVP_FLOAT energy = 0.0f;
	IVP_U_Float_Point tmp;

	energy = 0.5f * pCore->get_mass() * pCore->speed.dot_product(&pCore->speed); // 1/2mvv
	tmp.set_pairwise_mult(&pCore->rot_speed, pCore->get_rot_inertia()); // wI
	energy += 0.5f * tmp.dot_product(&pCore->rot_speed); // 1/2mvv + 1/2wIw
	
	return ConvertEnergyToHL( energy );
}
void CPlayerController::DetachObject( void )
{
	if ( !m_pObject )
		return;

	IVP_Real_Object *pivp = m_pObject->GetObject();
	IVP_Core *pCore = pivp->get_core();
	pCore->rot_speed_damp_factor = m_saveRot;
	pCore->calc_calc();
	m_pObject = NULL;
	pivp->get_environment()->get_controller_manager()->remove_controller_from_core( this, pCore );
}
void CPhysicsObject::ApplyTorqueCenter( const AngularImpulse &torqueImpulse )
{
	//Assert(IsMoveable());
	if ( !IsMoveable() )
		return;
	IVP_U_Float_Point ivpTorque;
	ConvertAngularImpulseToIVP( torqueImpulse, ivpTorque );
	IVP_Core *core = m_pObject->get_core();
	core->async_rot_push_core_multiple_ws( &ivpTorque, 1.0 );
	core->rot_speed_change.k[0] = clamp( core->rot_speed_change.k[0], -MAX_ROT_SPEED, MAX_ROT_SPEED );
	core->rot_speed_change.k[1] = clamp( core->rot_speed_change.k[1], -MAX_ROT_SPEED, MAX_ROT_SPEED );
	core->rot_speed_change.k[2] = clamp( core->rot_speed_change.k[2], -MAX_ROT_SPEED, MAX_ROT_SPEED );
	Wake();
}
// Apply force impulse (momentum) to the object
void CPhysicsObject::ApplyForceCenter( const Vector &forceVector )
{
//	Assert(IsMoveable());
	if ( !IsMoveable() )
		return;

	IVP_U_Float_Point tmp;

	ConvertForceImpulseToIVP( forceVector, tmp );
	IVP_Core *core = m_pObject->get_core();
	tmp.mult( core->get_inv_mass() );
	tmp.k[0] = clamp( tmp.k[0], -MAX_SPEED, MAX_SPEED );
	tmp.k[1] = clamp( tmp.k[1], -MAX_SPEED, MAX_SPEED );
	tmp.k[2] = clamp( tmp.k[2], -MAX_SPEED, MAX_SPEED );
	m_pObject->async_add_speed_object_ws( &tmp );
}
Esempio n. 13
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void IVP_Controller_Raycast_Airboat::DoSimulationTurbine(IVP_Event_Sim *pEventSim)
{
	IVP_Core *pAirboatCore = m_pAirboatBody->get_core();

	IVP_FLOAT thrust = m_flThrust;
	if (m_bAirborneIdle || (m_bAirborne && (thrust < 0.0f)))
		thrust *= 0.5f;

	IVP_U_Float_Point vecImpulse;
	pAirboatCore->get_m_world_f_core_PSI()->get_col(IVP_COORDINATE_INDEX(index_z), &vecImpulse);
	IVP_FLOAT flForwardY = vecImpulse.k[1];

	if ((flForwardY < -0.5f) && (thrust > 0.0f))
		thrust *= 1.0f + flForwardY;
	else if ((flForwardY > 0.5f) && (thrust < 0.0f))
		thrust *= 1.0f - flForwardY;

	
	vecImpulse.mult(pAirboatCore->get_mass() * thrust * pEventSim->delta_time);
	pAirboatCore->center_push_core_multiple_ws(&vecImpulse);
}
Esempio n. 14
0
//-----------------------------------------------------------------------------
// Purpose: Handle pontoons on water.
//-----------------------------------------------------------------------------
void IVP_Controller_Raycast_Airboat::DoSimulationPontoonsWater( IVP_Raycast_Airboat_Pontoon_Temp *pTempPontoon,
													            IVP_Raycast_Airboat_Impact *pImpact,
																IVP_Event_Sim *pEventSim )
{
	IVP_FLOAT flForce = pImpact->flWaterDepth;
	if (flForce > 0.41f)
	{
		flForce = 2.8f * 0.41f * 0.0254f;
	}
	else
	{
		if (flForce < 0.0f)
			flForce = 0.0f;
		else
			flForce *= 2.8f * 0.0254f;
	}
	IVP_Core *pAirboatCore = m_pAirboatBody->get_core();
	IVP_U_Float_Point vecImpulseWS(0.0f,
		flForce * (-0.4f * AIRBOAT_WATER_DENSITY) * pAirboatCore->get_mass() * pEventSim->delta_time, 0.0f);
	pAirboatCore->push_core_ws(&(pTempPontoon->ground_hit_ws), &vecImpulseWS);
}
Esempio n. 15
0
void IVP_Controller_Raycast_Airboat::DoSimulationKeepUprightRoll(IVP_Raycast_Airboat_Impact *pImpacts,
                                                                 IVP_Event_Sim *pEventSim)
{
	IVP_Core *pAirboatCore = m_pAirboatBody->get_core();

	IVP_U_Float_Point dir, temp, cross;
	temp.set(0.0f, -1.0f, 0.0f);
	pAirboatCore->get_m_world_f_core_PSI()->vimult3(&temp, &dir);
	dir.k[1] = -0.9848077f; // -cos(10deg)
	dir.normize();
	temp.set(0.0f, -0.9848077f, 0.17364818f); // 0.0, -cos(10deg), sin(10deg)
	cross.calc_cross_product(&temp, &dir);
	IVP_DOUBLE roll = IVP_Inline_Math::atan2d(cross.real_length_plus_normize(), temp.dot_product(&dir));

	IVP_BOOL bImpact = IVP_FALSE;
	int iPoint;
	for (iPoint = 0; iPoint < n_wheels; ++iPoint, ++pImpacts)
	{
		if (pImpacts->bImpact)
		{
			bImpact = IVP_TRUE;
			break;
		}
	}
	if (bImpact || (fabs(roll) < (10.0 * IVP_PI / 180.0)))
	{
		m_flKeepUprightRoll = roll;
		return;
	}

	IVP_FLOAT mass = pAirboatCore->get_mass();
	temp.set_multiple(&cross, (pEventSim->i_delta_time * 0.3 * (roll - m_flKeepUprightRoll) + roll * 0.2) * mass);
	m_flKeepUprightRoll = roll;
	mass *= (2.0 * IVP_PI / 180.0);
	IVP_FLOAT length = temp.real_length_plus_normize();
	if (length > mass)
		length = mass;
	temp.mult(length);
	pAirboatCore->rot_push_core_cs(&temp);
}
void CPhysicsObject::GetVelocityAtPoint( const Vector &worldPosition, Vector &velocity )
{
	IVP_Core *core = m_pObject->get_core();
	IVP_U_Point pos;
	ConvertPositionToIVP( worldPosition, pos );

	IVP_U_Float_Point rotSpeed;
	rotSpeed.add( &core->rot_speed, &core->rot_speed_change );

    IVP_U_Float_Point av_ws;
    core->get_m_world_f_core_PSI()->vmult3( &rotSpeed, &av_ws);

    IVP_U_Float_Point pos_rel; 	
	pos_rel.subtract( &pos, core->get_position_PSI());
    IVP_U_Float_Point cross;    
	cross.inline_calc_cross_product(&av_ws,&pos_rel);

	IVP_U_Float_Point speed;
    speed.add(&core->speed, &cross);
    speed.add(&core->speed_change);

	ConvertPositionToHL( speed, velocity );
}
void CPhysicsObject::CalculateForceOffset( const Vector &forceVector, const Vector &worldPosition, Vector &centerForce, AngularImpulse &centerTorque )
{
	IVP_U_Point pos;
	IVP_U_Float_Point force;

	ConvertPositionToIVP( forceVector, force );
	ConvertPositionToIVP( worldPosition, pos );

	IVP_Core *core = m_pObject->get_core();

    const IVP_U_Matrix *m_world_f_core = core->get_m_world_f_core_PSI();

    IVP_U_Float_Point point_d_ws;
	point_d_ws.subtract(&pos, m_world_f_core->get_position());

    IVP_U_Float_Point cross_point_dir;

    cross_point_dir.calc_cross_product( &point_d_ws, &force);
    m_world_f_core->inline_vimult3( &cross_point_dir, &cross_point_dir);

	ConvertAngularImpulseToHL( cross_point_dir, centerTorque );
	ConvertForceImpulseToHL( force, centerForce );
}
void CPhysicsObject::ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition )
{
//	Assert(IsMoveable());
	if ( !IsMoveable() )
		return;

	IVP_U_Point pos;
	IVP_U_Float_Point force;

	ConvertForceImpulseToIVP( forceVector, force );
	ConvertPositionToIVP( worldPosition, pos );

	IVP_Core *core = m_pObject->get_core();
	core->async_push_core_ws( &pos, &force );
	core->speed_change.k[0] = clamp( core->speed_change.k[0], -MAX_SPEED, MAX_SPEED );
	core->speed_change.k[1] = clamp( core->speed_change.k[1], -MAX_SPEED, MAX_SPEED );
	core->speed_change.k[2] = clamp( core->speed_change.k[2], -MAX_SPEED, MAX_SPEED );

	core->rot_speed_change.k[0] = clamp( core->rot_speed_change.k[0], -MAX_ROT_SPEED, MAX_ROT_SPEED );
	core->rot_speed_change.k[1] = clamp( core->rot_speed_change.k[1], -MAX_ROT_SPEED, MAX_ROT_SPEED );
	core->rot_speed_change.k[2] = clamp( core->rot_speed_change.k[2], -MAX_ROT_SPEED, MAX_ROT_SPEED );
	Wake();
}
void CPhysicsMotionController::AttachObject( IPhysicsObject *pObject )
{
	Assert(pObject);
	// BUGBUG: Sometimes restore comes back with a NULL, REVISIT
	if ( !pObject || pObject->IsStatic() )
		return;

	CPhysicsObject *pPhys = static_cast<CPhysicsObject *>(pObject);
	IVP_Real_Object *pIVP = pPhys->GetObject();
	IVP_Core *pCore = pIVP->get_core();

#if DEBUG
	int index = m_coreList.Find(pCore);
	if ( m_coreList.IsValidIndex(index) )
	{
		Msg("Attached core twice!!!\n");
		return;
	}
#endif

	m_coreList.AddToTail( pCore );
	pCore->add_core_controller( (IVP_Controller *)this );
}
Esempio n. 20
0
void IVP_Controller_Raycast_Airboat::DoSimulationKeepUprightPitch(IVP_Raycast_Airboat_Impact *pImpacts,
                                                                  IVP_Event_Sim *pEventSim)
{
	if (m_bAirborneIdle)
		return;

	IVP_Core *pAirboatCore = m_pAirboatBody->get_core();

	IVP_U_Float_Point dir, temp, cross;
	temp.set(0.0f, -1.0f, 0.0f);
	pAirboatCore->get_m_world_f_core_PSI()->vimult3(&temp, &dir);
	dir.k[0] = 0.0f;
	dir.normize();
	temp.set(0.0f, -0.9848077f, 0.17364818f); // 0.0, -cos(10deg), sin(10deg)
	cross.calc_cross_product(&temp, &dir);
	IVP_DOUBLE pitch = IVP_Inline_Math::atan2d(cross.real_length_plus_normize(), temp.dot_product(&dir));

	int iPoint;
	for (iPoint = 0; iPoint < n_wheels; ++iPoint, ++pImpacts)
	{
		if (pImpacts->bImpact)
		{
			m_flKeepUprightPitch = pitch;
			return;
		}
	}

	IVP_FLOAT mass = pAirboatCore->get_mass();
	temp.set_multiple(&cross, (pEventSim->i_delta_time * 0.04 * (pitch - m_flKeepUprightPitch) + pitch * 0.1) * mass);
	m_flKeepUprightPitch = pitch;
	mass *= (1.5 * IVP_PI / 180.0);
	IVP_FLOAT length = temp.real_length_plus_normize();
	if (length > mass)
		length = mass;
	temp.mult(length);
	pAirboatCore->rot_push_core_cs(&temp);
}
Esempio n. 21
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void IVP_Controller_Raycast_Airboat::DoSimulationSteering(IVP_Event_Sim *pEventSim)
{
	IVP_Core *pAirboatCore = m_pAirboatBody->get_core();

	if ((m_SteeringAngle == 0.0f) || (m_flThrust != 0.0f))
	{
		if (m_bAnalogSteering)
		{
			if (m_flThrust < -2.0f)
				m_bReverseSteering = IVP_TRUE;
			else if ((m_flThrust > 2.0f) || (m_LocalVelocity.k[2] > 0.0f))
				m_bReverseSteering = IVP_FALSE;
		}
		else
		{
			if (m_flThrust < 0.0f)
				m_bReverseSteering = IVP_TRUE;
			else if ((m_flThrust > 0.0f) || (m_LocalVelocity.k[2] > 0.0f))
				m_bReverseSteering = IVP_FALSE;
		}
	}

	IVP_FLOAT flForceRotational;
	IVP_FLOAT flSteeringSign;
	IVP_FLOAT flMass = pAirboatCore->get_mass();

	if (fabsf(m_SteeringAngle) > 0.01)
	{
		flSteeringSign = (m_SteeringAngle < 0.0f ? -1.0f : 1.0f);
		if (m_bReverseSteering)
			flSteeringSign = -flSteeringSign;
		IVP_FLOAT flLastSign = (m_LastForwardSteeringAngle < 0.0f ? -1.0f : 1.0f);
		if ((fabsf(m_LastForwardSteeringAngle) < 0.01) || (flSteeringSign != flLastSign))
			m_SteeringSpeed = 0.0f;

		flForceRotational = (m_bAnalogSteering ? fabsf(m_SteeringAngle) : m_SteeringSpeed) * 2.0f;
		if (flForceRotational < 0.0f)
			flForceRotational = 0.0f;
		else if (flForceRotational > 1.0f)
			flForceRotational = 1.0f;
		flForceRotational = flForceRotational * IVP_RAYCAST_AIRBOAT_STEERING_RATE + (IVP_RAYCAST_AIRBOAT_STEERING_RATE * 0.25f);
		flForceRotational *= -(flMass * pEventSim->i_delta_time * flSteeringSign);
		m_SteeringSpeed += pEventSim->delta_time;
	}
	else
	{
		flForceRotational = 0.0f;
	}

	m_LastForwardSteeringAngle = m_SteeringAngle;
	if (m_bReverseSteering)
		m_LastForwardSteeringAngle = -m_LastForwardSteeringAngle;

	IVP_FLOAT flRotSpeed = pAirboatCore->rot_speed.k[1];
	flSteeringSign = (flRotSpeed < 0.0f ? -1.0f : 1.0f);

	IVP_FLOAT flForceImpulse = flMass * pEventSim->i_delta_time * flSteeringSign;
	flForceRotational += 0.0004f * flRotSpeed * flRotSpeed * flForceImpulse;
	flForceRotational += 0.001f * fabsf(flRotSpeed) * flForceImpulse;

	IVP_U_Float_Point vecAngularImpulse;
	vecAngularImpulse.set(0.0f, -flForceRotational, 0.0f);
	pAirboatCore->rot_push_core_cs(&vecAngularImpulse);
}
void CPhysicsMotionController::do_simulation_controller(IVP_Event_Sim *event,IVP_U_Vector<IVP_Core> *core_list)
{
	if ( m_handler )
	{
		for ( int i = 0; i < core_list->len(); i++ )
		{
			IVP_U_Float_Point ivpSpeed, ivpRot;
			IVP_Core *pCore = core_list->element_at(i);
			Vector speed;
			AngularImpulse rot;

			IVP_Real_Object *pivp = pCore->objects.element_at(0);
			IPhysicsObject *pPhys = static_cast<IPhysicsObject *>(pivp->client_data);
			IMotionEvent::simresult_e ret = m_handler->Simulate( this, pPhys, event->delta_time, speed, rot );

			switch( ret )
			{
			case IMotionEvent::SIM_NOTHING:
				break;
			case IMotionEvent::SIM_LOCAL_ACCELERATION:
				{
					ConvertForceImpulseToIVP( speed, ivpSpeed );
					ConvertAngularImpulseToIVP( rot, ivpRot );
					const IVP_U_Matrix *m_world_f_core = pCore->get_m_world_f_core_PSI();
					// transform to world space
					m_world_f_core->inline_vmult3( &ivpSpeed, &ivpSpeed );
					// UNDONE: Put these values into speed change / rot_speed_change instead?
					pCore->speed.add_multiple( &ivpSpeed, event->delta_time );
					pCore->rot_speed.add_multiple( &ivpRot, event->delta_time );
				}
				break;
			case IMotionEvent::SIM_LOCAL_FORCE:
				{
					ConvertForceImpulseToIVP( speed, ivpSpeed );
					ConvertAngularImpulseToIVP( rot, ivpRot );
					const IVP_U_Matrix *m_world_f_core = pCore->get_m_world_f_core_PSI();
					// transform to world space
					m_world_f_core->inline_vmult3( &ivpSpeed, &ivpSpeed );
					pCore->center_push_core_multiple_ws( &ivpSpeed, event->delta_time );
					pCore->rot_push_core_multiple_cs( &ivpRot, event->delta_time );
				}
				break;
			case IMotionEvent::SIM_GLOBAL_ACCELERATION:
				{
					ConvertAngularImpulseToIVP( rot, ivpRot );
					ConvertForceImpulseToIVP( speed, ivpSpeed );
					pCore->speed.add_multiple( &ivpSpeed, event->delta_time );
					pCore->rot_speed.add_multiple( &ivpRot, event->delta_time );
				}
				break;
			case IMotionEvent::SIM_GLOBAL_FORCE:
				{
					ConvertAngularImpulseToIVP( rot, ivpRot );
					ConvertForceImpulseToIVP( speed, ivpSpeed );
					pCore->center_push_core_multiple_ws( &ivpSpeed, event->delta_time );
					pCore->rot_push_core_multiple_cs( &ivpRot, event->delta_time );
				}
				break;
			}
		}
	}
}