//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef CONVERT_H #define CONVERT_H #pragma once #include "mathlib/vector.h" #include "mathlib/mathlib.h" #include "ivp_physics.hxx" struct cplane_t; #include "vphysics_interface.h" // UNDONE: Remove all conversion/scaling // Convert our units (inches) to IVP units (meters) struct vphysics_units_t { float unitScaleMeters; // factor that converts game units to meters float unitScaleMetersInv; // factor that converts meters to game units float globalCollisionTolerance; // global collision tolerance in game units float collisionSweepEpsilon; // collision sweep tests clip at this, must be the same as engine's DIST_EPSILON float collisionSweepIncrementalEpsilon; // near-zero test for incremental steps in collision sweep tests }; extern vphysics_units_t g_PhysicsUnits; #define HL2IVP_FACTOR g_PhysicsUnits.unitScaleMeters #define IVP2HL(x) (float)(x * (g_PhysicsUnits.unitScaleMetersInv)) #define HL2IVP(x) (double)(x * HL2IVP_FACTOR) // Convert HL engine units to IVP units inline void ConvertPositionToIVP( const Vector &in, IVP_U_Float_Point &out ) { float tmpZ; tmpZ = in[1]; out.k[0] = HL2IVP(in[0]); out.k[1] = -HL2IVP(in[2]); out.k[2] = HL2IVP(tmpZ); } inline void ConvertPositionToIVP( const Vector &in, IVP_U_Point &out ) { float tmpZ; tmpZ = in[1]; out.k[0] = HL2IVP(in[0]); out.k[1] = -HL2IVP(in[2]); out.k[2] = HL2IVP(tmpZ); } inline void ConvertPositionToIVP( const Vector &in, IVP_U_Float_Point3 &out ) { float tmpZ; tmpZ = in[1]; out.k[0] = HL2IVP(in[0]); out.k[1] = -HL2IVP(in[2]); out.k[2] = HL2IVP(tmpZ); } inline void ConvertPositionToIVP( float &x, float &y, float &z ) { float tmpZ; tmpZ = y; y = -HL2IVP(z); z = HL2IVP(tmpZ); x = HL2IVP(x); } inline void ConvertDirectionToIVP( const Vector &in, IVP_U_Float_Point &out ) { float tmpZ; tmpZ = in[1]; out.k[0] = in[0]; out.k[1] = -in[2]; out.k[2] = tmpZ; } inline void ConvertDirectionToIVP( const Vector &in, IVP_U_Point &out ) { float tmpZ; tmpZ = in[1]; out.k[0] = in[0]; out.k[1] = -in[2]; out.k[2] = tmpZ; } // forces are handled the same as positions & velocities (scaled by distance conversion factor) #define ConvertForceImpulseToIVP ConvertPositionToIVP #define ConvertForceImpulseToHL ConvertPositionToHL inline float ConvertAngleToIVP( float angleIn ) { return DEG2RAD(angleIn); } inline void ConvertAngularImpulseToIVP( const AngularImpulse &in, IVP_U_Float_Point &out ) { float tmpZ; tmpZ = in[1]; out.k[0] = DEG2RAD(in[0]); out.k[1] = -DEG2RAD(in[2]); out.k[2] = DEG2RAD(tmpZ); } inline float ConvertDistanceToIVP( float distance ) { return HL2IVP( distance ); } inline void ConvertPlaneToIVP( const Vector &pNormal, float dist, IVP_U_Hesse &plane ) { ConvertDirectionToIVP( pNormal, (IVP_U_Point &)plane ); // HL stores planes as Ax + By + Cz = D // IVP stores them as Ax + BY + Cz + D = 0 plane.hesse_val = -ConvertDistanceToIVP( dist ); } inline void ConvertPlaneToIVP( const Vector &pNormal, float dist, IVP_U_Float_Hesse &plane ) { ConvertDirectionToIVP( pNormal, (IVP_U_Float_Point &)plane ); // HL stores planes as Ax + By + Cz = D // IVP stores them as Ax + BY + Cz + D = 0 plane.hesse_val = -ConvertDistanceToIVP( dist ); } inline float ConvertDensityToIVP( float density ) { return density; } // in convert.cpp extern void ConvertMatrixToIVP( const matrix3x4_t& matrix, IVP_U_Matrix &out ); extern void ConvertRotationToIVP( const QAngle &angles, IVP_U_Matrix3 &out ); extern void ConvertRotationToIVP( const QAngle& angles, IVP_U_Quat &out ); extern void ConvertBoxToIVP( const Vector &mins, const Vector &maxs, Vector &outmins, Vector &outmaxs ); extern int ConvertCoordinateAxisToIVP( int axisIndex ); extern int ConvertCoordinateAxisToHL( int axisIndex ); // IVP to HL conversions inline void ConvertPositionToHL( const IVP_U_Point &point, Vector& out ) { float tmpY = IVP2HL(point.k[2]); out[2] = -IVP2HL(point.k[1]); out[1] = tmpY; out[0] = IVP2HL(point.k[0]); } inline void ConvertPositionToHL( const IVP_U_Float_Point &point, Vector& out ) { float tmpY = IVP2HL(point.k[2]); out[2] = -IVP2HL(point.k[1]); out[1] = tmpY; out[0] = IVP2HL(point.k[0]); } inline void ConvertPositionToHL( const IVP_U_Float_Point3 &point, Vector& out ) { float tmpY = IVP2HL(point.k[2]); out[2] = -IVP2HL(point.k[1]); out[1] = tmpY; out[0] = IVP2HL(point.k[0]); } inline void ConvertDirectionToHL( const IVP_U_Point &point, Vector& out ) { float tmpY = point.k[2]; out[2] = -point.k[1]; out[1] = tmpY; out[0] = point.k[0]; } inline void ConvertDirectionToHL( const IVP_U_Float_Point &point, Vector& out ) { float tmpY = point.k[2]; out[2] = -point.k[1]; out[1] = tmpY; out[0] = point.k[0]; } inline float ConvertAngleToHL( float angleIn ) { return RAD2DEG(angleIn); } inline void ConvertAngularImpulseToHL( const IVP_U_Float_Point &point, AngularImpulse &out ) { float tmpY = point.k[2]; out[2] = -RAD2DEG(point.k[1]); out[1] = RAD2DEG(tmpY); out[0] = RAD2DEG(point.k[0]); } inline float ConvertDistanceToHL( float distance ) { return IVP2HL( distance ); } // NOTE: Converts in place inline void ConvertPlaneToHL( cplane_t &plane ) { IVP_U_Float_Hesse tmp(plane.normal.x, plane.normal.y, plane.normal.z, -plane.dist); ConvertDirectionToHL( (IVP_U_Float_Point &)tmp, plane.normal ); // HL stores planes as Ax + By + Cz = D // IVP stores them as Ax + BY + Cz + D = 0 plane.dist = -ConvertDistanceToHL( tmp.hesse_val ); } inline void ConvertPlaneToHL( const IVP_U_Float_Hesse &plane, Vector *pNormalOut, float *pDistOut ) { if ( pNormalOut ) { ConvertDirectionToHL( plane, *pNormalOut ); } // HL stores planes as Ax + By + Cz = D // IVP stores them as Ax + BY + Cz + D = 0 if ( pDistOut ) { *pDistOut = -ConvertDistanceToHL( plane.hesse_val ); } } inline float ConvertVolumeToHL( float volume ) { float factor = IVP2HL(1.0); factor = (factor * factor * factor); return factor * volume; } #define INSQR_PER_METERSQR (1.f / (METERS_PER_INCH*METERS_PER_INCH)) inline float ConvertEnergyToHL( float energy ) { return energy * INSQR_PER_METERSQR; } inline void IVP_Float_PointAbs( IVP_U_Float_Point &out, const IVP_U_Float_Point &in ) { out.k[0] = fabsf( in.k[0] ); out.k[1] = fabsf( in.k[1] ); out.k[2] = fabsf( in.k[2] ); } // convert.cpp extern void ConvertRotationToHL( const IVP_U_Matrix3 &in, QAngle &angles ); extern void ConvertMatrixToHL( const IVP_U_Matrix &in, matrix3x4_t& output ); extern void ConvertRotationToHL( const IVP_U_Quat &in, QAngle& angles ); extern void TransformIVPToLocal( IVP_U_Point &pointInOut, IVP_Real_Object *pObject, bool translate ); extern void TransformLocalToIVP( IVP_U_Point &pointInOut, IVP_Real_Object *pObject, bool translate ); extern void TransformIVPToLocal( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate ); extern void TransformLocalToIVP( const IVP_U_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate ); extern void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Point &pointOut, IVP_Real_Object *pObject, bool translate ); extern void TransformLocalToIVP( const IVP_U_Float_Point &pointIn, IVP_U_Float_Point &pointOut, IVP_Real_Object *pObject, bool translate ); #endif // CONVERT_H