📄 ivp_car_system.cxx
字号:
torque_template.anchors[0] = &anchor_left_template;
torque_template.anchors[1] = &anchor_right_template;
torque_template.torque = 0.0f; // This wasn't here, is this why we started with force?
this->car_act_torque[wheel_nr] = environment->create_torque( &torque_template );
this->fix_wheel_constraint[wheel_nr] = NULL;
}
// Wheel rotation counterforce to body
IVP_Template_Anchor anchor_left_template;
IVP_Template_Anchor anchor_right_template;
IVP_Template_Torque torque_template;
// countertorque default
torque_template.max_rotation_speed = ( IVP_FLOAT )IVP_PI * 100.0f;
// create torque actuator
IVP_U_Float_Point hp;
hp.set_to_zero();
hp.k[cs_car->x_idx] = 1.0f;
anchor_left_template.set_anchor_position_os( car_body, &hp );
hp.k[cs_car->x_idx] = -1.0f;
anchor_right_template.set_anchor_position_os( car_body, &hp );
torque_template.anchors[0] = &anchor_left_template;
torque_template.anchors[1] = &anchor_right_template;
torque_template.torque = 0.0f;
this->car_act_torque_body = environment->create_torque( &torque_template );
this->body_counter_torque_factor = templ->body_counter_torque_factor;
///////////////////////////////////////////////////////////////////
//////// STABILIZERS /////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// equip vehicle axles with stabilizers
if ( n_wheels != n_axis )
{
for( int i = 0; i < 2; i++ )
{
// i=0: front stabi, i=1: rear stabi
IVP_Template_Stabilizer stabi_template;
// set default
stabi_template.stabi_constant = templ->stabilizer_constant[i]; // Newton/meter
stabi_template.anchors[0] = &anchor_body_template[i*2];
stabi_template.anchors[1] = &anchor_wheel_template[i*2];
stabi_template.anchors[2] = &anchor_body_template[i*2+1];
stabi_template.anchors[3] = &anchor_wheel_template[i*2+1];
this->car_stabilizer[i] = environment->create_stabilizer( &stabi_template );
}
}
///////////////////////////////////////////////////////////////////
//////// DOWNFORCE //////////////////////
///////////////////////////////////////////////////////////////////
IVP_Real_Object *static_object = environment->get_static_object();
IVP_Template_Anchor anchor_center_template;
IVP_Template_Anchor anchor_down_template;
IVP_Template_Force force_template;
// create force actuator
// @@@OG Should better use core system.
// IVP_U_Float_Point hp;
hp.set_to_zero();
hp.k[cs_car->y_idx] += templ->body_down_force_vertical_offset; // offset for arbitrary rotation (e.g. when in air)
anchor_center_template.set_anchor_position_cs(car_body, &hp);
// Real far downwards so it appears vertical
hp.k[cs_car->y_idx] = 1e8f;
if ( environment->get_gravity()->k[cs_car->y_idx] > 0 )
{
hp.k[cs_car->y_idx] *= -1; // Check gravity
}
anchor_down_template.set_anchor_position_os( static_object, &hp );
force_template.anchors[0] = &anchor_center_template;
force_template.anchors[1] = &anchor_down_template;
force_template.force = 0.0f;
force_template.push_first_object = IVP_TRUE;
force_template.push_second_object = IVP_FALSE;
this->car_act_down_force = environment->create_force( &force_template );
///////////////////////////////////////////////////////////////////
//////// EXTRA GRAVITY //////////////////
///////////////////////////////////////////////////////////////////
// IVP_Template_Anchor anchor_center_template;
// IVP_Template_Anchor anchor_down_template;
// IVP_Template_Force force_template;
IVP_U_Float_Point center;
center.set_to_zero();
center.k[cs_car->y_idx] = templ->extra_gravity_height_offset;
anchor_center_template.set_anchor_position_cs( car_body, ¢er );
// IVP_U_Float_Point hp;
hp.set_to_zero();
// Real far downwards so it appears vertical
hp.k[cs_car->y_idx] = 1e8f;
if ( environment->get_gravity()->k[cs_car->y_idx] > 0 )
{
hp.k[cs_car->y_idx] *= -1; // Check direction of gravity
}
anchor_down_template.set_anchor_position_os( static_object, &hp );
force_template.anchors[0] = &anchor_center_template;
force_template.anchors[1] = &anchor_down_template;
force_template.force = templ->extra_gravity_force_value;
force_template.push_first_object = IVP_TRUE;
force_template.push_second_object = IVP_FALSE;
this->car_act_extra_gravity = environment->create_force( &force_template );
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
for ( int w = 0; w < n_wheels; w++ )
{
do_steering_wheel( IVP_POS_WHEEL( w ), 0.0f);
}
this ->steering_angle = -1.0f; // make sure next call is not optimized
this->do_steering( 0.0f ); // make sure next call gets through
// register to environment as PSI listener
//environment->add_listener_PSI(this);
return;
}
void IVP_Car_System_Real_Wheels::get_skid_info( IVP_Wheel_Skid_Info *array_of_skid_info_out){
for ( int w = 0; w < n_wheels; w++){
IVP_Wheel_Skid_Info &info = array_of_skid_info_out[w];
IVP_Constraint_Car_Object *wheel = car_constraint_solver->wheel_objects.element_at(w);
info.last_contact_position_ws = wheel->last_contact_position_ws;
info.last_skid_value = wheel->last_skid_value;
info.last_skid_time = wheel->last_skid_time;
}
}
// stop wheel completely (e.g. handbrake )
void IVP_Car_System_Real_Wheels::fix_wheel( IVP_POS_WHEEL wheel_nr, IVP_BOOL stop_wheel )
{
if ( !stop_wheel )
{
car_constraint_solver->wheel_objects.element_at( wheel_nr ) -> fix_wheel_constraint = NULL;
P_DELETE( fix_wheel_constraint[wheel_nr] );
return;
}
IVP_Real_Object *wheel = this->car_wheel[wheel_nr];
// Already activated.
if ( fix_wheel_constraint[wheel_nr] )
return;
// Attach constraint to block wheel rotation
IVP_Template_Constraint constraint;
constraint.set_reference_object( wheel ); // set reference object
constraint.set_attached_object( car_body ); // set attached object
constraint.fix_rotation_axis( IVP_INDEX_X );
constraint.free_rotation_axis( IVP_INDEX_Y );
constraint.free_rotation_axis( IVP_INDEX_Z );
constraint.free_translation_axis( IVP_INDEX_X );
constraint.free_translation_axis( IVP_INDEX_Y );
constraint.free_translation_axis( IVP_INDEX_Z );
// Magic Trick: slow down wheel to avoid effects that would normally
// result from such an immediate blocking (inertias!)
IVP_Core *wheel_core = wheel->get_core();
wheel_core->rot_speed.add_multiple( &car_body->get_core()->rot_speed, 0.25f );
// wheel_core->rot_speed = car_body->get_core()->rot_speed;
IVP_Environment *env = this->environment;
this->fix_wheel_constraint[wheel_nr] = env->create_constraint( &constraint );
car_constraint_solver->wheel_objects.element_at( wheel_nr ) ->fix_wheel_constraint = this->fix_wheel_constraint[wheel_nr];
}
/********************************************************************************
* Name: activate_booster
* Description: 'Rocket' propulsion (in contrary to the standard wheel drive)
********************************************************************************/
void IVP_Car_System_Real_Wheels::activate_booster( IVP_FLOAT thrust, IVP_FLOAT duration, IVP_FLOAT delay )
{
// Do we have an booster?
if( booster_actuator[0] )
return;
// Booster not ready yet.
if( booster_seconds_until_ready > 0.0f )
return;
// Ignite booster by adding an actuator force to the car body
float gravity = environment->get_gravity()->real_length();
set_booster_acceleration( thrust * gravity );
// seconds
booster_seconds_to_go = duration;
// time when next ignition is possible
booster_seconds_until_ready = duration + delay;
}
void IVP_Car_System_Real_Wheels::set_booster_acceleration( IVP_FLOAT acceleration )
{
if ( acceleration )
{
IVP_Real_Object *pCarBody = car_body;
if ( !booster_actuator[0] )
{
IVP_Template_Anchor anchorTempForward[2];
IVP_Template_Anchor anchorTempUp[2];
IVP_Template_Force forceTempForward;
IVP_Template_Force forceTempUp;
IVP_Constraint_Solver_Car *pCarConstraint = car_constraint_solver;
IVP_Real_Object *pStaticObject = environment->get_static_object();
IVP_U_Float_Point frontPoint, backPoint;
frontPoint.set_to_zero();
backPoint.set_to_zero();
frontPoint.k[pCarConstraint->z_idx] = 1.0f;
backPoint.k[pCarConstraint->z_idx] = -1.0f;
anchorTempForward[0].set_anchor_position_cs( pCarBody, &frontPoint );
anchorTempForward[1].set_anchor_position_cs( pCarBody, &backPoint );
IVP_U_Float_Point centerPoint, downPoint;
centerPoint.set_to_zero();
downPoint.set_to_zero();
downPoint.k[pCarConstraint->y_idx] = -1e8f;
anchorTempUp[0].set_anchor_position_cs( pCarBody, ¢erPoint );
anchorTempUp[1].set_anchor_position_os( pStaticObject, &downPoint );
forceTempForward.anchors[0] = &anchorTempForward[0];
forceTempForward.anchors[1] = &anchorTempForward[1];
forceTempForward.active_float_force = NULL;
forceTempForward.push_first_object = IVP_TRUE;
forceTempForward.push_second_object = IVP_FALSE;
forceTempForward.force = acceleration * pCarBody->get_core()->get_mass();
forceTempUp.anchors[0] = &anchorTempUp[0];
forceTempUp.anchors[1] = &anchorTempUp[1];
forceTempUp.active_float_force = NULL;
forceTempUp.push_first_object = IVP_TRUE;
forceTempUp.push_second_object = IVP_FALSE;
forceTempUp.force = -1.0f * pCarBody->get_core()->get_mass() * environment->get_gravity()->k[pCarConstraint->y_idx];
booster_actuator[0] = environment->create_force( &forceTempForward );
booster_actuator[1] = environment->create_force( &forceTempUp );
}
else
{
booster_actuator[0]->set_force( acceleration * pCarBody->get_core()->get_mass() );
}
}
else
{
P_DELETE( booster_actuator[0] );
P_DELETE( booster_actuator[1] );
}
}
/********************************************************************************
* Name: update_booster
* Description: Check and update booster burn status
********************************************************************************/
void IVP_Car_System_Real_Wheels::update_booster(IVP_FLOAT delta_time)
{
if ( booster_seconds_until_ready > 0.0f )
{
booster_seconds_until_ready -= delta_time;
}
if ( booster_seconds_to_go > 0.0f )
{
this->booster_seconds_to_go -= delta_time;
// booster shut down?
if ( booster_seconds_to_go <= 0.0f )
{
set_booster_acceleration( 0.0f );
}
}
}
IVP_FLOAT IVP_Car_System_Real_Wheels::get_booster_delay()
{
return booster_seconds_until_ready;
}
IVP_Car_System_Real_Wheels::~IVP_Car_System_Real_Wheels()
{
//environment->remove_listener_PSI(this);
P_DELETE(car_constraint_solver);
}
void IVP_Car_System_Real_Wheels::environment_will_be_deleted(IVP_Environment *){
delete this;
}
IVP_FLOAT IVP_Car_System::calc_ackerman_angle(IVP_FLOAT alpha, IVP_FLOAT dx, IVP_FLOAT dz){
// We got the steering angle for that front wheel towards
// the curve center (alpha). Now lets compute the Ackerman angle
// for the outer front wheel.
// dx means distance between the two front wheels,
// dz means "Radstand" (distance between front and rear 'axles').
IVP_FLOAT a = IVP_Inline_Math::fabsd(alpha); // was fabs, which was a sml call
if(a<0.001f) return alpha; // numerical reasons
IVP_DOUBLE tan_alpha = tan(a);
IVP_DOUBLE h = (dz*tan_alpha)/(dx*tan_alpha+dz);
IVP_DOUBLE beta = atan(h);
IVP_DOUBLE signum = (alpha<0.0f)?-1.0f:1.0f;
return (IVP_FLOAT)(beta * signum);
}
IVP_Car_System::~IVP_Car_System(){
;
}
IVP_Car_System::IVP_Car_System(){
;
}
//-----------------------------------------------------------------------------
// Purpose: Debug data for use in vphysics and the engine to visualize car data.
//-----------------------------------------------------------------------------
void IVP_Car_System_Real_Wheels::SetCarSystemDebugData( const IVP_CarSystemDebugData_t &carSystemDebugData )
{
return;
}
//-----------------------------------------------------------------------------
// Purpose: Debug data for use in vphysics and the engine to visualize car data.
//-----------------------------------------------------------------------------
void IVP_Car_System_Real_Wheels::GetCarSystemDebugData( IVP_CarSystemDebugData_t &carSystemDebugData )
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -