//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef SHEETSIMULATOR_H #define SHEETSIMULATOR_H #ifdef _WIN32 #pragma once #endif #include "mathlib/mathlib.h" #include "mathlib/vector.h" #include "utlvector.h" // Uncomment this for client-side simulation //#define CLIENT_SIDE_SIMULATION 1 //----------------------------------------------------------------------------- // Simulates a sheet //----------------------------------------------------------------------------- class CGameTrace; typedef CGameTrace trace_t; //struct trace_t; typedef void (*TraceLineFunc_t)(const Vector &vecStart, const Vector &vecEnd, unsigned int mask, int collisionGroup, trace_t *ptr); typedef void (*TraceHullFunc_t)(const Vector &vecStart, const Vector &vecEnd, const Vector &hullMin, const Vector &hullMax, unsigned int mask, int collisionGroup, trace_t *ptr); class CSheetSimulator { public: CSheetSimulator( TraceLineFunc_t traceline, TraceHullFunc_t traceHull ); ~CSheetSimulator(); void Init( int w, int h, int fixedPointCount ); // orientation void SetPosition( const Vector& origin, const QAngle& angles ); // Makes a spring void AddSpring( int p1, int p2, float restLength ); void AddFixedPointSpring( int fixedPoint, int p, float restLength ); // spring constants.... void SetPointSpringConstant( float constant ); void SetFixedSpringConstant( float constant ); // Used for both kinds of springs void SetSpringDampConstant( float damp ); void SetViscousDrag( float drag ); // Sets the collision group void SetCollisionGroup( int group ); // Sets the bounding box used for collision vs world void SetBoundingBox( Vector& mins, Vector& maxs ); // Computes the bounding box void ComputeBounds( Vector& mins, Vector& maxs ); // simulation void Simulate( float dt ); void Simulate( float dt, int steps ); // get at the points int NumHorizontal() const; int NumVertical() const; int PointCount() const; // Fixed points Vector& GetFixedPoint( int i ); // Point masses const Vector& GetPoint( int x, int y ) const; const Vector& GetPoint( int i ) const; // For iterative collision detection void DetectCollision( int i, float flOffset ); void InitPosition( int i ); // For offseting the control points void SetControlPointOffset( const Vector& offset ); // Gravity void SetGravityConstant( float g ); void AddGravityForce( int particle ); protected: struct Particle_t { float m_Mass; Vector m_Position; Vector m_Velocity; Vector m_Force; int m_Collided; int m_CollisionPlane; float m_CollisionDist; }; struct Spring_t { int m_Particle1; int m_Particle2; float m_RestLength; }; inline int NumParticles() const { return m_HorizontalCount * m_VerticalCount; } // simulator void EulerStep( float dt ); void ComputeControlPoints(); void ClearForces(); void ComputeForces(); void TestVertAgainstPlane( int vert, int plane, bool bFarTest = true ); void SatisfyCollisionConstraints(); void DetermineBestCollisionPlane( bool bFarTest = true ); void ClampPointsToCollisionPlanes(); // How many particles horiz + vert? int m_HorizontalCount; int m_VerticalCount; // The particles Particle_t* m_Particle; // Output position after simulation Vector* m_OutputPosition; // fixed points int m_FixedPointCount; Vector* m_pFixedPoint; Vector* m_ControlPoints; CUtlVector m_Springs; CUtlVector m_Gravity; // raycasting methods TraceLineFunc_t m_TraceLine; TraceHullFunc_t m_TraceHull; // Spring constants float m_FixedSpringConstant; float m_PointSpringConstant; float m_DampConstant; float m_ViscousDrag; // Collision group int m_CollisionGroup; // position + orientation Vector m_Origin; QAngle m_Angles; // collision box Vector m_FrustumBoxMin; Vector m_FrustumBoxMax; // Collision planes cplane_t* m_pCollisionPlanes; bool* m_pValidCollisionPlane; // Control point offset Vector m_ControlPointOffset; // Gravity float m_GravityConstant; }; //----------------------------------------------------------------------------- // Class to help dealing with the iterative computation //----------------------------------------------------------------------------- class CIterativeSheetSimulator : public CSheetSimulator { public: CIterativeSheetSimulator( TraceLineFunc_t traceline, TraceHullFunc_t traceHull ); void BeginSimulation( float dt, int steps, int substeps, int collisionCount ); // Returns true if it just did a simulation step bool Think( ); bool IsDone() const { return m_SimulationSteps == 0; } int StepsRemaining( ) const { return m_SimulationSteps; } private: CIterativeSheetSimulator( const CIterativeSheetSimulator & ); // not defined, not accessible // Iterative collision detection void DetectCollisions( void ); float m_TimeStep; float m_SubSteps; char m_TotalSteps; char m_SimulationSteps; char m_CollisionCount; char m_CurrentCollisionPt; bool m_InitialPass; }; #endif // TF_SHIELD_SHARED_H