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 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); }