⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ivp_car_system.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 2 页
字号:
		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, &center );
	
//	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, &centerPoint );
			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 + -