Seaside/SpyCustom/sdk/particles.h
2021-07-09 19:01:09 +03:00

929 lines
24 KiB
C++

#ifndef PARTICLES_H
#define PARTICLES_H
#ifdef _WIN32
#pragma once
#endif
#include "mathlib.h"
#include "vector.h"
#include "ssemath.h"
#include "imaterialsystem.h"
#include "dmxelement.h"
#include "utlintrusivelist.h"
#include "random.h"
#include "utlobjectreference.h"
#include "UtlStringMap.h"
#include "utlmap.h"
#include "MaterialSystemUtil.h"
#include "trace.h"
#include "utlsoacontainer.h"
#if defined( CLIENT_DLL )
#include "c_pixel_visibility.h"
#endif
struct DmxElementUnpackStructure_t;
class CParticleSystemDefinition;
class CParticleCollection;
class CParticleOperatorInstance;
class CParticleSystemDictionary;
class CUtlBuffer;
class IParticleOperatorDefinition;
class CSheet;
class CMeshBuilder;
extern float s_pRandomFloats[];
#define MAX_RANDOM_FLOATS 4096
#define RANDOM_FLOAT_MASK ( MAX_RANDOM_FLOATS - 1 )
#define MAX_PARTICLE_ATTRIBUTES 32
#define DEFPARTICLE_ATTRIBUTE( name, bit ) \
const int PARTICLE_ATTRIBUTE_##name##_MASK = (1 << bit); \
const int PARTICLE_ATTRIBUTE_##name = bit;
DEFPARTICLE_ATTRIBUTE(XYZ, 0);
DEFPARTICLE_ATTRIBUTE(LIFE_DURATION, 1);
DEFPARTICLE_ATTRIBUTE(PREV_XYZ, 2);
DEFPARTICLE_ATTRIBUTE(RADIUS, 3);
DEFPARTICLE_ATTRIBUTE(ROTATION, 4);
DEFPARTICLE_ATTRIBUTE(ROTATION_SPEED, 5);
DEFPARTICLE_ATTRIBUTE(TINT_RGB, 6);
DEFPARTICLE_ATTRIBUTE(ALPHA, 7);
DEFPARTICLE_ATTRIBUTE(CREATION_TIME, 8);
DEFPARTICLE_ATTRIBUTE(SEQUENCE_NUMBER, 9);
DEFPARTICLE_ATTRIBUTE(TRAIL_LENGTH, 10);
DEFPARTICLE_ATTRIBUTE(PARTICLE_ID, 11);
DEFPARTICLE_ATTRIBUTE(YAW, 12);
DEFPARTICLE_ATTRIBUTE(SEQUENCE_NUMBER1, 13);
DEFPARTICLE_ATTRIBUTE(HITBOX_INDEX, 14);
DEFPARTICLE_ATTRIBUTE(HITBOX_RELATIVE_XYZ, 15);
DEFPARTICLE_ATTRIBUTE(ALPHA2, 16);
DEFPARTICLE_ATTRIBUTE(TRACE_P0, 17);
DEFPARTICLE_ATTRIBUTE(TRACE_P1, 18);
DEFPARTICLE_ATTRIBUTE(TRACE_HIT_T, 19);
DEFPARTICLE_ATTRIBUTE(TRACE_HIT_NORMAL, 20);
#define MAX_PARTICLE_CONTROL_POINTS 64
#define ATTRIBUTES_WHICH_ARE_VEC3S_MASK ( PARTICLE_ATTRIBUTE_TRACE_P0_MASK | PARTICLE_ATTRIBUTE_TRACE_P1_MASK | \
PARTICLE_ATTRIBUTE_TRACE_HIT_NORMAL | PARTICLE_ATTRIBUTE_XYZ_MASK | \
PARTICLE_ATTRIBUTE_PREV_XYZ_MASK | PARTICLE_ATTRIBUTE_TINT_RGB_MASK | \
PARTICLE_ATTRIBUTE_HITBOX_RELATIVE_XYZ_MASK )
#define ATTRIBUTES_WHICH_ARE_0_TO_1 (PARTICLE_ATTRIBUTE_ALPHA_MASK | PARTICLE_ATTRIBUTE_ALPHA2_MASK)
#define ATTRIBUTES_WHICH_ARE_ANGLES (PARTICLE_ATTRIBUTE_ROTATION_MASK | PARTICLE_ATTRIBUTE_YAW_MASK )
#define ATTRIBUTES_WHICH_ARE_INTS (PARTICLE_ATTRIBUTE_PARTICLE_ID_MASK | PARTICLE_ATTRIBUTE_HITBOX_INDEX_MASK )
#if defined( _X360 )
#define MAX_PARTICLES_IN_A_SYSTEM 2000
#else
#define MAX_PARTICLES_IN_A_SYSTEM 5000
#endif
#define MEASURE_PARTICLE_PERF 0
enum ParticleFunctionType_t
{
FUNCTION_RENDERER = 0,
FUNCTION_OPERATOR,
FUNCTION_INITIALIZER,
FUNCTION_EMITTER,
FUNCTION_CHILDREN,
FUNCTION_FORCEGENERATOR,
FUNCTION_CONSTRAINT,
PARTICLE_FUNCTION_COUNT
};
struct CParticleVisibilityInputs
{
float m_flCameraBias;
float m_flInputMin;
float m_flInputMax;
float m_flAlphaScaleMin;
float m_flAlphaScaleMax;
float m_flRadiusScaleMin;
float m_flRadiusScaleMax;
float m_flProxyRadius;
float m_flBBoxScale;
bool m_bUseBBox;
int m_nCPin;
};
struct ModelHitBoxInfo_t
{
Vector m_vecBoxMins;
Vector m_vecBoxMaxes;
matrix3x4_t m_Transform;
};
class CModelHitBoxesInfo
{
public:
float m_flLastUpdateTime;
float m_flPrevLastUpdateTime;
int m_nNumHitBoxes;
int m_nNumPrevHitBoxes;
ModelHitBoxInfo_t* m_pHitBoxes;
ModelHitBoxInfo_t* m_pPrevBoxes;
bool CurAndPrevValid(void) const
{
return (m_nNumHitBoxes && (m_nNumPrevHitBoxes == m_nNumHitBoxes));
}
CModelHitBoxesInfo(void)
{
m_flLastUpdateTime = -1;
m_nNumHitBoxes = 0;
m_nNumPrevHitBoxes = 0;
m_pHitBoxes = NULL;
m_pPrevBoxes = NULL;
}
~CModelHitBoxesInfo(void)
{
if (m_pHitBoxes)
delete[] m_pHitBoxes;
if (m_pPrevBoxes)
delete[] m_pPrevBoxes;
}
};
#define PARTICLE_SYSTEM_QUERY_INTERFACE_VERSION "VParticleSystemQuery001"
class IParticleSystemQuery : public IAppSystem
{
public:
virtual void GetLightingAtPoint(const Vector& vecOrigin, Color& tint) = 0;
virtual void TraceLine(const Vector& vecAbsStart,
const Vector& vecAbsEnd, unsigned int mask,
const class IHandleEntity* ignore,
int collisionGroup,
CBaseTrace* ptr) = 0;
virtual bool MovePointInsideControllingObject(CParticleCollection* pParticles,
void* pObject,
Vector* pPnt)
{
return true;
}
virtual bool IsPointInControllingObjectHitBox(
CParticleCollection* pParticles,
int nControlPointNumber, Vector vecPos, bool bBBoxOnly = false)
{
return true;
}
virtual int GetCollisionGroupFromName(const char* pszCollisionGroupName)
{
return 0;
}
virtual void GetRandomPointsOnControllingObjectHitBox(
CParticleCollection* pParticles,
int nControlPointNumber,
int nNumPtsOut,
float flBBoxScale,
int nNumTrysToGetAPointInsideTheModel,
Vector* pPntsOut,
Vector vecDirectionBias,
Vector* pHitBoxRelativeCoordOut = NULL,
int* pHitBoxIndexOut = NULL) = 0;
virtual int GetControllingObjectHitBoxInfo(
CParticleCollection* pParticles,
int nControlPointNumber,
int nBufSize,
ModelHitBoxInfo_t* pHitBoxOutputBuffer)
{
return 0;
}
virtual Vector GetLocalPlayerPos(void)
{
return vec3_origin;
}
virtual void GetLocalPlayerEyeVectors(Vector* pForward, Vector* pRight = NULL, Vector* pUp = NULL)
{
*pForward = vec3_origin;
*pRight = vec3_origin;
*pUp = vec3_origin;
}
virtual float GetPixelVisibility(int* pQueryHandle, const Vector& vecOrigin, float flScale) = 0;
virtual void SetUpLightingEnvironment(const Vector& pos)
{
}
};
typedef int ParticleSystemHandle_t;
class CParticleSystemMgr
{
public:
CParticleSystemMgr();
~CParticleSystemMgr();
bool Init(IParticleSystemQuery* pQuery);
void AddBuiltinSimulationOperators(void);
void AddBuiltinRenderingOperators(void);
void AddParticleOperator(ParticleFunctionType_t nOpType, IParticleOperatorDefinition* pOpFactory);
bool ReadParticleConfigFile(const char* pFileName, bool bPrecache, bool bDecommitTempMemory = true);
bool ReadParticleConfigFile(CUtlBuffer& buf, bool bPrecache, bool bDecommitTempMemory = true, const char* pFileName = NULL);
void DecommitTempMemory();
bool WriteParticleConfigFile(const char* pParticleSystemName, CUtlBuffer& buf, bool bPreventNameBasedLookup = false);
bool WriteParticleConfigFile(const DmObjectId_t& id, CUtlBuffer& buf, bool bPreventNameBasedLookup = false);
CParticleCollection* CreateParticleCollection(const char* pParticleSystemName, float flDelay = 0.0f, int nRandomSeed = 0);
CParticleCollection* CreateParticleCollection(const DmObjectId_t& id, float flDelay = 0.0f, int nRandomSeed = 0);
bool IsParticleSystemDefined(const char* pParticleSystemName);
bool IsParticleSystemDefined(const DmObjectId_t& id);
ParticleSystemHandle_t GetParticleSystemIndex(const char* pParticleSystemName);
const char* GetParticleSystemNameFromIndex(ParticleSystemHandle_t iIndex);
int GetParticleSystemCount(void);
CUtlVector< IParticleOperatorDefinition*>& GetAvailableParticleOperatorList(ParticleFunctionType_t nWhichList);
const DmxElementUnpackStructure_t* GetParticleSystemDefinitionUnpackStructure();
void ShouldLoadSheets(bool bLoadSheets);
CSheet* FindOrLoadSheet(char const* pszFname, ITexture* pTexture);
CSheet* FindOrLoadSheet(IMaterial* pMaterial);
void FlushAllSheets(void);
void ResetRenderCache(void);
void AddToRenderCache(CParticleCollection* pParticles);
void DrawRenderCache(bool bShadowDepth);
IParticleSystemQuery* Query(void) { return m_pQuery; }
const char* GetParticleFieldName(int nParticleField) const;
CParticleSystemDefinition* FindParticleSystem(const char* pName);
CParticleSystemDefinition* FindParticleSystem(const DmObjectId_t& id);
void CommitProfileInformation(bool bCommit);
void DumpProfileInformation(void);
void PrecacheParticleSystem(const char* pName);
void UncacheAllParticleSystems();
void SetLastSimulationTime(float flTime);
float GetLastSimulationTime() const;
int Debug_GetTotalParticleCount() const;
bool Debug_FrameWarningNeededTestAndReset();
float ParticleThrottleScaling() const;
bool ParticleThrottleRandomEnable() const;
void TallyParticlesRendered(int nVertexCount, int nIndexCount = 0);
private:
struct RenderCache_t
{
IMaterial* m_pMaterial;
CUtlVector< CParticleCollection* > m_ParticleCollections;
};
struct BatchStep_t
{
CParticleCollection* m_pParticles;
CParticleOperatorInstance* m_pRenderer;
void* m_pContext;
int m_nFirstParticle;
int m_nParticleCount;
int m_nVertCount;
};
struct Batch_t
{
int m_nVertCount;
int m_nIndexCount;
CUtlVector< BatchStep_t > m_BatchStep;
};
bool ReadParticleDefinitions(CUtlBuffer& buf, const char* pFileName, bool bPrecache, bool bDecommitTempMemory);
void AddParticleSystem(CDmxElement* pParticleSystem);
CDmxElement* CreateParticleDmxElement(const DmObjectId_t& id);
CDmxElement* CreateParticleDmxElement(const char* pParticleSystemName);
bool WriteParticleConfigFile(CDmxElement* pParticleSystem, CUtlBuffer& buf, bool bPreventNameBasedLookup);
void BuildBatchList(int iRenderCache, IMatRenderContext* pRenderContext, CUtlVector< Batch_t >& batches);
CUtlVector<IParticleOperatorDefinition*> m_ParticleOperators[PARTICLE_FUNCTION_COUNT];
CParticleSystemDictionary* m_pParticleSystemDictionary;
typedef CUtlStringMap< CSheet* > SheetsCache_t;
SheetsCache_t m_SheetList;
void AttachKillList(CParticleCollection* pParticles);
void DetachKillList(CParticleCollection* pParticles);
CParticleCollection* m_pVisualizedParticles;
DmObjectId_t m_VisualizedOperatorId;
IParticleSystemQuery* m_pQuery;
CUtlVector< RenderCache_t > m_RenderCache;
IMaterial* m_pShadowDepthMaterial;
float m_flLastSimulationTime;
bool m_bDidInit;
bool m_bUsingDefaultQuery;
bool m_bShouldLoadSheets;
int m_nNumFramesMeasured;
enum { c_nNumFramesTracked = 10 };
int m_nParticleVertexCountHistory[c_nNumFramesTracked];
float m_fParticleCountScaling;
int m_nParticleIndexCount;
int m_nParticleVertexCount;
bool m_bFrameWarningNeeded;
friend class CParticleSystemDefinition;
friend class CParticleCollection;
};
extern CParticleSystemMgr* g_pParticleSystemMgr;
enum ParticleOperatorId_t
{
OPERATOR_GENERIC = -2,
OPERATOR_SINGLETON = -1,
OPERATOR_PI_POSITION,
OPERATOR_PI_RADIUS,
OPERATOR_PI_ALPHA,
OPERATOR_PI_TINT_RGB,
OPERATOR_PI_ROTATION,
OPERATOR_PI_YAW,
OPERATOR_ID_COUNT,
};
class IParticleOperatorDefinition
{
public:
virtual const char* GetName() const = 0;
virtual CParticleOperatorInstance* CreateInstance(const DmObjectId_t& id) const = 0;
virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const = 0;
virtual ParticleOperatorId_t GetId() const = 0;
virtual bool IsObsolete() const = 0;
virtual size_t GetClassSize() const = 0;
#if MEASURE_PARTICLE_PERF
float m_flMaxExecutionTime;
float m_flTotalExecutionTime;
float m_flUncomittedTime;
FORCEINLINE void RecordExecutionTime(float flETime)
{
m_flUncomittedTime += flETime;
m_flMaxExecutionTime = MAX(m_flMaxExecutionTime, flETime);
}
FORCEINLINE float TotalRecordedExecutionTime(void) const
{
return m_flTotalExecutionTime;
}
FORCEINLINE float MaximumRecordedExecutionTime(void) const
{
return m_flMaxExecutionTime;
}
#endif
};
class CParticleOperatorInstance
{
public:
void* operator new(size_t nSize);
void* operator new(size_t size, int nBlockUse, const char* pFileName, int nLine);
void operator delete(void* pData);
void operator delete(void* p, int nBlockUse, const char* pFileName, int nLine);
virtual void InitParams(CParticleSystemDefinition* pDef, CDmxElement* pElement)
{
}
virtual size_t GetRequiredContextBytes() const
{
return 0;
}
virtual void InitializeContextData(CParticleCollection* pParticles, void* pContext) const
{
}
virtual uint32 GetWrittenAttributes(void) const = 0;
virtual uint32 GetReadAttributes(void) const = 0;
virtual uint64 GetReadControlPointMask() const
{
return 0;
}
virtual uint32 GetReadInitialAttributes(void) const
{
return 0;
}
virtual void Operate(CParticleCollection* pParticles, float flOpStrength, void* pContext) const
{
}
virtual void Render(IMatRenderContext* pRenderContext,
CParticleCollection* pParticles, void* pContext) const
{
}
virtual bool IsBatchable() const
{
return true;
}
virtual void RenderUnsorted(CParticleCollection* pParticles, void* pContext, IMatRenderContext* pRenderContext, CMeshBuilder& meshBuilder, int nVertexOffset, int nFirstParticle, int nParticleCount) const
{
}
virtual int GetParticlesToRender(CParticleCollection* pParticles, void* pContext, int nFirstParticle, int nRemainingVertices, int nRemainingIndices, int* pVertsUsed, int* pIndicesUsed) const
{
*pVertsUsed = 0;
*pIndicesUsed = 0;
return 0;
}
virtual uint32 Emit(CParticleCollection* pParticles, float flOpCurStrength,
void* pContext) const
{
return 0;
}
virtual void StopEmission(CParticleCollection* pParticles, void* pContext, bool bInfiniteOnly = false) const
{
}
virtual void StartEmission(CParticleCollection* pParticles, void* pContext, bool bInfiniteOnly = false) const
{
}
virtual void Restart(CParticleCollection* pParticles, void* pContext) {}
virtual void InitParticleSystem(CParticleCollection* pParticles, void* pContext) const
{
}
virtual void AddForces(FourVectors* AccumulatedForces,
CParticleCollection* pParticles,
int nBlocks,
float flCurStrength,
void* pContext) const
{
}
virtual void SetupConstraintPerFrameData(CParticleCollection* pParticles,
void* pContext) const
{
}
virtual bool EnforceConstraint(int nStartBlock,
int nNumBlocks,
CParticleCollection* pParticles,
void* pContext,
int nNumValidParticlesInLastChunk) const
{
return false;
}
virtual bool IsFinalConstraint(void) const
{
return false;
}
virtual bool InitMultipleOverride()
{
return false;
}
virtual bool IsScrubSafe()
{
return false;
}
virtual void InitNewParticlesScalar(CParticleCollection* pParticles, int nFirstParticle, int n_particles, int attribute_write_mask, void* pContext) const
{
}
virtual void InitNewParticlesBlock(CParticleCollection* pParticles, int start_block, int n_blocks, int attribute_write_mask, void* pContext) const
{
InitNewParticlesScalar(pParticles, 4 * start_block, 4 * n_blocks, attribute_write_mask, pContext);
}
void InitNewParticles(CParticleCollection* pParticles, int nFirstParticle, int n_particles, int attribute_write_mask, void* pContext) const;
virtual bool MayCreateMoreParticles(CParticleCollection* pParticles, void* pContext) const
{
return false;
}
const IParticleOperatorDefinition* GetDefinition()
{
return m_pDef;
}
virtual bool ShouldRunBeforeEmitters(void) const
{
return false;
}
virtual bool RequiresOrderInvariance(void) const
{
return false;
}
virtual void SkipToTime(float flTime, CParticleCollection* pParticles, void* pContext) const {}
const DmObjectId_t& GetId() { return m_Id; }
virtual void Render(CParticleCollection* pParticles) const {}
int RandomInt(int nMin, int nMax)
{
Assert(0);
return 0;
}
float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f)
{
Assert(0);
return 0.0f;
}
float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f)
{
Assert(0);
return 0.0f;
}
float m_flOpStartFadeInTime;
float m_flOpEndFadeInTime;
float m_flOpStartFadeOutTime;
float m_flOpEndFadeOutTime;
float m_flOpFadeOscillatePeriod;
virtual ~CParticleOperatorInstance(void)
{
}
protected:
void InitScalarAttributeRandomRangeBlock(int nAttributeId, float fMinValue, float fMaxValue,
CParticleCollection* pParticles, int nStartBlock, int nBlockCount) const;
void InitScalarAttributeRandomRangeExpBlock(int nAttributeId, float fMinValue, float fMaxValue, float fExp,
CParticleCollection* pParticles, int nStartBlock, int nBlockCount) const;
void AddScalarAttributeRandomRangeBlock(int nAttributeId, float fMinValue, float fMaxValue, float fExp,
CParticleCollection* pParticles, int nStartBlock, int nBlockCount, bool bRandomlyInvert) const;
private:
friend class CParticleCollection;
const IParticleOperatorDefinition* m_pDef;
void SetDefinition(const IParticleOperatorDefinition* pDef, const DmObjectId_t& id)
{
m_pDef = pDef;
CopyUniqueId(id, &m_Id);
}
DmObjectId_t m_Id;
template <typename T> friend class CParticleOperatorDefinition;
};
class CParticleRenderOperatorInstance : public CParticleOperatorInstance
{
public:
CParticleVisibilityInputs VisibilityInputs;
};
template < class T >
class CParticleOperatorDefinition : public IParticleOperatorDefinition
{
public:
CParticleOperatorDefinition(const char* pFactoryName, ParticleOperatorId_t id, bool bIsObsolete) : m_pFactoryName(pFactoryName), m_Id(id)
{
#if MEASURE_PARTICLE_PERF
m_flTotalExecutionTime = 0.0f;
m_flMaxExecutionTime = 0.0f;
m_flUncomittedTime = 0.0f;
#endif
m_bIsObsolete = bIsObsolete;
}
virtual const char* GetName() const
{
return m_pFactoryName;
}
virtual ParticleOperatorId_t GetId() const
{
return m_Id;
}
virtual CParticleOperatorInstance* CreateInstance(const DmObjectId_t& id) const
{
CParticleOperatorInstance* pOp = new T;
pOp->SetDefinition(this, id);
return pOp;
}
virtual const DmxElementUnpackStructure_t* GetUnpackStructure() const
{
return m_pUnpackParams;
}
virtual bool IsObsolete() const
{
return m_bIsObsolete;
}
virtual size_t GetClassSize() const
{
return sizeof(T);
}
private:
const char* m_pFactoryName;
ParticleOperatorId_t m_Id;
bool m_bIsObsolete;
static DmxElementUnpackStructure_t* m_pUnpackParams;
};
#define DECLARE_PARTICLE_OPERATOR( _className ) \
DECLARE_DMXELEMENT_UNPACK() \
friend class CParticleOperatorDefinition<_className >
#define DEFINE_PARTICLE_OPERATOR( _className, _operatorName, _id ) \
static CParticleOperatorDefinition<_className> s_##_className##Factory( _operatorName, _id, false )
#define DEFINE_PARTICLE_OPERATOR_OBSOLETE( _className, _operatorName, _id ) \
static CParticleOperatorDefinition<_className> s_##_className##Factory( _operatorName, _id, true )
#define BEGIN_PARTICLE_OPERATOR_UNPACK( _className ) \
BEGIN_DMXELEMENT_UNPACK( _className ) \
DMXELEMENT_UNPACK_FIELD( "operator start fadein","0", float, m_flOpStartFadeInTime ) \
DMXELEMENT_UNPACK_FIELD( "operator end fadein","0", float, m_flOpEndFadeInTime ) \
DMXELEMENT_UNPACK_FIELD( "operator start fadeout","0", float, m_flOpStartFadeOutTime ) \
DMXELEMENT_UNPACK_FIELD( "operator end fadeout","0", float, m_flOpEndFadeOutTime ) \
DMXELEMENT_UNPACK_FIELD( "operator fade oscillate","0", float, m_flOpFadeOscillatePeriod )
#define END_PARTICLE_OPERATOR_UNPACK( _className ) \
END_DMXELEMENT_UNPACK_TEMPLATE( _className, CParticleOperatorDefinition<_className>::m_pUnpackParams )
#define BEGIN_PARTICLE_RENDER_OPERATOR_UNPACK( _className ) \
BEGIN_PARTICLE_OPERATOR_UNPACK( _className ) \
DMXELEMENT_UNPACK_FIELD( "Visibility Proxy Input Control Point Number", "-1", int, VisibilityInputs.m_nCPin ) \
DMXELEMENT_UNPACK_FIELD( "Visibility Proxy Radius", "1.0", float, VisibilityInputs.m_flProxyRadius ) \
DMXELEMENT_UNPACK_FIELD( "Visibility input minimum","0", float, VisibilityInputs.m_flInputMin ) \
DMXELEMENT_UNPACK_FIELD( "Visibility input maximum","1", float, VisibilityInputs.m_flInputMax ) \
DMXELEMENT_UNPACK_FIELD( "Visibility Alpha Scale minimum","0", float, VisibilityInputs.m_flAlphaScaleMin ) \
DMXELEMENT_UNPACK_FIELD( "Visibility Alpha Scale maximum","1", float, VisibilityInputs.m_flAlphaScaleMax ) \
DMXELEMENT_UNPACK_FIELD( "Visibility Radius Scale minimum","1", float, VisibilityInputs.m_flRadiusScaleMin ) \
DMXELEMENT_UNPACK_FIELD( "Visibility Radius Scale maximum","1", float, VisibilityInputs.m_flRadiusScaleMax ) \
DMXELEMENT_UNPACK_FIELD( "Visibility Camera Depth Bias", "0", float, VisibilityInputs.m_flCameraBias )
#define REGISTER_PARTICLE_OPERATOR( _type, _className ) \
g_pParticleSystemMgr->AddParticleOperator( _type, &s_##_className##Factory )
enum
{
PCFLAGS_FIRST_FRAME = 0x1,
PCFLAGS_PREV_CONTROL_POINTS_INITIALIZED = 0x2,
};
#define DEBUG_PARTICLE_SORT 0
struct ParticleRenderData_t
{
float m_flSortKey;
int m_nIndex;
float m_flRadius;
#if VALVE_LITTLE_ENDIAN
uint8 m_nAlpha;
uint8 m_nAlphaPad[3];
#else
uint8 m_nAlphaPad[3];
uint8 m_nAlpha;
#endif
};
struct ExtendedParticleRenderData_t : ParticleRenderData_t
{
float m_flX;
float m_flY;
float m_flZ;
float m_flPad;
};
typedef struct ALIGN16 _FourInts
{
int32 m_nValue[4];
} ALIGN16_POST FourInts;
struct CPathParameters
{
int m_nStartControlPointNumber;
int m_nEndControlPointNumber;
int m_nBulgeControl;
float m_flBulge;
float m_flMidPoint;
void ClampControlPointIndices(void)
{
m_nStartControlPointNumber = MAX(0, MIN(MAX_PARTICLE_CONTROL_POINTS - 1, m_nStartControlPointNumber));
m_nEndControlPointNumber = MAX(0, MIN(MAX_PARTICLE_CONTROL_POINTS - 1, m_nEndControlPointNumber));
}
};
struct CParticleVisibilityData
{
float m_flAlphaVisibility;
float m_flRadiusVisibility;
float m_flCameraBias;
bool m_bUseVisibility;
};
struct CParticleControlPoint
{
Vector m_Position;
Vector m_PrevPosition;
Vector m_ForwardVector;
Vector m_UpVector;
Vector m_RightVector;
void* m_pObject;
int m_nParent;
};
struct CParticleSIMDTransformation
{
FourVectors m_v4Origin;
FourVectors m_v4Fwd;
FourVectors m_v4Up;
FourVectors m_v4Right;
FORCEINLINE void VectorRotate(FourVectors& InPnt)
{
fltx4 fl4OutX = SubSIMD(AddSIMD(MulSIMD(InPnt.x, m_v4Fwd.x), MulSIMD(InPnt.z, m_v4Up.x)), MulSIMD(InPnt.y, m_v4Right.x));
fltx4 fl4OutY = SubSIMD(AddSIMD(MulSIMD(InPnt.x, m_v4Fwd.y), MulSIMD(InPnt.z, m_v4Up.y)), MulSIMD(InPnt.y, m_v4Right.y));
InPnt.z = SubSIMD(AddSIMD(MulSIMD(InPnt.x, m_v4Fwd.z), MulSIMD(InPnt.z, m_v4Up.z)), MulSIMD(InPnt.y, m_v4Right.z));
InPnt.x = fl4OutX;
InPnt.y = fl4OutY;
}
FORCEINLINE void VectorTransform(FourVectors& InPnt)
{
VectorRotate(InPnt);
InPnt.x = AddSIMD(InPnt.x, m_v4Origin.x);
InPnt.y = AddSIMD(InPnt.y, m_v4Origin.y);
InPnt.z = AddSIMD(InPnt.z, m_v4Origin.z);
}
};
#define NUM_COLLISION_CACHE_MODES 4
struct CUtlString_simple {
char* buffer;
int capacity;
int grow_size;
int length;
};
class CParticleSystemDefinition {
BYTE pad_0[308];
public:
CUtlString_simple m_Name;
};
struct CParticleAttributeAddressTable {
float* m_pAttributes[MAX_PARTICLE_ATTRIBUTES];
size_t m_nFloatStrides[MAX_PARTICLE_ATTRIBUTES];
FORCEINLINE float* FloatAttributePtr(int nAttribute, int nParticleNumber) const {
int block_ofs = nParticleNumber / 4;
return m_pAttributes[nAttribute] +
m_nFloatStrides[nAttribute] * block_ofs +
(nParticleNumber & 3);
}
};
class CParticleCollection {
BYTE pad_0[48];
public:
int m_nActiveParticles;
private:
BYTE pad_1[12];
public:
CUtlReference<CParticleSystemDefinition> m_pDef;
private:
BYTE pad_2[60];
public:
CParticleCollection* m_pParent;
private:
BYTE pad_3[84];
public:
CParticleAttributeAddressTable m_ParticleAttributes;
};
#endif