mirror of
https://github.com/thug1src/thug.git
synced 2024-11-30 12:06:44 +00:00
763 lines
24 KiB
C++
763 lines
24 KiB
C++
//****************************************************************************
|
|
//* MODULE: Gel/Components
|
|
//* FILENAME: VehicleComponent.h
|
|
//* OWNER: ???
|
|
//* CREATION DATE: ??/??/??
|
|
//****************************************************************************
|
|
|
|
#ifndef __COMPONENTS_VEHICLECOMPONENT_H__
|
|
#define __COMPONENTS_VEHICLECOMPONENT_H__
|
|
|
|
#include <core/defines.h>
|
|
#include <core/support.h>
|
|
|
|
#include <gel/collision/collcache.h>
|
|
#include <gel/components/skeletoncomponent.h>
|
|
#include <gel/components/triggercomponent.h>
|
|
#include <gel/object/basecomponent.h>
|
|
|
|
#include <sk/engine/rectfeeler.h>
|
|
#include <sk/engine/feeler.h>
|
|
|
|
#define CRC_VEHICLE CRCD(0xe47f1b79, "Vehicle")
|
|
#define GetVehicleComponent() ((Obj::CVehicleComponent*)GetComponent(CRC_VEHICLE))
|
|
#define GetVehicleComponentFromObject(pObj) ((Obj::CVehicleComponent*)(pObj)->GetComponent(CRC_VEHICLE))
|
|
|
|
namespace Script
|
|
{
|
|
class CScript;
|
|
class CStruct;
|
|
}
|
|
|
|
namespace Obj
|
|
{
|
|
class CInputComponent;
|
|
class CAnimationComponent;
|
|
class CSkaterCorePhysicsComponent;
|
|
class CModelComponent;
|
|
|
|
#define vVP_GRAVITATIONAL_ACCELERATION (386.4f)
|
|
#define vVP_MAX_NUM_GEARS (6)
|
|
#define vVP_NUM_COLLIDERS (2)
|
|
|
|
#define vVP_FLIP_DURATION (5000)
|
|
#define vVP_FLIP_DELAY (300)
|
|
#define vVP_FLIP_RATE (3.0f)
|
|
#define vVP_FLIP_GRAVITY_FACTOR (0.3f)
|
|
#define vVP_SLEEP_VEL (1.0f)
|
|
#define vVP_SLEEP_ROTVEL (0.01f)
|
|
|
|
class CVehicleComponent : public CBaseComponent
|
|
{
|
|
friend class CVehicleSoundComponent;
|
|
|
|
// number of frames of normal force history to record for each tire
|
|
enum { vVP_NORMAL_FORCE_HISTORY_LENGTH = 10 };
|
|
|
|
// HACK for control
|
|
struct SControls {
|
|
// steering; between -1.0 and 1.0
|
|
float steering;
|
|
|
|
// throttle
|
|
bool throttle;
|
|
|
|
// brake
|
|
bool brake;
|
|
|
|
// handbrake
|
|
bool handbrake;
|
|
|
|
// reverse
|
|
bool reverse;
|
|
};
|
|
|
|
struct SEngine
|
|
{
|
|
// state variables
|
|
// int gear;
|
|
|
|
// constant characteristics
|
|
|
|
// engine's base torque output before applying gear ratios
|
|
float drive_torque;
|
|
float drag_torque;
|
|
|
|
int num_gears;
|
|
|
|
float p_gear_ratios[vVP_MAX_NUM_GEARS];
|
|
|
|
float reverse_torque_ratio;
|
|
|
|
float differential_ratio;
|
|
|
|
// float differential_stiffness;
|
|
|
|
// float downshift_rotvel;
|
|
|
|
float upshift_rotvel;
|
|
};
|
|
|
|
struct SBrake
|
|
{
|
|
// state variables
|
|
|
|
// brake torque is applied both after engine torque and friction torque; here we track the unused torque between the applications
|
|
float spare_torque;
|
|
|
|
// constant characteristics
|
|
|
|
// braking torque per wheel
|
|
float torque;
|
|
|
|
// strength of the handbrake torque when throttle is down and steering is forward
|
|
float handbrake_torque;
|
|
};
|
|
|
|
struct SWheel
|
|
{
|
|
|
|
enum EStateType {
|
|
NO_STATE, OUT_OF_CONTACT, UNDER_GRIPPING, GRIPPING, SLIPPING, SKIDDING, HANDBRAKE_THROTTLE, HANDBRAKE_LOCKED
|
|
};
|
|
|
|
enum ESteeringType {
|
|
FIXED, LEFT, RIGHT
|
|
};
|
|
|
|
// state variables
|
|
|
|
// offset along Y-axis of wheel's position in vehicle's frame
|
|
float y_offset;
|
|
|
|
// is the wheel out of contact, gripped, skidding, etc
|
|
EStateType state;
|
|
|
|
// angular velocity about the axle
|
|
float rotvel;
|
|
|
|
// angular position about the axle
|
|
float orientation;
|
|
|
|
// angle of deflection from forward
|
|
float steering_angle;
|
|
|
|
// displayed angle of deflection from forward; lerps behind steering_angle
|
|
float steering_angle_display;
|
|
|
|
// dependent variables
|
|
|
|
// world frame position of the bottom of the wheel
|
|
Mth::Vector pos_world;
|
|
|
|
// world frame velocity of the bottom of the wheel, not counting rotation
|
|
Mth::Vector vel_world;
|
|
|
|
// magnitude of the normal force applied by the suspension through the tire; set in apply_suspension_forces(); used in apply_friction_forces()
|
|
float normal_force;
|
|
|
|
// magnitude of the normal force for the last few frames; friction uses a smoothed normal force to even out control
|
|
float normal_force_history [ vVP_NORMAL_FORCE_HISTORY_LENGTH ];
|
|
|
|
// normal of the wheel's contact surface
|
|
Mth::Vector contact_normal;
|
|
|
|
// friction coefficient this frame
|
|
float friction_coefficient;
|
|
|
|
// ground detector feeler start and end positions in world frame
|
|
Mth::Vector feeler_start_world;
|
|
Mth::Vector feeler_end_world;
|
|
|
|
// NOTE: used only to draw skid indicators; remove if not used for anything else
|
|
float slip_vel;
|
|
|
|
// accumulators
|
|
|
|
// total rotational acceleration applied so far this frame
|
|
float rotacc;
|
|
|
|
// constant characteristics
|
|
|
|
// start of the wheel's downward pointing collision feeler; basically the top of the wheel's position in the vehicle's frame
|
|
Mth::Vector pos;
|
|
|
|
// type of wheel with respect to steering
|
|
ESteeringType steering;
|
|
|
|
// true if the wheel is a drive wheel
|
|
bool drive;
|
|
|
|
// hang point; wheel's y_offset will drop only to this point; the effective equilibrium point for the spring, if one accounts for the wheel's
|
|
// weight ahead of time
|
|
float y_offset_hang;
|
|
|
|
// the wheels are never rendered above this y threshold; this has no affect on their location from the physics code's perspective
|
|
float max_draw_y_offset;
|
|
|
|
// radius of wheel and tire (in)
|
|
float radius;
|
|
|
|
// inverse moment of the wheel and tire around the axis (1 / lb / in^2)
|
|
float inv_moment;
|
|
|
|
// suspension's spring constant (lb / in); spring rate
|
|
float spring;
|
|
|
|
// suspension's damping constant (lb s / in); bump rate
|
|
float damping;
|
|
|
|
// the friction coefficient is a set of concatenated lines; the transitions are made as these velocities; a more sophisticated
|
|
float min_static_velocity;
|
|
float max_static_velocity;
|
|
float min_dynamic_velocity;
|
|
|
|
// static friction coefficient
|
|
float static_friction;
|
|
|
|
// dynamic friction coefficient
|
|
float dynamic_friction;
|
|
|
|
// friction coefficient during handbraking
|
|
float handbrake_throttle_friction;
|
|
float handbrake_locked_friction;
|
|
|
|
// subelements
|
|
|
|
// brake
|
|
SBrake brake;
|
|
|
|
// caches to avoid repeating calculations between friction coefficient calculation and friction application
|
|
Mth::Vector cache_projected_direction;
|
|
Mth::Vector cache_projected_vel;
|
|
|
|
// the last feeler for this wheel's height which touched the ground
|
|
CFeeler last_ground_feeler;
|
|
};
|
|
|
|
struct SCollisionPoint
|
|
{
|
|
// world position
|
|
Mth::Vector pos;
|
|
|
|
// impact normal
|
|
Mth::Vector normal;
|
|
|
|
// depth of collision as defined as the dot between the displacement from the nearest collider corner and the collision normal
|
|
float depth;
|
|
|
|
// normal impulse accumulator; used to set the maximum friction
|
|
float normal_impulse;
|
|
|
|
bool line;
|
|
};
|
|
|
|
struct SCollider
|
|
{
|
|
// the rectangle defining the collider in body space
|
|
Mth::Rectangle body;
|
|
|
|
// that rectangle transformed into world space
|
|
Mth::Rectangle world;
|
|
Mth::Vector first_edge_direction_world;
|
|
Mth::Vector second_edge_direction_world;
|
|
|
|
// a few precomputable values
|
|
float first_edge_length;
|
|
float second_edge_length;
|
|
};
|
|
|
|
public:
|
|
// inorder to interface with models and skeletons, the number of wheels must be hardcoded to four
|
|
enum { vVP_NUM_WHEELS = 4 };
|
|
|
|
public:
|
|
CVehicleComponent();
|
|
virtual ~CVehicleComponent();
|
|
|
|
public:
|
|
virtual void Update();
|
|
virtual void InitFromStructure( Script::CStruct* pParams );
|
|
virtual void RefreshFromStructure( Script::CStruct* pParams );
|
|
virtual void Finalize ( );
|
|
|
|
virtual EMemberFunctionResult CallMemberFunction( uint32 Checksum, Script::CStruct* pParams, Script::CScript* pScript );
|
|
virtual void GetDebugInfo( Script::CStruct* p_info );
|
|
|
|
static CBaseComponent* s_create();
|
|
|
|
void MoveToNode ( Script::CStruct* p_node );
|
|
void ApplyArtificialCollision ( const Mth::Vector& offset );
|
|
|
|
|
|
const Mth::Vector& GetVel ( ) const { return m_vel; }
|
|
int GetNumWheelsInContact ( ) const { return m_num_wheels_in_contact; }
|
|
bool IsOnGround ( ) const;
|
|
|
|
uint32 GetSoundSetupChecksum ( ) const;
|
|
|
|
private:
|
|
|
|
void get_input ( );
|
|
void zero_input ( );
|
|
|
|
void update_wheel_from_structure ( SWheel& wheel, Script::CStruct* p_wheel_struct );
|
|
|
|
void update_dynamic_state ( );
|
|
void update_wheel_dynamic_state ( );
|
|
void update_dependent_variables ( );
|
|
void update_velocities ( );
|
|
void update_collision_cache ( );
|
|
|
|
void damp_rotation ( );
|
|
|
|
void calculate_inverse_moment ( );
|
|
float calculate_friction_coefficient ( SWheel& wheel, float velocity ) const;
|
|
void calculate_friction_coefficients ( );
|
|
Mth::Vector calculate_body_point_velocity ( const Mth::Vector& pos ) const;
|
|
float calculate_body_point_effective_mass ( const Mth::Vector& pos, const Mth::Vector& direction ) const;
|
|
|
|
int determine_effective_gear ( float wheel_rotvel );
|
|
void update_wheel_heights ( );
|
|
void update_steering_angles ( );
|
|
|
|
void accumulate_forces ( );
|
|
void apply_gravitational_forces ( );
|
|
void apply_suspension_forces ( );
|
|
void apply_engine_forces ( );
|
|
void apply_drag_forces ( );
|
|
void apply_friction_forces ( );
|
|
void apply_brake_forces ( );
|
|
void apply_handbrake_forces ( float application_factor );
|
|
void apply_spare_brake_forces ( );
|
|
|
|
void accumulate_force ( const Mth::Vector& force, const Mth::Vector& location, uint32 color = MAKE_RGB(255, 255, 255) );
|
|
void accumulate_collision_force ( const Mth::Vector& force, const Mth::Vector& location );
|
|
void apply_wheel_torque ( SWheel& wheel, float torque );
|
|
float calculate_stopping_torque ( const SWheel& wheel, float rotvel ) const;
|
|
|
|
void update_flip ( );
|
|
void slerp_to_face_velocity ( );
|
|
void consider_sleeping ( );
|
|
bool in_artificial_collision ( );
|
|
|
|
|
|
// environment collision members
|
|
float calculate_collision_depth ( const SCollisionPoint& collision_point, const SCollider& collider ) const;
|
|
float calculate_collision_depth ( const CLineFeeler& line_feeler ) const;
|
|
bool check_for_capping ( SCollisionPoint& collision_point, const CRectFeeler& rect_feeler, const SCollider& collider, int collision_line_idx, int collision_point_end_idx ) const;
|
|
bool consider_culling_point ( const SCollisionPoint& collision_point ) const;
|
|
bool very_close ( const Mth::Vector p, const Mth::Vector q ) const;
|
|
bool reset_this_frame ( ) const;
|
|
void apply_environment_collisions ( );
|
|
void update_pos_with_uber_frig ( const Mth::Vector& movement );
|
|
void apply_impulse ( const Mth::Vector& impulse, const Mth::Vector& location);
|
|
|
|
void trip_trigger ( ESkaterTriggerType trigger_type, CLineFeeler &feeler );
|
|
void trip_trigger ( ESkaterTriggerType trigger_type, CRectFeeler &feeler );
|
|
|
|
void control_skater ( );
|
|
|
|
void update_skeleton ( );
|
|
|
|
void draw_shadow ( );
|
|
|
|
Mth::Vector wheel_point ( const SWheel& wheel, int i, bool side ) const;
|
|
void draw_debug_rendering ( ) const;
|
|
|
|
private:
|
|
|
|
// dynamic state variables
|
|
|
|
// position
|
|
Mth::Vector m_pos;
|
|
|
|
// linear momentum
|
|
Mth::Vector m_mom;
|
|
|
|
// angular orientation
|
|
Mth::Quat m_orientation;
|
|
|
|
// rotational momentum
|
|
Mth::Vector m_rotmom;
|
|
|
|
// like a rigidbody, the vehicle can go to sleep
|
|
enum EStateType
|
|
{
|
|
ASLEEP, AWAKE
|
|
}
|
|
m_state;
|
|
|
|
// counting the number of consecutive sleep-worthy frames; after a certain number, we will go to sleep
|
|
int m_consider_sleeping_count;
|
|
|
|
// number of collision contacts during latest collision test
|
|
int m_num_collision_points;
|
|
|
|
// dependent state variables
|
|
|
|
// angular orientation in 3x3 matrix form
|
|
Mth::Matrix m_orientation_matrix;
|
|
|
|
// linear velocity
|
|
Mth::Vector m_vel;
|
|
|
|
// rotational velocity
|
|
Mth::Vector m_rotvel;
|
|
|
|
// inverse moment of inertia in world frame
|
|
Mth::Matrix m_inv_moment;
|
|
|
|
// offset of center of mass used for suspension and friction, but not collisions
|
|
Mth::Vector m_suspension_center_of_mass_world;
|
|
|
|
// counts the number of wheels in contact with the ground
|
|
unsigned int m_num_wheels_in_contact;
|
|
|
|
// pointer to the next normal force history to use (the oldest one)
|
|
char m_next_normal_force_history_idx;
|
|
|
|
// if true, we were reset from a trigger script and should bail from the frame's update logic
|
|
bool m_reset_this_frame;
|
|
|
|
// if true, we are currently in the midst of flipping the car over
|
|
bool m_in_flip;
|
|
|
|
// if we're flipping the car, this is a time stamp of when the flipping began
|
|
Tmr::Time m_flip_start_time_stamp;
|
|
|
|
// during an artificial collision, this timer counts down to the end of the duration
|
|
float m_artificial_collision_timer;
|
|
|
|
// accumulators
|
|
|
|
// accumulates the force on the body in a frame
|
|
Mth::Vector m_force;
|
|
|
|
// accumulates the torque on the body in a frame
|
|
Mth::Vector m_torque;
|
|
|
|
// length of current frame
|
|
float m_time_step;
|
|
|
|
// constant characteristics
|
|
|
|
// vehicle's center of mass
|
|
Mth::Vector m_suspension_center_of_mass;
|
|
|
|
// inverse mass (1 / lb)
|
|
float m_inv_mass;
|
|
|
|
// inverse moment of inertia in vehicle's frame (1 / lb / in^2)
|
|
Mth::Vector m_inv_moment_body;
|
|
|
|
// coefficient of restitution of the body
|
|
float m_body_restitution;
|
|
|
|
// coefficient of friction of the body
|
|
float m_body_friction;
|
|
|
|
// spring constant of the collision penalty system
|
|
float m_body_spring;
|
|
|
|
// coefficient of friction of the body used when the vehicle is not upright
|
|
float m_body_wipeout_friction;
|
|
|
|
// factor of normal collision impulse which you can control via your steering
|
|
float m_collision_control;
|
|
|
|
// horizontal velocity cutoff below which no in-air slerping to face velocity occurs
|
|
float m_in_air_slerp_vel_cutoff;
|
|
|
|
// time over which in-air slerping lerps to full strength after takeoff
|
|
float m_in_air_slerp_time_delay;
|
|
|
|
// in-air slerping strength
|
|
float m_in_air_slerp_strength;
|
|
|
|
// special slerping at low speeds
|
|
bool m_vert_correction;
|
|
|
|
// number of wheels
|
|
unsigned int m_num_wheels;
|
|
|
|
// number of drive wheels; engine torque is divided between this number of wheels
|
|
unsigned int m_num_drive_wheels;
|
|
|
|
// maximum steering angle
|
|
float m_max_steering_angle;
|
|
|
|
// effective distance between fixed and steering axles (in); used when determining turning radius
|
|
float m_cornering_wheelbase;
|
|
|
|
// distance between center of steering wheels (in); used when determining steering angles
|
|
float m_cornering_axle_length;
|
|
|
|
// constant and quadratic rotational damp coefficients
|
|
float m_const_rotvel_damping;
|
|
float m_quad_rotvel_damping;
|
|
|
|
// vehicles have rectangular feelers which they use to detect collisions with their environment
|
|
SCollider mp_colliders[vVP_NUM_COLLIDERS];
|
|
|
|
// offset from the vehicle's center of mass the model's origin
|
|
// float m_body_model_offset;
|
|
|
|
// body model's position
|
|
Mth::Vector m_body_pos;
|
|
|
|
// if true, triangle acts as a brake and throws an ExitCar exception when the car stops
|
|
bool m_exitable;
|
|
|
|
// if true, the car has no handbrake
|
|
bool m_no_handbrake;
|
|
|
|
// subelements
|
|
|
|
// wheels
|
|
SWheel* mp_wheels;
|
|
|
|
// engine
|
|
SEngine m_engine;
|
|
|
|
// input state
|
|
SControls m_controls;
|
|
|
|
// collision cache
|
|
Nx::CCollCache m_collision_cache;
|
|
|
|
// parameters controlling skater while vehicle is active
|
|
|
|
// true if the skater should be visible while in the vehicle
|
|
bool m_skater_visible;
|
|
|
|
// position offset of skater model
|
|
Mth::Vector m_skater_pos;
|
|
|
|
// skater animation to use while in the vehicle
|
|
uint32 m_skater_anim;
|
|
|
|
// controls the steering used for the displayed wheels and driving animation; lerps to m_controls.steering
|
|
float m_steering_display;
|
|
|
|
// name of the sound setup structure from PlayerVehicleSounds that which vehicle uses
|
|
uint32 m_sound_setup_checksum;
|
|
|
|
// dynamic script-controllable parameters
|
|
|
|
// the effective gravity can be modified via script; graviy is multiplied by m_gravity_fraction over a duration of m_gravity_override_timer
|
|
float m_gravity_override_fraction;
|
|
float m_gravity_override_timer;
|
|
|
|
// if true, the brakes are forced to be on
|
|
bool m_force_brake;
|
|
|
|
// state observers
|
|
|
|
// time since we last had a wheel on the ground (plus no body contact)
|
|
float m_air_time;
|
|
float m_air_time_no_collision;
|
|
|
|
// latest updates maximum normal collision impulse
|
|
float m_max_normal_collision_impulse;
|
|
|
|
// peer components
|
|
|
|
CSkeletonComponent* mp_skeleton_component;
|
|
CInputComponent* mp_input_component;
|
|
CModelComponent* mp_model_component;
|
|
|
|
// shared objects
|
|
|
|
// shared collision point array
|
|
static SCollisionPoint sp_collision_points[4 * (Nx::MAX_NUM_2D_COLLISIONS_REPORTED + 1)];
|
|
|
|
// debug
|
|
int m_draw_debug_lines;
|
|
|
|
// if true, no collision detection is done and the skeleton is not updated; this is used to allow a car to settle on its suspension "off camera"
|
|
bool m_update_suspension_only;
|
|
|
|
// the driver
|
|
CCompositeObject* mp_skater;
|
|
CAnimationComponent* mp_skater_animation_component;
|
|
CSkaterCorePhysicsComponent* mp_skater_core_physics_component;
|
|
CTriggerComponent* mp_skater_trigger_component;
|
|
};
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline bool CVehicleComponent::IsOnGround ( ) const
|
|
{
|
|
return m_num_wheels_in_contact > 0;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline uint32 CVehicleComponent::GetSoundSetupChecksum ( ) const
|
|
{
|
|
return m_sound_setup_checksum;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline void CVehicleComponent::update_velocities ( )
|
|
{
|
|
m_vel = m_inv_mass * m_mom;
|
|
|
|
// Zero the W component here to avoid possible NaN propogation issues.
|
|
m_vel[W] = 0.0f;
|
|
m_rotvel = m_inv_moment.Rotate(m_rotmom);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline Mth::Vector CVehicleComponent::calculate_body_point_velocity ( const Mth::Vector& pos ) const
|
|
{
|
|
return m_vel + Mth::CrossProduct(m_rotvel, pos);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline void CVehicleComponent::accumulate_force ( const Mth::Vector& force, const Mth::Vector& location, uint32 color )
|
|
{
|
|
m_force += force;
|
|
m_torque += Mth::CrossProduct(location - m_suspension_center_of_mass_world, force);
|
|
|
|
#if 0
|
|
if (m_draw_debug_lines)
|
|
{
|
|
Mth::Vector adjusted_location = location;
|
|
adjusted_location[Y] += 1.0f; // pull out of the ground
|
|
Gfx::AddDebugLine(m_pos + adjusted_location, m_pos + adjusted_location + 0.05f * force, color, color, 1);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline void CVehicleComponent::accumulate_collision_force ( const Mth::Vector& force, const Mth::Vector& location )
|
|
{
|
|
m_force += force;
|
|
m_torque += Mth::CrossProduct(location, force);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline void CVehicleComponent::apply_wheel_torque ( SWheel& wheel, float torque )
|
|
{
|
|
float rotacc = wheel.inv_moment * torque;
|
|
|
|
wheel.rotvel += rotacc * m_time_step;
|
|
|
|
wheel.rotacc += rotacc;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline float CVehicleComponent::calculate_stopping_torque ( const SWheel& wheel, float rotvel ) const
|
|
{
|
|
return -rotvel / (m_time_step * wheel.inv_moment);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline float CVehicleComponent::calculate_collision_depth ( const CLineFeeler& line_feeler ) const
|
|
{
|
|
return (1.0f - line_feeler.GetDist()) * Mth::DotProduct(line_feeler.GetNormal(), line_feeler.m_start - line_feeler.m_end);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline void CVehicleComponent::apply_impulse ( const Mth::Vector& impulse, const Mth::Vector& location )
|
|
{
|
|
m_mom += impulse;
|
|
m_rotmom += Mth::CrossProduct(location, impulse);
|
|
|
|
update_velocities();
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline bool CVehicleComponent::very_close ( const Mth::Vector p, const Mth::Vector q ) const
|
|
{
|
|
return Mth::Abs(p[X] - q[X]) < 0.1f && Mth::Abs(p[Y] - q[Y]) < 0.1f && Mth::Abs(p[Z] - q[Z]) < 0.1f;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline bool CVehicleComponent::reset_this_frame ( ) const
|
|
{
|
|
return m_reset_this_frame || GetObject()->IsDead();
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline void CVehicleComponent::trip_trigger ( ESkaterTriggerType trigger_type, CLineFeeler &feeler )
|
|
{
|
|
mp_skater_trigger_component->CheckFeelerForTrigger(trigger_type, feeler);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline void CVehicleComponent::trip_trigger ( ESkaterTriggerType trigger_type, CRectFeeler &feeler )
|
|
{
|
|
mp_skater_trigger_component->CheckFeelerForTrigger(trigger_type, feeler);
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* */
|
|
/* */
|
|
/******************************************************************/
|
|
|
|
inline bool CVehicleComponent::in_artificial_collision ( )
|
|
{
|
|
return m_artificial_collision_timer > 0.0f;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|