sqwarmed/sdk_src/game/shared/sheetsimulator.h

214 lines
5.3 KiB
C++

//========= Copyright © 1996-2005, 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<Spring_t> m_Springs;
CUtlVector<int> 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