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