214 lines
5.3 KiB
C++
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
|