void IVP_Controller_Raycast_Airboat::do_steering_wheel(IVP_POS_WHEEL wheel_nr, IVP_FLOAT s_angle) { IVP_Raycast_Airboat_Wheel *wheel = get_wheel(wheel_nr); wheel->axis_direction_cs.set_to_zero(); wheel->axis_direction_cs.k[ index_x ] = 1.0f; wheel->axis_direction_cs.rotate( IVP_COORDINATE_INDEX(index_y), s_angle); }
void CPhysics_Car_System_Raycast_Wheels::update_wheel_positions( void ) { // Get the car body object. IVP_Cache_Object *pCacheObject = car_body->get_cache_object(); // Get the core (vehicle) matrix. IVP_U_Matrix m_core_f_object; car_body->calc_m_core_f_object( &m_core_f_object ); for ( int iWheel = 0; iWheel < n_wheels; ++iWheel ) { // Get the current raycast wheel. IVP_Raycast_Car_Wheel *pRaycastWheel = get_wheel( IVP_POS_WHEEL( iWheel ) ); // Get the position of the wheel in vehicle core space. IVP_U_Float_Point hp_cs; hp_cs.add_multiple( &pRaycastWheel->hp_cs, &pRaycastWheel->spring_direction_cs, pRaycastWheel->raycast_dist - pRaycastWheel->wheel_radius ); // Get the position on vehicle object space (inverse transform). IVP_U_Float_Point hp_os; m_core_f_object.vimult4( &hp_cs, &hp_os ); // Transform the wheel position from object space into world space. IVP_U_Point hp_ws; pCacheObject->transform_position_to_world_coords( &hp_os, &hp_ws ); // Apply rotational component. IVP_U_Point wheel_cs( &pRaycastWheel->axis_direction_cs ); IVP_U_Point wheel2_cs( 0 ,0 ,0 ); wheel2_cs.k[index_y] = -1.0; wheel2_cs.rotate( IVP_COORDINATE_INDEX( index_x ), pRaycastWheel->angle_wheel ); IVP_U_Matrix3 m_core_f_wheel; m_core_f_wheel.init_normized3_col( &wheel_cs, IVP_COORDINATE_INDEX( index_x ), &wheel2_cs ); IVP_U_Matrix3 m_world_f_wheel; pCacheObject->m_world_f_object.mmult3( &m_core_f_wheel, &m_world_f_wheel ); // bid hack, assumes cs = os (for rotation); IVP_U_Quat rot_ws; rot_ws.set_quaternion( &m_world_f_wheel ); m_pWheels[iWheel]->beam_object_to_new_position( &rot_ws, &hp_ws ); } pCacheObject->remove_reference(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void IVP_Controller_Raycast_Airboat::DoSimulationTurbine( IVP_Raycast_Airboat_Pontoon_Temp *pTempPontoons, IVP_Event_Sim *pEventSim, IVP_Core *pAirboatCore ) { // Get the forward vector in world-space. IVP_U_Float_Point vecForwardWS; const IVP_U_Matrix *matWorldFromCore = pAirboatCore->get_m_world_f_core_PSI(); matWorldFromCore->get_col( IVP_COORDINATE_INDEX( index_z ), &vecForwardWS ); // Forward (Front/Back) force IVP_U_Float_Point vecImpulse; vecImpulse.set_multiple( &vecForwardWS, m_flThrust * pEventSim->delta_time ); pAirboatCore->center_push_core_multiple_ws( &vecImpulse ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void IVP_Controller_Raycast_Airboat::DoSimulationSteering( IVP_Raycast_Airboat_Pontoon_Temp *pTempPontoons, IVP_Core *pAirboatCore, IVP_Event_Sim *pEventSim ) { IVP_U_Float_Point vecRightWS; const IVP_U_Matrix *matWorldFromCore = pAirboatCore->get_m_world_f_core_PSI(); matWorldFromCore->get_col( IVP_COORDINATE_INDEX( index_x ), &vecRightWS ); IVP_FLOAT flForceRotational = 0.0f; // Check for rotation. if ( fabsf( m_SteeringAngle ) > 0.01 ) { // Get the steering sign. IVP_FLOAT flSteeringSign = m_SteeringAngle < 0.0f ? -1.0f : 1.0f; flForceRotational = IVP_RAYCAST_AIRBOAT_STEERING_RATE * pAirboatCore->get_mass() * pEventSim->i_delta_time; flForceRotational *= flSteeringSign; } // General force that will help get us back to zero rotation. IVP_FLOAT flRotSpeedSign = pAirboatCore->rot_speed.k[1] < 0.0f ? -1.0f : 1.0f; IVP_FLOAT flRotationalDrag = -0.5f * IVP_RAYCAST_AIRBOAT_STEERING_RATE * pAirboatCore->get_mass() * pEventSim->i_delta_time; flRotationalDrag *= flRotSpeedSign; flForceRotational += flRotationalDrag; IVP_U_Float_Point vecImpulse; for ( int iPoint = 0; iPoint < 4; ++iPoint ) { IVP_Raycast_Airboat_Wheel *pPontoonPoint = get_wheel( IVP_POS_WHEEL( iPoint ) ); IVP_Raycast_Airboat_Pontoon_Temp *pTempPontoonPoint = &pTempPontoons[iPoint]; IVP_FLOAT flPontoonSign = iPoint >= 2 ? -1.0f : 1.0f; IVP_FLOAT flForceRot = flForceRotational * flPontoonSign; vecImpulse.set_multiple( &vecRightWS, flForceRot * pEventSim->delta_time ); IVP_U_Float_Point vecPointPosCS, vecPointPosWS; vecPointPosCS = pPontoonPoint->raycast_start_cs; matWorldFromCore->vmult3( &vecPointPosCS, &vecPointPosWS ); IVP_U_Point vecPointPositionWS( vecPointPosWS ); pAirboatCore->push_core_ws( &vecPointPositionWS, &vecImpulse ); } }
//----------------------------------------------------------------------------- // 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); }