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 ¢erVelocity, AngularImpulse ¢erAngularVelocity ) { 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 ); }
//----------------------------------------------------------------------------- // 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); }
//----------------------------------------------------------------------------- // 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); }
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 ¢erForce, AngularImpulse ¢erTorque ) { 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 ); }
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); }
//----------------------------------------------------------------------------- // 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; } } } }