This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

180
public/rubikon/constants.h Normal file
View File

@@ -0,0 +1,180 @@
//========= Copyright <20> 1996-2012, Valve Corporation, All rights reserved. ============//
#ifndef CONSTANTS_HDR
#define CONSTANTS_HDR
#include "tier0/basetypes.h"
#include "resourcefile/resourcestream.h"
//! Global tuning constants based on meter-kilogram-seconds (MKS) units. Here adjusted
//! to inches for Source2 (1 inch ~ 2.5 cm <=> 1 cm ~ 0.4 inch <=> 1 m ~ 40 inch)
//---------------------------------------------------------------------------------------
// General
//---------------------------------------------------------------------------------------
//! A small distance used as collision detection and dynamics tolerance. It is chosen
//! to be numerically significant, but visually insignificant.
//! (This is 1/32 of an inch)
#define LINEAR_SLOP 0.03125f
//! A small angle used a collision detection and dynamics tolerance. It is chosen
//! to be numerically significant, but visually insignificant.
#define ANGULAR_SLOP (2.0f / 180.0f * M_PI)
//---------------------------------------------------------------------------------------
// Convex hulls
//---------------------------------------------------------------------------------------
//! The *desired* maximum number of vertices on a convex hull. The number of vertices is
//! chosen such that quadric shapes (e.g. cylinder and cones) can be approximated smoothly.
//! Do not change this value!
#define DESIRED_HULL_VERTICES 32
//! Maximum number of vertices supported at runtime on a convex hull.
//! Do not change this value!
#define MAX_HULL_VERTICES 256
//! Maximum number of half-edges supported at runtime on a convex hull.
//! Do not change this value!
#define MAX_HULL_HALFEDGES 256
//! Maximum number of faces supported at runtime on a convex hull.
//! Do not change this value!
#define MAX_HULL_FACES 256
//! The relative weld tolerance when pre-processing hull vertices.
//! This value is dimensionless!
#define RELATIVE_WELD_TOLERANCE 0.01f
//---------------------------------------------------------------------------------------
// Broadphase
//---------------------------------------------------------------------------------------
//! The maximum stack depth for iterative tree traversals.
#define STACK_SIZE 64
//! Constant to indicate an invalid proxy identifier
#define NULL_PROXY -1
//! The initial node capacity of the dynamic tree
#define INITIAL_NODE_CAPACITY 32
//! This is used to fatten AABBs in the dynamic tree. This allows proxies
//! to move by a small amount without triggering a tree adjustment.
//! (This is 0.1 [m] in MKS)
#define BOUNDS_EXTENSION 4.0f
//! This is used to fatten AABBs in the dynamic tree. This is used to predict
//! the future position based on the current displacement.
//! (This is a dimensionless multiplier)
#define BOUNDS_MULTIPLIER 2.0f
//---------------------------------------------------------------------------------------
// Collision
//---------------------------------------------------------------------------------------
//! The maximum number of contact points between two touching shapes. Do not change this value!
#define MAX_CONTACT_POINTS 4
//! The number of buckets used in the mesh SAH builder
#define SAH_BUILDER_BUCKET_COUNT 32
//! The desired number of triangles in a leaf node of the mesh BVH
#define DESIRED_TRIANGLES_PER_LEAF 4
//! The maximum number of triangles in a leaf node of the mesh BVH
#define MAXIMUM_TRIANGLES_PER_LEAF 8
//! The maximum number of iteration of the TOI root finder
#define MAX_ROOT_FINDER_ITERATIONS 64
//! The radius of the hull/mesh shape skin. This should not be modified. Making
//! this smaller means polytopes will have an insufficient buffer for continuous
//! collision. Making it larger may create artifacts for vertex collision.
#define CONVEX_RADIUS (2.0f * LINEAR_SLOP)
//! The maximum number of sub-steps per contact in a continuous physics simulation.
#define MAX_SUBSTEPS 4
//---------------------------------------------------------------------------------------
// Dynamics
//---------------------------------------------------------------------------------------
//! Define default solver position iterations.
#define DEFAULT_POSITION_ITERATIONS 2
//! Define default solver velocity iterations.
#define DEFAULT_VELOCITY_ITERATIONS 8
//! Define default gravity.
//! (This is 9 [m/s^2] in MKS)
#define DEFAULT_GRAVITY 360.0f
//! Default air density, taken from CDragController
#define DEFAULT_AIR_DENSITY 2.0f;
//! The maximum linear velocity of a body. This limit is very large and is used
//! to prevent numerical problems. You shouldn't need to adjust this.
#define MAX_TRANSLATION 80.0f
//! The maximum angular velocity of a body. This limit is very large and is used
//! to prevent numerical problems. You shouldn't need to adjust this.
#define MAX_ROTATION (0.25f * M_PI)
//! A velocity threshold for elastic collisions. Any collision with a relative linear
//! velocity below this threshold will be treated as inelastic.
//! (This is 1 [m/s] in MKS)
#define VELOCITY_THRESHOLD 40.0f
//! The maximum linear position correction used when solving constraints. This helps to
//! prevent overshoot.
//! (This is 0.2 [m] in MKS)
#define MAX_LINEAR_CORRECTION 8.0f
//! The maximum angular position correction used when solving constraints. This helps to
//! prevent overshoot.
#define MAX_ANGULAR_CORRECTION (8.0f / 180.0f * M_PI)
//! A Baumgarte like factor when using projection for constraint stabilization. This only
//! effects contacts and limits. We want to avoid overshooting so this value should be in
//! range 0.1 - 0.2. Overshooting can result in loosing contacts and warm-starting information
//! which has a bunch of negative side effects (e.g. jitter and bad friction).
//! (This is a dimensionless multiplier)
#define TOI_BAUMGARTE 0.75f
#define POSITION_BAUMGARTE 0.2f
//! Factor when using Baumgarte stabilization to stabilize velocity constraints. This will
//! effect all joints and add momentum when enabled.
//! (This is a dimensionless multiplier)
#define VELOCITY_BAUMGARTE 0.1f
//---------------------------------------------------------------------------------------
// Sleeping
//---------------------------------------------------------------------------------------
//! The time in seconds that a body must be still before it will go to sleep.
#define TIME_TO_SLEEP 0.5f
//! A body cannot sleep if its linear velocity is above this tolerance.
//! (This is 0.01 [m/s] in MKS)
#define LINEAR_SLEEP_TOLERANCE 0.4f
//! A body cannot sleep if its angular velocity is above this tolerance.
#define ANGULAR_SLEEP_TOLERANCE (2.0f / 180.0f * M_PI)
//---------------------------------------------------------------------------------------
// Default joint parameter
//---------------------------------------------------------------------------------------
#define DEFAULT_JOINT_CFM float( 0.0f )
#define DEFAULT_JOINT_ERP float( 0.1f )
// dummy schema data: workaround for a build dependency issue
schema struct RnDummy_t
{
int32 m_nDummy;
};
#endif

View File

@@ -0,0 +1,87 @@
//========= Copyright <20> Valve Corporation, All rights reserved. ============//
#ifndef RNDEBUGNAME_HDR
#define RNDEBUGNAME_HDR
#ifdef _DEBUG
#define RUBIKON_DEBUG_NAMES 1
#else
#define RUBIKON_DEBUG_NAMES 0
#endif
class CRnDebugName
{
public:
CRnDebugName() { Init( ); }
~CRnDebugName();
public:
void SetV( const char* pNameFormat, va_list args );
const char *Get() const;
const char *GetSafe( ) const; // return either name or "", but not NULL
void Init();
public:
#if RUBIKON_DEBUG_NAMES
char *m_pName; // please keep the name at the top if possible: it's much easier to debug in VS that way
#endif
};
inline void CRnDebugName::Init()
{
#if RUBIKON_DEBUG_NAMES
m_pName = NULL;
#endif
}
inline CRnDebugName::~CRnDebugName()
{
#if RUBIKON_DEBUG_NAMES
if( m_pName )
{
delete[]m_pName;
}
#endif
}
//---------------------------------------------------------------------------------------
inline void CRnDebugName::SetV( const char *pNameFormat, va_list args )
{
#if RUBIKON_DEBUG_NAMES
if( m_pName )
{
delete[]m_pName;
m_pName = NULL;
}
if( pNameFormat )
{
CReuseVaList dup_args( args );
int nLen = vsnprintf( NULL, 0, pNameFormat, dup_args.m_ReuseList );
if( nLen > 0 )
{
m_pName = new char[nLen + 2];
m_pName[nLen] = '\xFF';
m_pName[nLen + 1] = '\xFF';
vsnprintf( m_pName, nLen + 1, pNameFormat, args );
AssertDbg( m_pName[nLen + 1] == '\xFF' && m_pName[nLen] == '\0' );
}
}
#endif
}
inline const char *CRnDebugName::Get() const
{
#if RUBIKON_DEBUG_NAMES
return m_pName;
#else
return NULL;
#endif
}
inline const char *CRnDebugName::GetSafe() const
{
const char *p = Get( );
return p ? p : "";
}
#endif

View File

@@ -0,0 +1,188 @@
//========= Copyright <20> Valve Corporation, All rights reserved. ============//
#ifndef RUBIKON_INTERSECTION_ATTRIBUTES_HDR
#define RUBIKON_INTERSECTION_ATTRIBUTES_HDR
static const uint32 INTERSECTION_ENTITY_ID_NONE = 0xFFFFFFFF;
enum BuiltInCollisionGroup_t
{
// Default layer, always collides with everything.
COLLISION_GROUP_ALWAYS = 0, // "always"
// This is how you turn off all collisions for an object - move it to this group
COLLISION_GROUP_NONPHYSICAL = 1, // "never"
// Trigger layer, never collides with anything, only triggers/interacts. Use when querying for interaction layers.
COLLISION_GROUP_TRIGGER = 2, // "trigger"
// Conditionally solid means that the collision response will be zero or as defined in the table when there are matching interactions
COLLISION_GROUP_CONDITIONALLY_SOLID = 3, // needs interactions
// First unreserved collision layer index.
COLLISION_GROUP_FIRST_USER = 4,
// Hard limit of 254 due to memory layout, and these are never visible to scene queries.
COLLISION_GROUPS_MAX_ALLOWED = 64,
};
enum BuiltInInteractionLayer_t
{
// Slow path for generating interactions when INTERSECTION_INTERACTION_LAYER_MAX is hit.
// Set by default on every m_interactsAs, but not any m_interactsWith.
INTERACTION_LAYER_ALWAYS = 0, // "always"
// Indicates that the query will have to recurse into a hitbox model.
INTERACTION_LAYER_HITBOXES = 1,
// Might as well hard-code "trigger" as generic interaction layer. Character Controllers add it by default.
INTERACTION_LAYER_TRIGGER = 2,
// First unreserved interaction layer index.
INTERACTION_LAYER_SKY = 3,
INTERACTION_LAYER_FIRST_USER = 4,
INTERACTION_LAYER_NOT_FOUND = -1,
// Number of scene query interaction layers limited by storing these in a 64-bit uint mask
INTERACTION_LAYERS_MAX_ALLOWED = 64,
};
enum IntersectionPairFlags_t
{
INTERSECTION_PAIR_RESOLVE_CONTACTS = (1<<0),
INTERSECTION_PAIR_NOTIFY_TOUCH_FOUND = (1<<2),
INTERSECTION_PAIR_NOTIFY_TOUCH_PERSISTS = (1<<3),
INTERSECTION_PAIR_NOTIFY_TOUCH_LOST = (1<<4),
INTERSECTION_PAIR_TRIGGER = INTERSECTION_PAIR_NOTIFY_TOUCH_FOUND | INTERSECTION_PAIR_NOTIFY_TOUCH_LOST,
INTERSECTION_PAIR_DEFAULT_COLLISION = INTERSECTION_PAIR_RESOLVE_CONTACTS,
INTERSECTION_NOTIFICATION_ANY = INTERSECTION_PAIR_NOTIFY_TOUCH_FOUND | INTERSECTION_PAIR_NOTIFY_TOUCH_PERSISTS | INTERSECTION_PAIR_NOTIFY_TOUCH_LOST
};
enum IntersectionQueryResult_t
{
INTERSECTION_QUERY_RESULT_FLAGS_NONE = 0,
INTERSECTION_QUERY_RESULT_FLAGS_BLOCK = 1,
};
enum CollisionFunctionMask_t
{
FCOLLISION_FUNC_ENABLE_SOLID_CONTACT = 1<<0,
FCOLLISION_FUNC_ENABLE_TRACE_QUERY = 1<<1,
FCOLLISION_FUNC_ENABLE_TOUCH_EVENT = 1<<2,
FCOLLISION_FUNC_ENABLE_SHOULD_COLLIDE_CALLBACK = 1<<3,
FCOLLISION_FUNC_IGNORE_FOR_HITBOX_TEST = 1<<4,
};
enum RnMassPriorityEnum_t
{
MASS_PRIORITY_DEFAULT = 0,
MASS_PRIORITY_TRIGGER = -1 // triggers never have mass that affects other physics objects
};
// Volume queries: Let's you decide between broadphase proxy and shape overlaps
enum OverlapTest_t
{
OVERLAP_TEST_PROXY, // This will only test the shapes broadphase proxy and not the shape itself
OVERLAP_TEST_SHAPE // This will first find all overlapping proxies inside the broadphase and then test the actual shape for overlap
};
// these are on by default
#define FCOLLISION_FUNC_DEFAULT (FCOLLISION_FUNC_ENABLE_SOLID_CONTACT | FCOLLISION_FUNC_ENABLE_TRACE_QUERY | FCOLLISION_FUNC_ENABLE_TOUCH_EVENT)
extern CUtlString IntersectionPairFlagsToString( uint16 nPairFlags );
// TODO: Currently these flags are stored in a table as 16-bits per-pair. Once we have
// TODO: identified the desired permutations of flags, the per-pair data will be
// TODO: palletized down to a 4-bit index into a lookup table.
// ==================================================================================================
typedef int32 IntersectionLayerIndex;
typedef int32 CollisionGroupIndex;
typedef uint16 IntersectionLayerPairFlags;
typedef uint16 CollisionGroupPairFlags;
struct RnCollisionAttr_t
{
public:
//uintp m_nOwner;
// Which interaction layers do I represent? (e.g. I am a INTERACTION_LAYER_PLAYERCLIP volume)
// NOTE: This is analogous to "contents" in source 1 (bit mask of CONTENTS_* or 1<<INTERACTION_LAYER_*)
uint64 m_nInteractsAs;
// Which interaction layers do I interact or collide with? (e.g. I collide with INTERACTION_LAYER_PASSBULLETS because I am not a bullet)
// NOTE: This is analogous to the "solid mask" or "trace mask" in source 1 (bit mask of CONTENTS_* or 1<<INTERACTION_LAYER_*)
uint64 m_nInteractsWith;
// Which interaction layers do I _not_ interact or collide with? If my exclusion layers match m_nInteractsAs on the other object then no interaction happens.
uint64 m_nInteractsExclude;
uint32 m_nEntityId; // this is the ID of the game entity
uint16 m_nHierarchyId; // this is an ID for the hierarchy of game entities (used to disable collision among objects in a hierarchy)
uint8 m_nCollisionGroup; // one of the registered collision groups
uint8 m_nCollisionFunctionMask; // set of CollisionFunctionMask_t bits
public:
inline RnCollisionAttr_t()
{
m_nInteractsAs = 0; //1 << INTERACTION_LAYER_ALWAYS;
m_nInteractsWith = 0;
m_nInteractsExclude = 0;
m_nCollisionGroup = COLLISION_GROUP_ALWAYS;
m_nCollisionFunctionMask = FCOLLISION_FUNC_DEFAULT;
m_nEntityId = 0;
m_nHierarchyId = 0;
}
uint64 GetUsedLayerMask() const { return m_nInteractsAs | m_nInteractsWith | m_nInteractsExclude; }
uint64 GetUsedGroupMask() const { return 1ull << m_nCollisionGroup; }
uint8 GetCollisionFunctionMask() const { return m_nCollisionFunctionMask; }
void SetCollisionFunctionMask( uint8 nCollisionFunctionMask ) { m_nCollisionFunctionMask = nCollisionFunctionMask; }
inline bool AddCollisionFunctionMask( uint8 nAddMask );
inline bool RemoveCollisionFunctionMask( uint8 nRemoveMask );
inline void SetCollisionGroup( int nGroup ) { m_nCollisionGroup = nGroup; }
bool IsSolidContactEnabled() const { return (GetCollisionFunctionMask() & FCOLLISION_FUNC_ENABLE_SOLID_CONTACT) != 0; }
bool IsTraceAndQueryEnabled() const { return (GetCollisionFunctionMask() & FCOLLISION_FUNC_ENABLE_TRACE_QUERY) != 0; }
bool IsTouchEventEnabled() const { return (GetCollisionFunctionMask() & FCOLLISION_FUNC_ENABLE_TOUCH_EVENT) != 0; }
bool IsShouldCollideCallbackEnabled() const { return (GetCollisionFunctionMask() & FCOLLISION_FUNC_ENABLE_SHOULD_COLLIDE_CALLBACK) != 0; }
bool ShouldIgnoreForHitboxTest() const { return (GetCollisionFunctionMask() & FCOLLISION_FUNC_IGNORE_FOR_HITBOX_TEST) != 0; }
inline bool HasInteractsAsLayer( int nLayerIndex ) const { return ( m_nInteractsAs & ( 1ull << nLayerIndex ) ) != 0; }
inline bool HasInteractsWithLayer( int nLayerIndex ) const { return ( m_nInteractsWith & ( 1ull << nLayerIndex ) ) != 0; }
inline bool HasInteractsExcludeLayer( int nLayerIndex ) const { return ( m_nInteractsExclude & ( 1ull << nLayerIndex ) ) != 0; }
inline void EnableInteractsAsLayer( int nLayer ) { m_nInteractsAs |= ( 1ull << nLayer ); }
inline void EnableInteractsWithLayer( int nLayer ) { m_nInteractsWith |= ( 1ull << nLayer ); }
inline void EnableInteractsExcludeLayer( int nLayer ) { m_nInteractsExclude |= ( 1ull << nLayer ); }
inline void DisableInteractsAsLayer( int nLayer ) { m_nInteractsAs &= ~( 1ull << nLayer ); }
inline void DisableInteractsWithLayer( int nLayer ) { m_nInteractsWith &= ~( 1ull << nLayer ); }
inline void DisableInteractsExcludeLayer( int nLayer ) { m_nInteractsExclude &= ~( 1ull << nLayer ); }
inline uint32 GetEntityId() const { return m_nEntityId; }
inline uint32 GetHierarchyId() const { return m_nHierarchyId; }
};
inline bool RnCollisionAttr_t::AddCollisionFunctionMask( uint8 nAddMask )
{
if ( (m_nCollisionFunctionMask & nAddMask) != nAddMask )
{
m_nCollisionFunctionMask |= nAddMask;
return true;
}
return false;
}
inline bool RnCollisionAttr_t::RemoveCollisionFunctionMask( uint8 nRemoveMask )
{
if ( (m_nCollisionFunctionMask & nRemoveMask) != 0 )
{
m_nCollisionFunctionMask &= ~nRemoveMask;
return true;
}
return false;
}
#endif

View File

@@ -0,0 +1,780 @@
//========= Copyright <20> Valve Corporation, All rights reserved. ============//
#ifndef VPHYSICS2_PARAM_TYPES
#define VPHYSICS2_PARAM_TYPES
#include "mathlib/mathlib.h"
#include "mathlib/eigen.h"
#include "tier1/utlvector.h"
#include "rubikon/serializehelpers.h"
#include "rubikon/constants.h"
#include "mathlib/transform.h"
struct RnMaterial_t;
#if _MSC_VER >= 1300 // msvc 7.1
#define RN_DEPRECATED __declspec( deprecated )
#pragma warning(1 : 4996) // deprecated warning
#else
#define RN_DEPRECATED
#endif
//-------------------------------------------------------------------------------------------------
// Angular velocity type
//-------------------------------------------------------------------------------------------------
enum AngularVelocityUnits_t
{
RAD_PER_SECOND,
DEG_PER_SECOND
};
//-------------------------------------------------------------------------------------------------
// Simulation type
//-------------------------------------------------------------------------------------------------
enum PhysicsSimulation_t
{
DISCRETE_SIM,
CONTINUOUS_SIM
};
//-------------------------------------------------------------------------------------------------
// Softbody simulation type
//-------------------------------------------------------------------------------------------------
enum PhysicsSoftbodySimulation_t
{
SOFTBODY_SIM_RELAXATION = 1 << 0,
SOFTBODY_SIM_CONJUGATE_GRADIENT = 1 << 1,
SOFTBODY_SIM_MULTIGRID = 1 << 2,
SOFTBODY_SIM_DIAGONAL_PRECONDITIONER = 1 << 3,
SOFTBODY_SIM_LINEARIZATION_GUARD = 1 << 4,
SOFTBODY_SIM_WARMSTART = 1 << 5,
SOFTBODY_SIM_TRIDIAGONAL_PRECONDITIONER = 1 << 6,
SOFTBODY_SIM_RELAXATION_PRECONDITIONER = 1 << 7,
SOFTBODY_SIM_BOXERMAN_DAMPING = 1 << 8,
SOFTBODY_SIM_EXPERIMENTAL_1 = 1 << 24,
SOFTBODY_SIM_EXPERIMENTAL_2 = 1 << 25,
SOFTBODY_SIM_EXPERIMENTAL_3 = 1 << 26,
SOFTBODY_SIM_EXPERIMENTAL_4 = 1 << 27
};
enum PhysicsSoftbodyDebugDrawFlags_t
{
SOFTBODY_DEBUG_DRAW_TREE_BOTTOM_UP = 1 << 0,
SOFTBODY_DEBUG_DRAW_TREE_TOP_DOWN = 1 << 1,
SOFTBODY_DEBUG_DRAW_TREE_CLUSTERS = 1 << 2
};
enum PhysicsSoftbodyAnimSpace_t
{
SOFTBODY_ANIM_SPACE_WORLD,
SOFTBODY_ANIM_SPACE_LOCAL
};
enum PhysicsSoftbodySimTransformsFlags_t
{
SOFTBODY_SIM_TRANSFORMS_INCLUDE_STATIC = 1
};
enum PhysicsSoftbodyEnergyTypeEnum_t
{
SOFTBODY_ENERGY_ELASTIC,
SOFTBODY_ENERGY_KINEMATIC,
SOFTBODY_ENERGY_POTENTIAL,
SOFTBODY_ENERGY_TOTAL,
SOFTBODY_ENERGY_COUNT
};
//-------------------------------------------------------------------------------------------------
// Stabilization type
//-------------------------------------------------------------------------------------------------
enum PhysicsStabilization_t
{
BAUMGARTE_STAB,
PROJECTION_STAB
};
//-------------------------------------------------------------------------------------------------
// Body type
//-------------------------------------------------------------------------------------------------
enum PhysicsBodyType_t
{
BODY_STATIC,
BODY_KEYFRAMED,
BODY_DYNAMIC,
BODY_TYPE_COUNT
};
enum RnContactType_t
{
CONTACT_CONVEX,
CONTACT_MESH,
CONTACT_TYPE_COUNT
};
//-------------------------------------------------------------------------------------------------
// Joint type
//-------------------------------------------------------------------------------------------------
enum PhysicsJointType_t
{
NULL_JOINT,
SPHERICAL_JOINT,
PRISMATIC_JOINT,
REVOLUTE_JOINT,
QUAT_ORTHOTWIST_JOINT,
MOUSE_JOINT,
WELD_JOINT,
SPRING,
PULLEY,
GEAR,
CONICAL_JOINT,
JOINT_COUNT,
INVALID_JOINT_TYPE = JOINT_COUNT
};
//-------------------------------------------------------------------------------------------------
// Joint state
//-------------------------------------------------------------------------------------------------
enum JointStateFlagsEnum_t
{
JOINT_STATE_DEACTIVATED = 1 << 0,
JOINT_STATE_COLLIDE = 1 << 1, // the joint does NOT collide if it's disabled, but it keeps this state in case it's re-enabled later
JOINT_STATE_LINEAR_CONSTRAINT_DISABLED = 1 << 2, // only angular constraint: linear constraint is not active and objects are free to translate (but not rotate) independently
JOINT_STATE_ANGULAR_CONSTRAINT_DISABLED = 1 << 3, // only linear constraint: angular constraints are not active and objects are free to rotate (but not translate) independently
JOINT_STATE_MOTOR_ENABLED = 1 << 4, // enable/disable motor
JOINT_STATE_LIMIT_ENABLED = 1 << 5 // enable/disable limit (we might need to distinguish between linear and angular limit if we add a cylindrical joint)
};
//-------------------------------------------------------------------------------------------------
// Limit state
//-------------------------------------------------------------------------------------------------
enum PhysicsLimitState_t
{
LIMIT_FREE,
LIMIT_AT_LOWER_LIMIT,
LIMIT_AT_UPPER_LIMIT,
LIMIT_AT_LIMIT
};
//-------------------------------------------------------------------------------------------------
// Range (e.g. used for defining limits)
//-------------------------------------------------------------------------------------------------
struct Range_t
{
float m_flMin;
float m_flMax;
Range_t( void ) { m_flMin = FLT_MAX; m_flMax = -FLT_MAX; }
Range_t( float flMin, float flMax ) { m_flMin = flMin; m_flMax = flMax; }
};
inline bool operator==( const Range_t& lhs, const Range_t& rhs )
{
return lhs.m_flMin == rhs.m_flMin && lhs.m_flMax == rhs.m_flMax;
}
inline bool operator!=( const Range_t& lhs, const Range_t& rhs )
{
return lhs.m_flMin != rhs.m_flMin || lhs.m_flMax != rhs.m_flMax;
}
//-------------------------------------------------------------------------------------------------
// Shape type
//-------------------------------------------------------------------------------------------------
enum PhysicsShapeType_t
{
SHAPE_SPHERE,
SHAPE_CAPSULE,
SHAPE_HULL,
SHAPE_MESH,
SHAPE_COUNT,
SHAPE_UNKNOWN
};
enum PhysicsPseudoShapeEnum_t
{
PSEUDO_SHAPE_BOX = SHAPE_COUNT,
PSEUDO_SHAPE_COMPOUND,
PSEUDO_SHAPE_NONE,
PSEUDO_SHAPE_COUNT
};
//-------------------------------------------------------------------------------------------------
// ShapeCastResult
//-------------------------------------------------------------------------------------------------
enum RnSelectStaticDynamic
{
SELECT_STATIC = 1,
SELECT_DYNAMIC = 2, // <sergiy> the "2" is for binary backwards-compatibility with PhysX, but I hope we'll switch to keyframed_only |dynamic_only combo later, it'd be more convenient for physics testbed
SELECT_KEYFRAMED_ONLY = 0x104, // select kinematic, but not dynamic
SELECT_DYNAMIC_ONLY = 0x108, // select dynamic, but not kinematic
SELECT_ALL = SELECT_STATIC | SELECT_DYNAMIC,
};
enum RnDebugLayers_t
{
RN_DRAW_STATIC_BODIES = 1 << 0, // Draw all shapes associated with a rigid body
RN_DRAW_KEYFRAMED_BODIES = 1 << 1, // Draw all shapes associated with a rigid body
RN_DRAW_DYNAMIC_BODIES = 1 << 2, // Draw all shapes associated with a rigid body
RN_DRAW_CONTACT_POINTS = 1 << 3, // Draw contact points and normals
RN_DRAW_CONTACT_MANIFOLDS = 1 << 4,
RN_DRAW_CONTACT_INDICES = 1 << 5,
RN_DRAW_CONTACTS = RN_DRAW_CONTACT_POINTS | RN_DRAW_CONTACT_MANIFOLDS | RN_DRAW_CONTACT_INDICES,
RN_DRAW_JOINTS = 1 << 6, // Draw joints and limits
RN_DRAW_PROXIES = 1 << 7, // Draw broadphase proxies associated with each shape
RN_DRAW_RECORDED_RAYCASTS = 1 << 8,
RN_DRAW_RECORDED_FORCES = 1 << 9,
RN_DRAW_INERTIA_BOXES = 1 << 10,
RN_DRAW_MESH_FACE_INDICES = 1 << 11,
RN_DRAW_MESH_VERTEX_INDICES = 1 << 12,
RN_DRAW_MESH_EDGE_INDICES = 1 << 13,
RN_DRAW_SOFTBODIES = 1 << 14,
RN_DRAW_SOFTBODY_INDICES = 1 << 15,
RN_DRAW_SOFTBODY_FIELDS = 1 << 16,
RN_DRAW_AWAKE_BODIES = 1 << 17,
RN_DRAW_RECORDED_CAPSULE_SWEEPS = 1 << 18, // Draw recorded capsule sweeps for character controller
RN_DRAW_RECORDED_COLLISION_RESULTS = 1 << 19, // Draw recorded contact planes for character controller
RN_DRAW_SOFTBODY_BASES = 1 << 20
};
enum RnSoftbodyDrawLayers_t
{
RN_SOFTBODY_DRAW_EDGES = 1 << 0,
RN_SOFTBODY_DRAW_POLYGONS = 1 << 1,
RN_SOFTBODY_DRAW_INDICES = 1 << 2,
RN_SOFTBODY_DRAW_FIELDS = 1 << 3,
RN_SOFTBODY_DRAW_BASES = 1 << 4,
RN_SOFTBODY_DRAW_WIND = 1 << 5
};
struct RnTreeStats_t
{
RnTreeStats_t( )
{
m_nNodeCount = 0;
m_nLeafCount = 0;
m_nTreeHeight = 0;
m_flLeafMetric = 0;
m_flNodeMetric = 0;
m_flRootMetric = 0;
}
float GetLeafFactor( ) const
{
return m_flRootMetric > 0 ? m_flLeafMetric / m_flRootMetric : 0;
}
float GetNodeFactor( ) const
{
return m_flRootMetric > 0 ? m_flNodeMetric / m_flRootMetric : 0;
}
uint m_nNodeCount;
uint m_nLeafCount;
uint m_nTreeHeight;
float m_flRootMetric;
float m_flLeafMetric;
float m_flNodeMetric;
};
//-------------------------------------------------------------------------------------------------
// Shape cast result
//-------------------------------------------------------------------------------------------------
struct CShapeCastResult
{
float m_flHitTime;
Vector m_vHitPoint;
Vector m_vHitNormal;
const RnMaterial_t *m_pMaterial;
bool m_bStartInSolid;
CShapeCastResult( void )
{
m_flHitTime = 1.0f;
m_vHitPoint = Vector( 0, 0, 0 );
m_vHitNormal = Vector( 0, 0, 0 );
m_bStartInSolid = false;
m_pMaterial = NULL;
}
bool DidHit( void )
{
return m_flHitTime < 1.0f;
}
};
//-------------------------------------------------------------------------------------------------
// Distance query
//-------------------------------------------------------------------------------------------------
struct RnDistanceQueryResult_t
{
float m_flDistance; //!< Distance between shapes (distance of zero means shapes are touching or penetrating)
Vector m_vPoint1; //!< Closest point on first shape
Vector m_vPoint2; //!< Closest point on second shape
bool Overlap() const
{
return m_flDistance == 0.0f;
}
Vector GetNormal() const
{
Vector vNormal = m_vPoint2 - m_vPoint1;
VectorNormalize( vNormal );
return vNormal;
}
};
#define MAX_SIMPLEX_VERTICES 4
struct RnSimplexCache_t
{
float m_flMetric;
int m_nVertexCount;
uint8 m_Vertices1[ MAX_SIMPLEX_VERTICES ];
uint8 m_Vertices2[ MAX_SIMPLEX_VERTICES ];
float m_Lambdas[ MAX_SIMPLEX_VERTICES ];
void Clear( void ) { m_nVertexCount = 0; }
bool IsEmpty( void ) const { return m_nVertexCount == 0; }
};
struct RnIteration_t
{
float m_flAlpha;
RnDistanceQueryResult_t m_Query;
RnSimplexCache_t m_Cache;
Vector m_vLocalVertexA1;
Vector m_vLocalVertexA2;
Vector m_vLocalVertexB1;
Vector m_vLocalVertexB2;
Vector m_vLocalAxis;
int m_nWitnessA;
int m_nWitnessB;
};
//-------------------------------------------------------------------------------------------------
// Shape material
//-------------------------------------------------------------------------------------------------
struct RnMaterial_t
{
RnMaterial_t()
{
}
// Default material (density of water in kg/inch^3)
RnMaterial_t( float flFriction, float flRestitution )
: m_flDensity( 0.015625f )
, m_flFriction( flFriction )
, m_flRestitution( flRestitution )
{
}
float m_flDensity;
float m_flFriction;
float m_flRestitution;
uintp m_pUserData AUTO_SERIALIZE_AS( CPhysSurfacePropertiesHandle );
};
//-------------------------------------------------------------------------------------------------
// This describes definitively the box position, orientation and size.
// Useful for testing, to pass around the box with inertia equivalent to a given non-box body
//-------------------------------------------------------------------------------------------------
struct PhysicsInertiaBox_t
{
Quaternion m_qOrientation; // global orientation (it's the principal axes orientation for an equivalent body)
Vector m_vCenter; // (center of mass of equivalent body)
Vector m_vSize; // the dimensions of the box is -m_vSize ... +m_vSize
Vector m_vInertiaTensor; // eigenvalues of inertia tensor
static PhysicsInertiaBox_t GetDefault( )
{
PhysicsInertiaBox_t ib;
ib.m_qOrientation = quat_identity;
ib.m_vCenter = vec3_origin;
ib.m_vSize = Vector( 1,1,1 );
ib.m_vInertiaTensor = Vector( 1,1,1 );
return ib;
}
};
//---------------------------------------------------------------------------------------
// Manifold
//---------------------------------------------------------------------------------------
struct ManifoldPoint_t
{
Vector m_vPosition; //! The contact point in world coordinates on the surface of shape1
Vector m_vLocalP1, m_vLocalP2; //! The contact point in local coordinates of shape1 and shape2
float m_flSeparation; //! The separation at the contact point. A negative value means that the shapes are penetrating.
float m_flImpulse; //! The non-penetration impulse applied by the solver at this contact point (must be greater or equal zero)
uint32 m_nID; //! A unique ID for this contact point to match it to the old manifold and find the last applied non-penetration impulse
};
struct Manifold_t
{
int m_nPointCount; //! The number of contact points in the manifold (can be zero to four)
ManifoldPoint_t m_Points[ MAX_CONTACT_POINTS ]; //! The current contact patch. All points lie in the same plane
Vector m_vCenter; //! The center of the current contact patch
Vector m_vNormal; //! The plane normal of current contact patch (points from shape1 towards shape2)
Vector m_vTangent1, m_vTangent2;
float m_flTangentImpulse1; //! The friction impulse applied by the solver in the direction of tangent1
float m_flTangentImpulse2; //! The friction impulse applied by the solver in the direction of tangent2
float m_flTwistImpulse; //! The torsional friction impulse applied by the solver in the direction of the normal
};
//---------------------------------------------------------------------------------------
// Swept transform
//---------------------------------------------------------------------------------------
struct RnSweptTransform_t
{
RnSweptTransform_t() {}
RnSweptTransform_t( const CTransform& xform1, const CTransform& xform2 )
: m_vPosition1( xform1.m_vPosition )
, m_vPosition2( xform2.m_vPosition )
, m_qOrientation1( xform1.m_orientation )
, m_qOrientation2( xform2.m_orientation )
{
// Normalize sweep (e.g. check polarity)
Normalize();
}
RnSweptTransform_t( matrix3x4_t xform1, matrix3x4_t xform2 )
{
// Normalize the matrix to avoid issues when
// converting the rotation to a quaternion!
MatrixNormalize( xform1, xform1 );
MatrixNormalize( xform2, xform2 );
m_vPosition1 = xform1.GetOrigin();
m_vPosition2 = xform2.GetOrigin();
m_qOrientation1 = xform1.ToQuaternion();
m_qOrientation2 = xform2.ToQuaternion();
// Normalize sweep (e.g. check polarity)
Normalize();
}
CTransform Interpolate( float flAlpha ) const
{
AssertDbg( IsNormalized() );
CTransform out;
out.m_vPosition = ( 1.0f - flAlpha ) * m_vPosition1 + flAlpha * m_vPosition2;
out.m_orientation = ( 1.0f - flAlpha ) * m_qOrientation1 + flAlpha * m_qOrientation2;
QuaternionNormalize( out.m_orientation );
return out;
}
void Normalize()
{
if ( QuaternionDotProduct( m_qOrientation1, m_qOrientation2 ) < 0.0f )
{
m_qOrientation2 = -m_qOrientation2;
}
}
bool IsNormalized() const
{
return QuaternionDotProduct( m_qOrientation1, m_qOrientation2 ) >= 0.0f;
}
Vector m_vPosition1, m_vPosition2;
Quaternion m_qOrientation1, m_qOrientation2;
};
//---------------------------------------------------------------------------------------
// Snooping
//---------------------------------------------------------------------------------------
struct RnSnooperAdvertisement_t
{
int64 m_nProcessId;
int64 m_nRnWorldAddr;
char m_Name[48];
};
struct RnWorldSnoopStats_t: public RnSnooperAdvertisement_t
{
uint m_nBodies;
uint m_nSoftbodies;
uint m_nJoints;
uint m_nContacts;
uint m_nSimulationFrame;
float m_flSimulationTimeElapsed;
};
struct RnWorldSnoopParams_t
{
RnWorldSnoopParams_t()
{
V_memset( this, 0, sizeof( *this ) );
}
int m_nProcessId;
uint64 m_nRemoteAddr;
uint m_nTimeout;
bool m_bOnlyIfFrameChanged;
bool m_bPurgeResourceCaches;
bool m_bFailOnTimeout; // when this is set to true, it make snooping safe: when snooper cannot lock the snoop mutex, it won't try to snoop
};
enum RnWorldSnoopEnum_t
{
RN_WORLD_SNOOP_OK,
RN_WORLD_SNOOP_UNCHANGED,
RN_WORLD_SNOOP_ERROR,
RN_WORLD_SNOOP_CRASH,
RN_WORLD_SNOOP_TIMEOUT
};
class CRnBody;
class CRnShape;
class CPhysSurfaceProperties;
struct RecordedTraceResult_t
{
const CRnBody *m_pHitObject;
const CRnShape *m_pHitShape;
Vector m_vHitPoint;
Vector m_vHitNormal;
float m_flHitOffset;
float m_flFraction;
bool m_bStartInSolid;
const CPhysSurfaceProperties *m_pSurfaceProperties;
Vector m_vRayStart;
Vector m_vRayDelta;
Vector m_vExtents;
int m_nSelect;
};
struct RecordedForce_t
{
const CRnBody *m_pHitObject;
const CRnShape *m_pHitShape;
Vector m_vForcePoint;
Vector m_vForce;
};
struct RnInertiaProperties_t
{
matrix3x4_t m_Inertia;
float m_flMass;
const Vector GetMassCenter( ) const { return m_Inertia.GetOrigin(); }
float GetMass() const { return m_flMass; }
Quaternion GetOrientation( Vector &inertia )const
{
return Diagonalizer( m_Inertia, inertia );
}
Quaternion GetOrientation( )const
{
Vector inertia;
NOTE_UNUSED( inertia );
return Diagonalizer( m_Inertia, inertia );
}
matrix3x4_t GetPrincipalTransform()const
{
return QuaternionMatrix( GetOrientation(), m_Inertia.GetOrigin() );
}
void SetMassCenter( const Vector &v )
{
m_Inertia.SetOrigin( v );
}
static const RnInertiaProperties_t GetDefault()
{
RnInertiaProperties_t out;
V_memset( &out, 0, sizeof( out ) );
return out;
}
};
inline const RnInertiaProperties_t TransformInertiaProperties( const matrix3x4_t &tm, const RnInertiaProperties_t &ip )
{
RnInertiaProperties_t out;
out.m_flMass = ip.m_flMass;
// Multiply R * I * R^-1
out.m_Inertia = ConcatTransforms( ConcatTransforms( tm, ip.m_Inertia ), MatrixInvert( tm ) );
out.SetMassCenter( tm.TransformVector( ip.GetMassCenter() ) );
return out;
}
struct RnSupport_t
{
Vector m_vPoint; // support point - farthest in the given direction
float m_flDistance; // support distance - max in the given direction
public:
const Vector &GetPoint()const { return m_vPoint; }
float GetDistance() const { return m_flDistance; }
static RnSupport_t GetDefault()
{
RnSupport_t out;
out.m_flDistance = -FLT_MAX;
out.m_vPoint.Init(0,0,0);
return out;
}
};
struct CRnContactStats
{
uint m_nContacts;
uint m_nPoints;
uint m_nTouchingPoints;
uint m_nManifolds;
CRnContactStats( uint nContacts = 0 )
{
m_nContacts = nContacts;
m_nPoints = 0;
m_nTouchingPoints = 0;
m_nManifolds = 0;
}
CRnContactStats& operator += ( const CRnContactStats&that )
{
m_nContacts += that.m_nContacts;
m_nPoints += that.m_nPoints;
m_nTouchingPoints += that.m_nTouchingPoints;
m_nManifolds += that.m_nManifolds;
return *this;
}
};
struct RnPlane_t;
typedef CUtlVectorFixedGrowable< RnPlane_t, 32 > PlaneBuffer;
struct RnDebugDrawOptions_t
{
RnDebugDrawOptions_t( uint nLayers = 0 ) { m_nLayers = nLayers; m_nSoftbodyLayers = 1; }
uint32 m_nLayers;
uint32 m_nSoftbodyLayers;
void EnableLayers( uint nLayersMask, bool bEnable )
{
if ( bEnable )
m_nLayers |= nLayersMask;
else
m_nLayers &= ~nLayersMask;
}
};
struct PhysGenericCallback_t
{
void( *m_pCallbackFn )( void * );
void *m_pData;
PhysGenericCallback_t( ) : m_pCallbackFn( NULL ), m_pData( NULL ) {}
PhysGenericCallback_t( void( *pCallbackFn )( void * ), void *pData = NULL ): m_pCallbackFn( pCallbackFn ), m_pData( pData ) { }
void Call() const
{
m_pCallbackFn( m_pData );
}
bool operator == ( const PhysGenericCallback_t &that )const
{
return m_pCallbackFn == that.m_pCallbackFn && m_pData == that.m_pData;
}
};
enum PhysCallbackStage_t
{
PHYS_CALLBACK_END_OF_STEP,
PHYS_CALLBACK_COUNT
};
class CDebugHighlightCone
{
public:
Vector m_vApex;
Vector m_vAxis;
float m_flSlope; // 0 means 0-width cone; 1 means cone surface goes 45 degrees from the axis
public:
CDebugHighlightCone():
m_vAxis(0, 0, 1), m_vApex(0, 0, 0), m_flSlope( 0)
{
}
bool ContainsPoint( const Vector &v )
{
return Highlight( v ) > 0.0f;
}
float Highlight( const Vector &v )
{
if ( m_flSlope <= 0 )
return 0.0f;
Vector d = v - m_vApex;
float flDistAlongAxis = DotProduct( d, m_vAxis );
if ( flDistAlongAxis <= 0 )
return 0.0f;
float flDistToAxis = ( d - m_vAxis * flDistAlongAxis ).Length();
if ( flDistToAxis >= flDistAlongAxis * m_flSlope )
return 0.0f;
else
{
return 1.0f - flDistToAxis / flDistAlongAxis * m_flSlope;
}
}
};
struct RnHullSimplificationParams_t
{
float m_flPrecisionDegrees;
float m_flPrecisionInches;
int m_nMaxFaces;
int m_nMaxEdges;
int m_nMaxVerts;
RnHullSimplificationParams_t()
{
m_flPrecisionDegrees = 0.0f;
m_flPrecisionInches = 0.0f;
m_nMaxFaces = 0;
m_nMaxEdges = 0;
m_nMaxVerts = 0;
}
bool HasLimits()const
{
return m_flPrecisionDegrees > 0 || m_nMaxVerts > 0 || m_nMaxFaces > 0 || m_nMaxEdges > 0;
}
};
#endif

1675
public/rubikon/serialize.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
//========= Copyright <20> Valve Corporation, All rights reserved. ============//
#ifndef SERIALIZE_HELPERS_HDR
#define SERIALIZE_HELPERS_HDR
#ifdef __clang__
# define CLANG_ATTR(ATTR) __attribute__((annotate( ATTR )))
#else
# define CLANG_ATTR(ATTR)
#endif
#define AUTO_SERIALIZE_AS( TYPE ) CLANG_ATTR( "auto_serialize_as:" #TYPE )
#define SERIALIZE_ARRAY_SIZE( SIZE ) CLANG_ATTR( "array_size:" #SIZE )
#define SERIALIZE_SHARED_ARRAY_SIZE( SIZE ) CLANG_ATTR( "shared_data;array_size:" #SIZE )
class CRnObjectStats;
class CRnSnooper;
class CRnUnserializer;
class CRnSerializer;
#define AUTO_SERIALIZE_(RET,ATTR) public: RET Serialize( CRnSerializer* pOut ) const ATTR; RET Unserialize( CRnUnserializer* pIn ) ATTR; RET Serialize( CRnObjectStats* pOut ) const ATTR; RET Snoop( CRnSnooper* pIn, const void *pLocalCopy ) ;
#define AUTO_SERIALIZE_BASE AUTO_SERIALIZE_( virtual bool, CLANG_ATTR( "auto_serialize base" ) ); virtual CUtlStringToken GetClassName() const = 0
#define AUTO_SERIALIZE AUTO_SERIALIZE_( bool, CLANG_ATTR( "auto_serialize" ) )
#define AUTO_SERIALIZE_LEAF AUTO_SERIALIZE_( virtual bool, CLANG_ATTR( "auto_serialize leaf" ) ); virtual CUtlStringToken GetClassName() const OVERRIDE;
#define AUTO_SERIALIZE_POSTINIT() CLANG_ATTR( "auto_serialize_postinit" )
#define AUTO_SERIALIZE_STRUCT(NAME) bool Serialize( CRnSerializer *pOut, const NAME &ref ) CLANG_ATTR("auto_serialize"); bool Unserialize( CRnUnserializer* pIn, NAME &ref ) CLANG_ATTR("auto_serialize"); bool Serialize( CRnObjectStats *pOut, const NAME &ref ) CLANG_ATTR("auto_serialize"); bool Snoop( CRnSnooper *pIn, const NAME *pLocalCopy, NAME &ref );
#define DECL_SERIALIZE_STRUCT(NAME) bool Serialize( CRnSerializer *pOut, const NAME &ref ); bool Unserialize( CRnUnserializer* pIn, NAME &ref ); bool Serialize( CRnObjectStats *pOut, const NAME &ref ) ; bool Snoop( CRnSnooper *pIn, const NAME *pLocalCopy, NAME &ref );
#define DECL_SERIALIZE_CLASS(NAME) void Serialize( CRnObjectStats *pOut, const NAME * const pObj ); void Serialize( CRnSerializer *pOut, const NAME * const pObj ); void Unserialize( CRnUnserializer *pIn, NAME *& refPtr );
#define SKIP_SERIALIZE CLANG_ATTR( "skip_serialize" )
#include "tier1/utlbufferstrider.h"
#include "serializehelpers.inl"
#endif

View File

@@ -0,0 +1,2 @@
//========= Copyright <20> Valve Corporation, All rights reserved. ============//