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

View File

@@ -0,0 +1,70 @@
// ----------------------------------------- //
// File generated by VPC //
// ----------------------------------------- //
Source file: F:\csgo_64\cstrike15_src\particles\addbuiltin_ops.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\addbuiltin_ops.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\addbuiltin_ops.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\builtin_constraints.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\builtin_constraints.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\builtin_constraints.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\builtin_initializers.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\builtin_initializers.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\builtin_initializers.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\builtin_particle_emitters.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_emitters.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_emitters.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\builtin_particle_forces.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_forces.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_forces.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\builtin_particle_ops.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_ops.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_ops.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\builtin_particle_render_ops.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_render_ops.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\builtin_particle_render_ops.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Debug output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Release output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\particle_snapshot.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\particle_snapshot.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\particle_snapshot.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\particle_sort.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\particle_sort.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\particle_sort.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\particles\particles.cpp
Debug output file: F:\csgo_64\cstrike15_src\particles\particles.cpp
Release output file: F:\csgo_64\cstrike15_src\particles\particles.cpp
Containing unity file:
PCH file:

View File

@@ -0,0 +1,46 @@
//===== Copyright © 1996-2007, Valve Corporation, All rights reserved. ======//
//
// Purpose: particle system code
//
//===========================================================================//
#include "tier0/platform.h"
#include "particles/particles.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
void AddBuiltInParticleOperators( void );
void AddBuiltInParticleRenderers( void );
void AddBuiltInParticleInitializers( void );
void AddBuiltInParticleEmitters( void );
void AddBuiltInParticleForceGenerators( void );
void AddBuiltInParticleConstraints( void );
void CParticleSystemMgr::AddBuiltinSimulationOperators( void )
{
static bool s_DidAddSim = false;
if ( ! s_DidAddSim )
{
s_DidAddSim = true;
AddBuiltInParticleOperators();
AddBuiltInParticleInitializers();
AddBuiltInParticleEmitters();
AddBuiltInParticleForceGenerators();
AddBuiltInParticleConstraints();
}
}
void CParticleSystemMgr::AddBuiltinRenderingOperators( void )
{
static bool s_DidAddRenderers = false;
if ( ! s_DidAddRenderers )
{
s_DidAddRenderers = true;
AddBuiltInParticleRenderers();
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,887 @@
//===== Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose: particle system code
//
//===========================================================================//
#include "tier0/platform.h"
#include "particles/particles.h"
#include "filesystem.h"
#include "tier2/tier2.h"
#include "tier2/fileutils.h"
#include "tier1/UtlStringMap.h"
#include "tier1/strtools.h"
#ifdef USE_BLOBULATOR
// TODO: These should be in public by the time the SDK ships
#include "../common/blobulator/physics/physparticle.h"
#include "../common/blobulator/physics/physparticlecache_inl.h"
#include "../common/blobulator/physics/phystiler.h"
#endif
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
class C_OP_RandomForce : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_RandomForce );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return 0;
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
Vector m_MinForce;
Vector m_MaxForce;
};
void C_OP_RandomForce::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
FourVectors box_min,box_max;
box_min.DuplicateVector( m_MinForce * flStrength );
box_max.DuplicateVector( m_MaxForce * flStrength);
box_max -= box_min;
int nContext = GetSIMDRandContext();
for(int i=0;i<nBlocks;i++)
{
pAccumulatedForces->x = AddSIMD(
pAccumulatedForces->x, AddSIMD( box_min.x, MulSIMD( box_max.x, RandSIMD( nContext) ) ) );
pAccumulatedForces->y = AddSIMD(
pAccumulatedForces->y, AddSIMD( box_min.y, MulSIMD( box_max.y, RandSIMD( nContext) ) ) );
pAccumulatedForces->z = AddSIMD(
pAccumulatedForces->z, AddSIMD( box_min.z, MulSIMD( box_max.z, RandSIMD( nContext) ) ) );
pAccumulatedForces++;
}
ReleaseSIMDRandContext( nContext );
}
DEFINE_PARTICLE_OPERATOR( C_OP_RandomForce, "random force", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_RandomForce )
DMXELEMENT_UNPACK_FIELD( "min force", "0 0 0", Vector, m_MinForce )
DMXELEMENT_UNPACK_FIELD( "max force", "0 0 0", Vector, m_MaxForce )
END_PARTICLE_OPERATOR_UNPACK( C_OP_RandomForce )
class C_OP_ParentVortices : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_ParentVortices );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return PARTICLE_ATTRIBUTE_XYZ_MASK;
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
float m_flForceScale;
Vector m_vecTwistAxis;
bool m_bFlipBasedOnYaw;
};
struct VortexParticle_t
{
FourVectors m_v4Center;
FourVectors m_v4TwistAxis;
fltx4 m_fl4OORadius;
fltx4 m_fl4Strength;
};
void C_OP_ParentVortices::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
if ( pParticles->m_pParent && ( pParticles->m_pParent->m_nActiveParticles ) )
{
FourVectors Twist_AxisInWorldSpace;
Twist_AxisInWorldSpace.DuplicateVector( m_vecTwistAxis );
Twist_AxisInWorldSpace.VectorNormalize();
int nVortices = pParticles->m_pParent->m_nActiveParticles;
VortexParticle_t *pVortices = ( VortexParticle_t * ) stackalloc( nVortices * sizeof( VortexParticle_t ) );
for( int i = 0; i < nVortices; i++ )
{
pVortices[i].m_v4TwistAxis = Twist_AxisInWorldSpace;
pVortices[i].m_fl4OORadius = ReplicateX4( 1.0 / ( 0.00001 + *( pParticles->m_pParent->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_RADIUS, i ) ) ) );
pVortices[i].m_fl4OORadius = MulSIMD( pVortices[i].m_fl4OORadius, pVortices[i].m_fl4OORadius );
pVortices[i].m_fl4Strength = ReplicateX4( m_flForceScale * flStrength * ( * ( pParticles->m_pParent->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_ALPHA, i ) ) ) );
float const *pXYZ = pParticles->m_pParent->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_XYZ, i );
pVortices[i].m_v4Center.x = ReplicateX4( pXYZ[0] );
pVortices[i].m_v4Center.y = ReplicateX4( pXYZ[4] );
pVortices[i].m_v4Center.z = ReplicateX4( pXYZ[8] );
if ( m_bFlipBasedOnYaw )
{
float const *pYaw = pParticles->m_pParent->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_YAW, i );
if ( pYaw[0] >= M_PI )
{
pVortices[i].m_v4Center *= Four_NegativeOnes;
}
}
}
size_t nPosStride;
const FourVectors *pPos=pParticles->Get4VAttributePtr( PARTICLE_ATTRIBUTE_XYZ, &nPosStride );
for(int i=0; i < nBlocks ; i++)
{
FourVectors v4SumForces;
v4SumForces.x = Four_Zeros;
v4SumForces.y = Four_Zeros;
v4SumForces.z = Four_Zeros;
for( int v = 0; v < nVortices; v++ )
{
FourVectors v4Ofs = *pPos;
v4Ofs -= pVortices[v].m_v4Center;
fltx4 v4DistSQ = v4Ofs * v4Ofs;
bi32x4 bGoodLen = CmpGtSIMD( v4DistSQ, Four_Epsilons );
v4Ofs.VectorNormalize();
FourVectors v4Parallel_comp = v4Ofs;
v4Parallel_comp *= ( v4Ofs * pVortices[v].m_v4TwistAxis );
v4Ofs -= v4Parallel_comp;
bGoodLen = AndSIMD( bGoodLen, CmpGtSIMD( v4Ofs * v4Ofs, Four_Epsilons ) );
v4Ofs.VectorNormalize();
FourVectors v4TangentialForce = v4Ofs ^ pVortices[v].m_v4TwistAxis;
fltx4 fl4Strength = pVortices[v].m_fl4Strength;
fl4Strength = MulSIMD( fl4Strength, MaxSIMD( Four_Zeros, SubSIMD( Four_Ones, MulSIMD( v4DistSQ, pVortices[v].m_fl4OORadius ) ) ) ); // scale so strength = 0.0 at radius or farther
v4TangentialForce *= fl4Strength;
v4TangentialForce.x = AndSIMD( v4TangentialForce.x, bGoodLen );
v4TangentialForce.y = AndSIMD( v4TangentialForce.y, bGoodLen );
v4TangentialForce.z = AndSIMD( v4TangentialForce.z, bGoodLen );
v4SumForces += v4TangentialForce;
}
*( pAccumulatedForces++ ) += v4SumForces;
pPos += nPosStride;
}
}
}
DEFINE_PARTICLE_OPERATOR( C_OP_ParentVortices, "Create vortices from parent particles", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_ParentVortices )
DMXELEMENT_UNPACK_FIELD( "amount of force", "0", float, m_flForceScale )
DMXELEMENT_UNPACK_FIELD( "twist axis", "0 0 1", Vector, m_vecTwistAxis )
DMXELEMENT_UNPACK_FIELD( "flip twist axis with yaw","0", bool, m_bFlipBasedOnYaw )
END_PARTICLE_OPERATOR_UNPACK( C_OP_ParentVortices )
class C_OP_TwistAroundAxis : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_TwistAroundAxis );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return PARTICLE_ATTRIBUTE_XYZ_MASK;
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
float m_fForceAmount;
Vector m_TwistAxis;
bool m_bLocalSpace;
};
void C_OP_TwistAroundAxis::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
FourVectors Twist_AxisInWorldSpace;
Twist_AxisInWorldSpace.DuplicateVector( pParticles->TransformAxis( m_TwistAxis, m_bLocalSpace ) );
Twist_AxisInWorldSpace.VectorNormalize();
Vector vecCenter;
pParticles->GetControlPointAtTime( 0, pParticles->m_flCurTime, &vecCenter );
FourVectors Center;
Center.DuplicateVector( vecCenter );
size_t nPosStride;
fltx4 ForceScale = ReplicateX4( m_fForceAmount * flStrength );
const FourVectors *pPos=pParticles->Get4VAttributePtr( PARTICLE_ATTRIBUTE_XYZ, &nPosStride );
for(int i=0;i<nBlocks;i++)
{
FourVectors ofs=*pPos;
ofs -= Center;
bi32x4 bGoodLen = CmpGtSIMD( ofs*ofs, Four_Epsilons );
ofs.VectorNormalize();
FourVectors parallel_comp=ofs;
parallel_comp *= ( ofs*Twist_AxisInWorldSpace );
ofs-=parallel_comp;
bGoodLen = AndSIMD( bGoodLen, CmpGtSIMD( ofs*ofs, Four_Epsilons ) );
ofs.VectorNormalize();
FourVectors TangentialForce = ofs ^ Twist_AxisInWorldSpace;
TangentialForce *= ForceScale;
TangentialForce.x = AndSIMD( TangentialForce.x, bGoodLen );
TangentialForce.y = AndSIMD( TangentialForce.y, bGoodLen );
TangentialForce.z = AndSIMD( TangentialForce.z, bGoodLen );
*(pAccumulatedForces++) += TangentialForce;
pPos += nPosStride;
}
}
DEFINE_PARTICLE_OPERATOR( C_OP_TwistAroundAxis, "twist around axis", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_TwistAroundAxis )
DMXELEMENT_UNPACK_FIELD( "amount of force", "0", float, m_fForceAmount )
DMXELEMENT_UNPACK_FIELD( "twist axis", "0 0 1", Vector, m_TwistAxis )
DMXELEMENT_UNPACK_FIELD( "object local space axis 0/1","0", bool, m_bLocalSpace )
END_PARTICLE_OPERATOR_UNPACK( C_OP_TwistAroundAxis )
class C_OP_AttractToControlPoint : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_AttractToControlPoint );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return 0;
}
virtual uint64 GetReadControlPointMask() const
{
return 1ULL << m_nControlPointNumber;
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
float m_fForceAmount;
float m_fFalloffPower;
int m_nControlPointNumber;
};
void C_OP_AttractToControlPoint::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
int power_frac=-4.0*m_fFalloffPower; // convert to what pow_fixedpoint_exponent_simd wants
fltx4 fForceScale=ReplicateX4( -m_fForceAmount * flStrength );
Vector vecCenter;
pParticles->GetControlPointAtTime( m_nControlPointNumber, pParticles->m_flCurTime, &vecCenter );
FourVectors Center;
Center.DuplicateVector( vecCenter );
size_t nPosStride;
const FourVectors *pPos=pParticles->Get4VAttributePtr( PARTICLE_ATTRIBUTE_XYZ, &nPosStride );
for(int i=0;i<nBlocks;i++)
{
FourVectors ofs=*pPos;
ofs -= Center;
fltx4 len = ofs.length();
ofs *= MulSIMD( fForceScale, ReciprocalSaturateSIMD( len )); // normalize and scale
ofs *= Pow_FixedPoint_Exponent_SIMD( len, power_frac ); // * 1/pow(dist, exponent)
bi32x4 bGood = CmpGtSIMD( len, Four_Epsilons );
ofs.x = AndSIMD( bGood, ofs.x );
ofs.y = AndSIMD( bGood, ofs.y );
ofs.z = AndSIMD( bGood, ofs.z );
*(pAccumulatedForces++) += ofs;
pPos += nPosStride;
}
}
DEFINE_PARTICLE_OPERATOR( C_OP_AttractToControlPoint, "Pull towards control point", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_AttractToControlPoint )
DMXELEMENT_UNPACK_FIELD( "amount of force", "0", float, m_fForceAmount )
DMXELEMENT_UNPACK_FIELD( "falloff power", "2", float, m_fFalloffPower )
DMXELEMENT_UNPACK_FIELD( "control point number", "0", int, m_nControlPointNumber )
END_PARTICLE_OPERATOR_UNPACK( C_OP_AttractToControlPoint )
class C_OP_ForceBasedOnDistanceToPlane : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_ForceBasedOnDistanceToPlane );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return 0;
}
virtual uint64 GetReadControlPointMask() const
{
return 1ULL << m_nControlPointNumber;
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
float m_flMinDist;
Vector m_vecForceAtMinDist;
float m_flMaxDist;
Vector m_vecForceAtMaxDist;
Vector m_vecPlaneNormal;
int m_nControlPointNumber;
float m_flExponent;
};
void C_OP_ForceBasedOnDistanceToPlane::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
float flDeltaDistances = m_flMaxDist - m_flMinDist;
fltx4 fl4OORange = Four_Zeros;
if ( flDeltaDistances )
{
fl4OORange = ReplicateX4( 1.0 / flDeltaDistances );
}
Vector vecPointOnPlane = pParticles->GetControlPointAtCurrentTime( m_nControlPointNumber );
FourVectors v4PointOnPlane;
v4PointOnPlane.DuplicateVector( vecPointOnPlane );
FourVectors v4PlaneNormal;
v4PlaneNormal.DuplicateVector( m_vecPlaneNormal );
fltx4 fl4MinDist = ReplicateX4( m_flMinDist );
C4VAttributeIterator pXYZ( PARTICLE_ATTRIBUTE_XYZ, pParticles );
FourVectors v4Force0;
v4Force0.DuplicateVector( m_vecForceAtMinDist );
FourVectors v4ForceDelta;
v4ForceDelta.DuplicateVector( m_vecForceAtMaxDist - m_vecForceAtMinDist );
int nPowValue = 4.0 * m_flExponent;
for(int i=0 ; i < nBlocks ; i++)
{
FourVectors v4Ofs = *pXYZ;
v4Ofs -= v4PointOnPlane;
fltx4 fl4DistanceFromPlane = v4Ofs * v4PlaneNormal;
fl4DistanceFromPlane = MulSIMD( SubSIMD( fl4DistanceFromPlane, fl4MinDist ), fl4OORange );
fl4DistanceFromPlane = MaxSIMD( Four_Zeros, MinSIMD( Four_Ones, fl4DistanceFromPlane ) );
fl4DistanceFromPlane = Pow_FixedPoint_Exponent_SIMD( fl4DistanceFromPlane, nPowValue );
// now, calculate lerped force
FourVectors v4OutputForce = v4ForceDelta;
v4OutputForce *= fl4DistanceFromPlane;
v4OutputForce += v4Force0;
*( pAccumulatedForces++ ) += v4OutputForce;
++pXYZ;
}
}
DEFINE_PARTICLE_OPERATOR( C_OP_ForceBasedOnDistanceToPlane, "Force based on distance from plane", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_ForceBasedOnDistanceToPlane )
DMXELEMENT_UNPACK_FIELD( "Min distance from plane", "0", float, m_flMinDist )
DMXELEMENT_UNPACK_FIELD( "Force at Min distance", "0 0 0", Vector, m_vecForceAtMinDist )
DMXELEMENT_UNPACK_FIELD( "Max Distance from plane", "1", float, m_flMaxDist )
DMXELEMENT_UNPACK_FIELD( "Force at Max distance", "0 0 0", Vector, m_vecForceAtMaxDist )
DMXELEMENT_UNPACK_FIELD( "Plane Normal", "0 0 1", Vector, m_vecPlaneNormal )
DMXELEMENT_UNPACK_FIELD( "Control point number", "0", int, m_nControlPointNumber )
DMXELEMENT_UNPACK_FIELD( "Exponent", "1", float, m_flExponent )
END_PARTICLE_OPERATOR_UNPACK( C_OP_ForceBasedOnDistanceToPlane )
#undef USE_BLOBULATOR // TODO (Ilya): Must fix this code
#ifdef USE_BLOBULATOR
class C_OP_LennardJonesForce : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_LennardJonesForce );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return 0;
}
void InitParams( CParticleSystemDefinition *pDef, CDmxElement *pElement )
{
//m_pParticleCache = new ParticleCache(m_fInteractionRadius);
m_pPhysTiler = new PhysTiler(m_fInteractionRadius);
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
// TODO: Have to destroy PhysTiler in destructor somewhere!!!!
//ParticleCache* m_pParticleCache;
PhysTiler* m_pPhysTiler;
float m_fInteractionRadius;
float m_fSurfaceTension;
float m_fLennardJonesRepulsion;
float m_fLennardJonesAttraction;
float m_fMaxRepulsion;
float m_fMaxAttraction;
private:
//virtual void addParticleForce(PhysParticle* a, PhysParticleCacheNode* bcn, float flStrength, float ts) const;
virtual void addParticleForce(PhysParticle* a, PhysParticle* b, float distSq, float flStrength, float ts) const;
};
// TODO: I should make sure I don't have divide by zero errors.
// TODO: ts is not used
void C_OP_LennardJonesForce::addParticleForce(PhysParticle* a, PhysParticle* b, float distSq, float flStrength, float ts) const
{
float d = sqrtf(distSq);
//========================================================
// based on equation of force between two molecules which is
// factor * ((distance/bond_length)^-7 - (distance/bond_length)^-13)
float f;
if(a->group == b->group) // In the same group
{
float p = a->radius * 2.0f / (d+FLT_EPSILON);
float p2 = p * p;
float p4 = p2 * p2;
// Surface tension:
//Notes:
// Can average the neighbor count between the two particles...
// I tried this, and discovered that rather than averaging, I can take maybe take the
// larger of the two neighbor counts, so the attraction between two particles on the surface will be strong, but
// the attraction between a particle inside and a particle on the surface will be weak. I can also try
// taking the min so that the attraction between a particle on the surface and a particle inside the fluid will
// be strong, but the attraction between two particles completely on the inside will be weak.
//
// int symmetric_neighbor_count = min(a->neighbor_count, b->neighbor_count);
//
// Can try having neighbors only cause stronger attraction (no repulsion)
// Can try lower exponents for the LennardJones forces.
// This is a trick to prevent single particles from floating off... the less neighbors a particle has.. the more it sticks
// This also tends to simulate surface tension
float surface_tension_modifier = ((24.0f * m_fSurfaceTension) / (a->neighbor_count + b->neighbor_count + 0.1f)) + 1.0f;
//float lennard_jones_force = fLennardJones * 2.0f * (p2 - (p4 * p4));
float lennard_jones_force = m_fLennardJonesAttraction * p2 - m_fLennardJonesRepulsion*p4;
f = surface_tension_modifier * lennard_jones_force;
// This is some older code:
//f = ((35.0f * LampScene::simulationSurfaceTension) / (a->neighbor_count + 0.1f)) * (p2 - (p4 * p4));
// used to be 68'
//float factor = (b->neighbor_count < 13 && neighbor_count < 13 ? 4.0f : 0.5f);
//f = factor * (p2 - (p2 * p2 * p2 * p2));
}
else
{
// This was 3.5 ... made 3.0 so particles get closer when they collide
if(d > a->radius * 3.0f) return;
float p = a->radius * 4.0f / d;
f = -1.0f * p * p;
}
// These checks are great to have, but are they really necessary?
// It might also be good to have a limit on velocity
// Attraction is a positive value.
// Repulsion is negative.
if(f < -m_fMaxRepulsion) f = -m_fMaxRepulsion;
if(f > m_fMaxAttraction) f = m_fMaxAttraction;
Point3D scaledr = (b->center - a->center) * (f/(d+FLT_EPSILON)); // Dividing by d scales distance down to a unit vector
a->force.add(scaledr);
b->force.subtract(scaledr);
}
void C_OP_LennardJonesForce::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
int nParticles = pParticles->m_nActiveParticles; // Not sure if this is correct!
size_t nPosStride;
const FourVectors *pPos=pParticles->Get4VAttributePtr( PARTICLE_ATTRIBUTE_XYZ, &nPosStride );
// The +4 is because particles are stored by PET in blocks of 4
// However, not every block is full. Thus, nParticles may be
// less than nBlocks*4. Could get rid of this if the swizzling/unswizzling
// loop were better written.
static SmartArray<PhysParticle> imp_particles_sa; // This doesn't specify alignment, might have problems with SSE
while(imp_particles_sa.size < nParticles+4)
{
imp_particles_sa.pushAutoSize(PhysParticle());
}
/*
size_t nPrevPosStride;
const FourVectors *pPrevPos=pParticles->Get4VAttributePtr( PARTICLE_ATTRIBUTE_PREV_XYZ, &nPrevPosStride );
*/
//m_pParticleCache->beginFrame();
//m_pParticleCache->beginTile(nParticles);
m_pPhysTiler->beginFrame(Point3D(0.0f, 0.0f, 0.0f));
// Unswizzle from the FourVectors format into particles
for(int i=0, p=0;i<nBlocks;i++)
{
FourVectors ofs=*pPos;
PhysParticle* particle = &(imp_particles_sa[p]);
particle->force.clear();
if(p < nParticles)
{
particle->center = ofs.Vec(0);
particle->group = 0;
particle->neighbor_count = 0;
m_pPhysTiler->insertParticle(particle);
}
p++;
particle = &(imp_particles_sa[p]);
particle->force.clear();
if(p < nParticles)
{
particle->center = ofs.Vec(1);
particle->group = 0;
particle->neighbor_count = 0;
m_pPhysTiler->insertParticle(particle);
}
p++;
particle = &(imp_particles_sa[p]);
particle->force.clear();
if(p < nParticles)
{
particle->center = ofs.Vec(2);
particle->group = 0;
particle->neighbor_count = 0;
m_pPhysTiler->insertParticle(particle);
}
p++;
particle = &(imp_particles_sa[p]);
particle->force.clear();
if(p < nParticles)
{
particle->center = ofs.Vec(3);
particle->group = 0;
particle->neighbor_count = 0;
m_pPhysTiler->insertParticle(particle);
}
p++;
pPos += nPosStride;
}
m_pPhysTiler->processTiles();
float timeStep = 1.0f; // This should be customizable
float nearNeighborInteractionRadius = 2.3f;
float nearNeighborInteractionRadiusSq = nearNeighborInteractionRadius * nearNeighborInteractionRadius;
PhysParticleCache* pCache = m_pPhysTiler->getParticleCache();
// Calculate number of near neighbors for each particle
for(int i = 0; i < nParticles; i++)
{
PhysParticle *b1 = &(imp_particles_sa[i]);
PhysParticleAndDist* node = pCache->get(b1);
while(node->particle != NULL)
{
PhysParticle* b2 = node->particle;
// Compare addresses of the two particles. This makes sure we apply a force only once between a pair of particles.
if(b1 < b2 && node->distSq < nearNeighborInteractionRadiusSq)
{
b1->neighbor_count++;
b2->neighbor_count++;
}
node++;
}
}
// Calculate forces on particles due to other particles
for(int i = 0; i < nParticles; i++)
{
PhysParticle *b1 = &(imp_particles_sa[i]);
PhysParticleAndDist* node = pCache->get(b1);
while(node->particle != NULL)
{
PhysParticle* b2 = node->particle;
// Compare addresses of the two particles. This makes sure we apply a force only once between a pair of particles.
if(b1 < b2)
{
addParticleForce(b1, b2, node->distSq, flStrength, timeStep);
}
node++;
}
}
/*
for(ParticleListNode* bit3 = particles; bit3; bit3 = bit3->next)
{
Particle* b = bit3->particle;
b->prev_group = b->group; // Set prev group
//b1->addDirDragForce();
b->move(ts); // Move the particle (it should never be used again until next iteration)
}
*/
m_pPhysTiler->endFrame();
// Swizzle forces back into FourVectors format
for(int i=0;i<nBlocks;i++)
{
pAccumulatedForces->X(0) += imp_particles_sa[i*4].force[0];
pAccumulatedForces->Y(0) += imp_particles_sa[i*4].force[1];
pAccumulatedForces->Z(0) += imp_particles_sa[i*4].force[2];
pAccumulatedForces->X(1) += imp_particles_sa[i*4+1].force[0];
pAccumulatedForces->Y(1) += imp_particles_sa[i*4+1].force[1];
pAccumulatedForces->Z(1) += imp_particles_sa[i*4+1].force[2];
pAccumulatedForces->X(2) += imp_particles_sa[i*4+2].force[0];
pAccumulatedForces->Y(2) += imp_particles_sa[i*4+2].force[1];
pAccumulatedForces->Z(2) += imp_particles_sa[i*4+2].force[2];
pAccumulatedForces->X(3) += imp_particles_sa[i*4+3].force[0];
pAccumulatedForces->Y(3) += imp_particles_sa[i*4+3].force[1];
pAccumulatedForces->Z(3) += imp_particles_sa[i*4+3].force[2];
pAccumulatedForces++;
}
}
DEFINE_PARTICLE_OPERATOR( C_OP_LennardJonesForce, "lennard jones force", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_LennardJonesForce )
DMXELEMENT_UNPACK_FIELD( "interaction radius", "4", float, m_fInteractionRadius )
DMXELEMENT_UNPACK_FIELD( "surface tension", "1", float, m_fSurfaceTension )
DMXELEMENT_UNPACK_FIELD( "lennard jones attractive force", "1", float, m_fLennardJonesAttraction )
DMXELEMENT_UNPACK_FIELD( "lennard jones repulsive force", "1", float, m_fLennardJonesRepulsion )
DMXELEMENT_UNPACK_FIELD( "max repulsion", "100", float, m_fMaxRepulsion )
DMXELEMENT_UNPACK_FIELD( "max attraction", "100", float, m_fMaxAttraction )
END_PARTICLE_OPERATOR_UNPACK( C_OP_LennardJonesForce )
#endif
class C_OP_TimeVaryingForce : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_TimeVaryingForce );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return PARTICLE_ATTRIBUTE_CREATION_TIME_MASK;
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
float m_flStartLerpTime;
Vector m_StartingForce;
float m_flEndLerpTime;
Vector m_EndingForce;
};
void C_OP_TimeVaryingForce::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
FourVectors box_min,box_max;
box_min.DuplicateVector( m_StartingForce * flStrength );
box_max.DuplicateVector( m_EndingForce * flStrength);
box_max -= box_min;
CM128AttributeIterator pCreationTime( PARTICLE_ATTRIBUTE_CREATION_TIME, pParticles );
fltx4 fl4StartTime = ReplicateX4( m_flStartLerpTime );
fltx4 fl4OODuration = ReplicateX4( 1.0 / ( m_flEndLerpTime - m_flStartLerpTime ) );
fltx4 fl4CurTime = pParticles->m_fl4CurTime;
for(int i=0;i<nBlocks;i++)
{
fltx4 fl4Age = SubSIMD( fl4CurTime, *pCreationTime );
fl4Age = MulSIMD( fl4OODuration, SubSIMD( fl4Age, fl4StartTime ) );
fl4Age = MaxSIMD( Four_Zeros, MinSIMD( Four_Ones, fl4Age ) );
FourVectors v4Force = box_max;
v4Force *= fl4Age;
v4Force += box_min;
(*pAccumulatedForces) += v4Force;
++pAccumulatedForces;
++pCreationTime;
}
}
DEFINE_PARTICLE_OPERATOR( C_OP_TimeVaryingForce, "time varying force", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_TimeVaryingForce )
DMXELEMENT_UNPACK_FIELD( "time to start transition", "0", float, m_flStartLerpTime )
DMXELEMENT_UNPACK_FIELD( "starting force", "0 0 0", Vector, m_StartingForce )
DMXELEMENT_UNPACK_FIELD( "time to end transition", "10", float, m_flEndLerpTime )
DMXELEMENT_UNPACK_FIELD( "ending force", "0 0 0", Vector, m_EndingForce )
END_PARTICLE_OPERATOR_UNPACK( C_OP_TimeVaryingForce )
class C_OP_TurbulenceForce : public CParticleOperatorInstance
{
DECLARE_PARTICLE_OPERATOR( C_OP_TurbulenceForce );
uint32 GetWrittenAttributes( void ) const
{
return 0;
}
uint32 GetReadAttributes( void ) const
{
return PARTICLE_ATTRIBUTE_XYZ_MASK;
}
virtual void AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const;
float m_flNoiseCoordScale[4];
Vector m_vecNoiseAmount[4];
};
void C_OP_TurbulenceForce::AddForces( FourVectors *pAccumulatedForces,
CParticleCollection *pParticles,
int nBlocks,
float flStrength,
void *pContext ) const
{
C4VAttributeIterator pXYZ( PARTICLE_ATTRIBUTE_XYZ, pParticles );
fltx4 fl4Scales[4];
FourVectors v4Amounts[4];
for( int i = 0; i < ARRAYSIZE( fl4Scales ); i++ )
{
fl4Scales[i] = ReplicateX4( m_flNoiseCoordScale[i] );
v4Amounts[i].DuplicateVector( m_vecNoiseAmount[i] );
}
for(int i=0;i<nBlocks;i++)
{
for( int j = 0; j < ARRAYSIZE( fl4Scales ); j++ )
{
FourVectors ppos = *pXYZ;
ppos *= fl4Scales[j];
ppos = DNoiseSIMD( ppos );
ppos *= v4Amounts[j];
(*pAccumulatedForces) += ppos;
}
++pAccumulatedForces;
++pXYZ;
}
}
DEFINE_PARTICLE_OPERATOR( C_OP_TurbulenceForce, "turbulent force", OPERATOR_GENERIC );
BEGIN_PARTICLE_OPERATOR_UNPACK( C_OP_TurbulenceForce )
DMXELEMENT_UNPACK_FIELD( "Noise scale 0", "1", float, m_flNoiseCoordScale[0] )
DMXELEMENT_UNPACK_FIELD( "Noise amount 0", "1 1 1", Vector, m_vecNoiseAmount[0] )
DMXELEMENT_UNPACK_FIELD( "Noise scale 1", "0", float, m_flNoiseCoordScale[1] )
DMXELEMENT_UNPACK_FIELD( "Noise amount 1", ".5 .5 .5", Vector, m_vecNoiseAmount[1] )
DMXELEMENT_UNPACK_FIELD( "Noise scale 2", "0", float, m_flNoiseCoordScale[2] )
DMXELEMENT_UNPACK_FIELD( "Noise amount 2", ".25 .25 .25", Vector, m_vecNoiseAmount[2] )
DMXELEMENT_UNPACK_FIELD( "Noise scale 3", "0", float, m_flNoiseCoordScale[3] )
DMXELEMENT_UNPACK_FIELD( "Noise amount 3", ".125 .125 .125", Vector, m_vecNoiseAmount[3] )
END_PARTICLE_OPERATOR_UNPACK( C_OP_TurbulenceForce )
void AddBuiltInParticleForceGenerators( void )
{
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_RandomForce );
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_TwistAroundAxis );
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_ParentVortices );
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_AttractToControlPoint );
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_TimeVaryingForce );
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_TurbulenceForce );
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_ForceBasedOnDistanceToPlane );
#ifdef USE_BLOBULATOR
REGISTER_PARTICLE_OPERATOR( FUNCTION_FORCEGENERATOR, C_OP_LennardJonesForce );
#endif
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,388 @@
//===== Copyright <20> 1996-2007, Valve Corporation, All rights reserved. ======//
//
// Purpose: see CParticleSnapshot declaration (in particles.h)
//
//===========================================================================//
#include "tier0/platform.h"
#include "particles/particles.h"
#include "filesystem.h"
#include "tier2/tier2.h"
#include "tier2/fileutils.h"
#include "tier1/utlbuffer.h"
#include "tier1/UtlStringMap.h"
#include "tier1/strtools.h"
#include "dmxloader/dmxloader.h"
#include "dmxloader/utlsoacontainer_serialization.h"
#include "tier1/lzmaDecoder.h"
#include "tier0/vprof.h"
#include "particles_internal.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// This macro is used to process the attribute mapping parameters, for both vararg versions of Init():
#define ATTRIBUTE_MAPPING_LOOP( _lastarg_ ) \
va_list args; \
va_start( args, _lastarg_ ); \
for(;;) \
{ \
int nFieldNumber = va_arg( args, int ); \
if ( nFieldNumber == -1 ) \
break; \
/* Associate nParticleAttribute with nFieldNumber */ \
int nParticleAttribute = va_arg( args, int );
//-----------------------------------------------------------------------------
// Purge, clear the container back to its initial state
//-----------------------------------------------------------------------------
void CParticleSnapshot::Purge( void )
{
m_Container.Purge();
m_pContainer = NULL;
for ( int i = 0; i < ARRAYSIZE( m_ParticleAttributeToContainerAttribute ); i++ ) m_ParticleAttributeToContainerAttribute[ i ] = -1;
for ( int i = 0; i < ARRAYSIZE( m_ContainerAttributeToParticleAttribute ); i++ ) m_ContainerAttributeToParticleAttribute[ i ] = -1;
}
//-----------------------------------------------------------------------------
// AddAttributeMapping, add a new field/attribute pair
//-----------------------------------------------------------------------------
bool CParticleSnapshot::AddAttributeMapping( int nFieldNumber, int nParticleAttribute, const char *pFunc )
{
if ( ( ( m_ParticleAttributeToContainerAttribute[ nParticleAttribute ] != -1 ) && ( m_ParticleAttributeToContainerAttribute[ nParticleAttribute ] != nFieldNumber ) ) ||
( ( m_ContainerAttributeToParticleAttribute[ nFieldNumber ] != -1 ) && ( m_ContainerAttributeToParticleAttribute[ nFieldNumber ] != nParticleAttribute ) ) )
{
Warning( "CParticleSnapshot::%s - Invalid attribute mapping specified (must be one-to-one)!\n", pFunc );
Assert( 0 );
Purge();
return false;
}
m_ParticleAttributeToContainerAttribute[ nParticleAttribute ] = nFieldNumber;
m_ContainerAttributeToParticleAttribute[ nFieldNumber ] = nParticleAttribute;
return true;
}
//-----------------------------------------------------------------------------
// ValidateAttributeMapping, check datatypes for a field/attribute pair
//-----------------------------------------------------------------------------
bool CParticleSnapshot::ValidateAttributeMapping( int nFieldNumber, int nParticleAttribute, const char *pFunc )
{
// Check the presence/datatype of each specified container field
// TODO: support unallocated attributes (requires different 'copy' implementations in operators - can't use memcpy!)
EAttributeDataType nExpectedDataType = g_pParticleSystemMgr->GetParticleAttributeDataType( nParticleAttribute );
if ( ( m_pContainer->GetAttributeType( nFieldNumber ) != nExpectedDataType ) || !m_pContainer->HasAllocatedMemory( nFieldNumber ) )
{
Warning( "CParticleSnapshot::%s - Invalid attribute mapping specified for the provided container!\n", pFunc );
if ( m_pContainer->GetAttributeType( nFieldNumber ) != nExpectedDataType )
Warning( " (data type of container field %d does not match particle attribute %s)\n", nFieldNumber, g_pParticleSystemMgr->GetParticleAttributeName( nParticleAttribute ) );
if ( !m_pContainer->HasAllocatedMemory( nFieldNumber ) )
Warning( " (container field %d has no allocated data)\n", nFieldNumber );
Assert( 0 );
Purge();
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Init, creating a new container with the specified attribute mapping
//-----------------------------------------------------------------------------
bool CParticleSnapshot::Init( int nX, int nY, int nZ, const AttributeMapVector &attributeMaps )
{
Assert( attributeMaps.Count() > 0 );
if ( attributeMaps.Count() <= 0 )
return false;
Assert( ( nX >= 1 ) && ( nY >= 1 ) && ( nZ >= 1 ) );
if ( ( nX < 1 ) || ( nY < 1 ) || ( nZ < 1 ) )
return false;
Purge();
m_pContainer = &m_Container;
for ( int i = 0; i < attributeMaps.Count(); i++ )
{
int nFieldNumber = attributeMaps[ i ].m_nContainerAttribute;
int nParticleAttribute = attributeMaps[ i ].m_nParticleAttribute;
if ( !AddAttributeMapping( nFieldNumber, nParticleAttribute, "Init" ) )
return false;
// Set the datatype of each specified container field
EAttributeDataType nDataType = g_pParticleSystemMgr->GetParticleAttributeDataType( nParticleAttribute );
m_Container.SetAttributeType( nFieldNumber, nDataType );
}
m_Container.AllocateData( nX, nY, nZ );
return true;
}
//-----------------------------------------------------------------------------
// Init, creating a new container with the specified attribute mapping
//-----------------------------------------------------------------------------
bool CParticleSnapshot::Init( int nX, int nY, int nZ, ... )
{
AttributeMapVector attributeMaps;
ATTRIBUTE_MAPPING_LOOP( nZ )
//{
attributeMaps.AddToTail( AttributeMap( nFieldNumber, nParticleAttribute ) );
}
return Init( nX, nY, nZ, attributeMaps );
}
//-----------------------------------------------------------------------------
// Init using an existing container, with the specified attribute mapping
//-----------------------------------------------------------------------------
bool CParticleSnapshot::InitExternal( CSOAContainer *pContainer, const AttributeMapVector &attributeMaps )
{
Assert( attributeMaps.Count() > 0 );
if ( attributeMaps.Count() <= 0 )
return false;
Purge();
m_pContainer = pContainer;
for ( int i = 0; i < attributeMaps.Count(); i++ )
{
int nFieldNumber = attributeMaps[ i ].m_nContainerAttribute;
int nParticleAttribute = attributeMaps[ i ].m_nParticleAttribute;
if ( !AddAttributeMapping( nFieldNumber, nParticleAttribute, "InitExternal" ) ||
!ValidateAttributeMapping( nFieldNumber, nParticleAttribute, "InitExternal" ) )
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Init using an existing container, with the specified attribute mapping
//-----------------------------------------------------------------------------
bool CParticleSnapshot::InitExternal( CSOAContainer *pContainer, ... )
{
AttributeMapVector attributeMaps;
ATTRIBUTE_MAPPING_LOOP( pContainer )
//{
attributeMaps.AddToTail( AttributeMap( nFieldNumber, nParticleAttribute ) );
}
return InitExternal( pContainer, attributeMaps );
}
//-----------------------------------------------------------------------------
// Unpack structure for CParticleSnapshot
//-----------------------------------------------------------------------------
BEGIN_DMXELEMENT_UNPACK( CParticleSnapshot )
DMXELEMENT_UNPACK_FIELD_ARRAY( "particle_attribute_to_container_attribute", "-1", int, m_ParticleAttributeToContainerAttribute )
DMXELEMENT_UNPACK_FIELD_ARRAY( "container_attribute_to_particle_attribute", "-1", int, m_ContainerAttributeToParticleAttribute )
END_DMXELEMENT_UNPACK( CParticleSnapshot, s_pParticleSnapshotUnpack )
//-----------------------------------------------------------------------------
// Check whether the particle system's defined attributes have changed
//-----------------------------------------------------------------------------
void CParticleSnapshot::CheckParticleAttributesForChanges( void )
{
// If this doesn't compile, then we need to bump the file version and perform fixup on files saved w/ the old attribute definitions:
// TODO: store out an array of attribute names (g_pParticleSystemMgr->GetParticleAttributeName()) with the data so the fixup can be automatic and general
COMPILE_TIME_ASSERT( MAX_PARTICLE_ATTRIBUTES == 24 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_XYZ == 0 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_LIFE_DURATION == 1 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_PREV_XYZ == 2 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_RADIUS == 3 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_ROTATION == 4 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_ROTATION_SPEED == 5 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_TINT_RGB == 6 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_ALPHA == 7 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_CREATION_TIME == 8 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_SEQUENCE_NUMBER == 9 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_TRAIL_LENGTH == 10 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_PARTICLE_ID == 11 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_YAW == 12 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_SEQUENCE_NUMBER1 == 13 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_HITBOX_INDEX == 14 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_HITBOX_RELATIVE_XYZ == 15 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_ALPHA2 == 16 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_SCRATCH_VEC == 17 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_SCRATCH_FLOAT == 18 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_UNUSED == 19 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_PITCH == 20 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_NORMAL == 21 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_GLOW_RGB == 22 );
COMPILE_TIME_ASSERT( PARTICLE_ATTRIBUTE_GLOW_ALPHA == 23 );
}
//-----------------------------------------------------------------------------
// Init from a DMX (.psf) file
//-----------------------------------------------------------------------------
bool CParticleSnapshot::Unserialize( const char *pFullPath )
{
DECLARE_DMX_CONTEXT();
CheckParticleAttributesForChanges();
CDmxElement *pRootElement = NULL;
bool bTextMode = true, bBinaryMode = false;
if ( !UnserializeDMX( pFullPath, "GAME", bTextMode, &pRootElement ) &&
!UnserializeDMX( pFullPath, "GAME", bBinaryMode, &pRootElement ) ) // TODO: shouldn't UnserializeDMX automatically detect text mode?
{
Warning( "ERROR: CParticleSnapshot::Unserialize - could not load file %s!\n", pFullPath );
return false;
}
bool bSuccess = true;
CDmxElement *pParticleSnapshotElement = pRootElement->GetValue< CDmxElement * >( "particle_snapshot" );
if ( !pParticleSnapshotElement )
{
Warning( "ERROR: CParticleSnapshot::Unserialize - %s is not a particle snapshot (.psf) file!\n", pFullPath );
bSuccess = false;
}
int nVersion = -1;
if ( bSuccess )
{
// Read the version number
nVersion = pParticleSnapshotElement->GetValue( "version", -1 );
if ( nVersion == -1 )
{
Warning( "ERROR: CParticleSnapshot::Unserialize - missing version field in file %s\n", pFullPath );
bSuccess = false;
}
}
if ( bSuccess )
{
// Read the CParticleSnapshot structure
Purge();
pParticleSnapshotElement->UnpackIntoStructure( this, s_pParticleSnapshotUnpack );
// Unserialize the embedded CSOAContainer:
CDmxElement *pContainerElement = pParticleSnapshotElement->GetValue< CDmxElement * >( "container" );
if ( !UnserializeCSOAContainer( &m_Container, pContainerElement ) )
{
Warning( "ERROR: CParticleSnapshot::Unserialize - error reading embedded CSOAContainer in file %s\n", pFullPath );
bSuccess = false;
}
}
if ( bSuccess )
{
// Update files saved in old versions
switch( nVersion )
{
case PARTICLE_SNAPSHOT_DMX_VERSION:
// Up to date - nothing to do.
break;
default:
// The DMX unpack structure will set reasonable defaults or flag stuff that needs fixing up
// TODO: add code when versions are bumped and fixup needs to happen
bSuccess = false;
break;
}
}
if ( bSuccess )
{
m_pContainer = &m_Container;
// Validate the attribute mapping (re-'add' it, in both directions, to be paranoid)
int nForwardMaps = 0, nReverseMaps = 0;
for ( int i = 0; i < ARRAYSIZE( m_ParticleAttributeToContainerAttribute ); i++ )
{
int nFieldNumber = m_ParticleAttributeToContainerAttribute[ i ];
if ( nFieldNumber == -1 )
continue;
if ( !AddAttributeMapping( nFieldNumber, i, "Unserialize" ) ||
!ValidateAttributeMapping( nFieldNumber, i, "Unserialize" ) )
{
bSuccess = false;
break;
}
nForwardMaps++;
}
for ( int i = 0; i < ARRAYSIZE( m_ContainerAttributeToParticleAttribute ); i++ )
{
int nParticleAttribute = m_ContainerAttributeToParticleAttribute[ i ];
if ( nParticleAttribute == -1 )
continue;
if ( !AddAttributeMapping( i, nParticleAttribute, "Unserialize" ) ||
!ValidateAttributeMapping( i, nParticleAttribute, "Unserialize" ) )
{
bSuccess = false;
break;
}
nReverseMaps++;
}
if ( bSuccess && ( !nForwardMaps || !nReverseMaps ) )
{
bSuccess = false;
Warning( "ERROR: CParticleSnapshot::Unserialize - error in data in file %s (no attribute mapping specified)\n", pFullPath );
Assert( 0 );
}
}
if ( !bSuccess )
{
// Leave a beautiful corpse
Purge();
}
CleanupDMX( pRootElement );
return bSuccess;
}
//-----------------------------------------------------------------------------
// Write out to a DMX (.psf) file
//-----------------------------------------------------------------------------
bool CParticleSnapshot::Serialize( const char *pFullPath, bool bTextMode )
{
DECLARE_DMX_CONTEXT();
if ( !IsValid() )
{
Warning( "ERROR: CParticleSnapshot::Serialize - cannot serialize an uninitialized CParticleSnapshot! (%s)\n", pFullPath );
return false;
}
const char *pExtension = V_GetFileExtension( pFullPath );
if ( !pExtension || Q_stricmp( pExtension, "psf" ) )
{
Warning( "ERROR: CParticleSnapshot::Serialize - file extension should be '.psf' (%s)\n", pFullPath );
return false;
}
bool bSuccess = true;
CDmxElement *pRootElement = CreateDmxElement( "CDmeElement" );
{
CDmxElementModifyScope modifyRoot( pRootElement );
// Write the version number first
CDmxElement *pParticleSnapshotElement = CreateDmxElement( "CDmeParticleSnapshot" );
pRootElement->SetValue( "particle_snapshot", pParticleSnapshotElement );
int nDmxVersion = PARTICLE_SNAPSHOT_DMX_VERSION;
pParticleSnapshotElement->SetValue( "version", nDmxVersion );
// Then all our member variables
pParticleSnapshotElement->AddAttributesFromStructure( this, s_pParticleSnapshotUnpack );
// Then the embedded container
CDmxElement *pContainerElement = CreateDmxElement( "CDmeSOAContainer" );
pParticleSnapshotElement->SetValue( "container", pContainerElement );
if ( !SerializeCSOAContainer( m_pContainer, pContainerElement ) )
{
Warning( "ERROR: CParticleSnapshot::Serialize - error serializing embedded CSOAContainer for file %s\n", pFullPath );
bSuccess = false;
}
}
if ( bSuccess )
{
// Write out the file
bSuccess = SerializeDMX( pFullPath, "GAME", bTextMode, pRootElement );
}
CleanupDMX( pRootElement );
return bSuccess;
}

606
particles/particle_sort.cpp Normal file
View File

@@ -0,0 +1,606 @@
//===== Copyright 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose: particle system code
//
//===========================================================================//
#include <algorithm>
#include "tier0/platform.h"
#include "tier0/vprof.h"
#include "particles/particles.h"
#include "particles_internal.h"
#include "bitmap/psheet.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define SORTBUFSIZE0 (( MAX_PARTICLES_IN_A_SYSTEM + 4 ) * sizeof( ParticleRenderData_t ) )
#define SORTBUFSIZE1 ( ( 1 + MAX_PARTICLES_IN_A_SYSTEM / 4 )* sizeof( ParticleFullRenderData_Scalar_View ) )
#define SORTBUFSIZE2 ( ( 1 + MAX_PARTICLES_IN_A_SYSTEM / 4 )* sizeof( ParticleRenderDataWithOutlineInformation_Scalar_View ) )
static ALIGN16 uint8 s_SortBuffer[ COMPILETIME_MAX( COMPILETIME_MAX( SORTBUFSIZE0, SORTBUFSIZE1 ), SORTBUFSIZE2 )] ALIGN16_POST;
static ALIGN16 ParticleFullRenderData_Scalar_View *s_pParticlePtrs[MAX_PARTICLES_IN_A_SYSTEM] ALIGN16_POST;
enum EParticleSortKeyType
{
SORT_KEY_NONE,
SORT_KEY_DISTANCE,
SORT_KEY_CREATION_TIME,
};
void C4VInterpolatedAttributeIterator::Init( int nAttribute, CParticleCollection *pParticles )
{
// initializing this is somewhat complicated by the behavior of prev_xyz and xyz
m_pData = pParticles->Get4VAttributePtr( nAttribute, &m_nStride );
Assert( pParticles->GetPrevAttributeMemory() );
if ( m_nStride )
{
m_nOldDataOffset =
pParticles->m_PreviousFrameAttributes.ByteAddress( nAttribute ) - pParticles->m_ParticleAttributes.ByteAddress( nAttribute );
}
else
{
// it's constant data
m_nOldDataOffset = 0;
}
}
template<EParticleSortKeyType eSortKeyMode, bool bCull> void s_GenerateData( void *pOutData, Vector CameraPos, Vector *pCameraFwd,
CParticleVisibilityData *pVisibilityData, CParticleCollection *pParticles )
{
fltx4 *pOutUnSorted = reinterpret_cast<fltx4 *>( pOutData );
C4VAttributeIterator pXYZ( PARTICLE_ATTRIBUTE_XYZ, pParticles );
CM128AttributeIterator pCreationTimeStamp( PARTICLE_ATTRIBUTE_CREATION_TIME, pParticles );
CM128AttributeIterator pAlpha( PARTICLE_ATTRIBUTE_ALPHA, pParticles );
CM128AttributeIterator pAlpha2( PARTICLE_ATTRIBUTE_ALPHA2, pParticles );
CM128AttributeIterator pRadius( PARTICLE_ATTRIBUTE_RADIUS, pParticles );
int nParticles = pParticles->m_nActiveParticles;
FourVectors EyePos;
EyePos.DuplicateVector( CameraPos );
FourVectors v4Fwd;
if ( bCull )
v4Fwd.DuplicateVector( *pCameraFwd );
fltx4 fl4AlphaVis = ReplicateX4( pVisibilityData->m_flAlphaVisibility );
fltx4 fl4RadVis = ReplicateX4( pVisibilityData->m_flRadiusVisibility );
// indexing. We will generate the index as float and use magicf2i to convert to integer
fltx4 fl4OutIdx = g_SIMD_0123; // 0 1 2 3
fl4OutIdx = AddSIMD( fl4OutIdx, Four_2ToThe23s); // fix as int
bool bUseVis = pVisibilityData->m_bUseVisibility;
fltx4 fl4AlphaScale = ReplicateX4( 255.0 );
fltx4 fl4SortKey = Four_Zeros;
do
{
fltx4 fl4FinalAlpha = MulSIMD( *pAlpha, *pAlpha2 );
fltx4 fl4FinalRadius = *pRadius;
if ( bUseVis )
{
fl4FinalAlpha = MaxSIMD ( Four_Zeros, MinSIMD( Four_Ones, MulSIMD( fl4FinalAlpha, fl4AlphaVis) ) );
fl4FinalRadius = MulSIMD( fl4FinalRadius, fl4RadVis );
}
// convert float 0..1 to int 0..255
fl4FinalAlpha = AddSIMD( MulSIMD( fl4FinalAlpha, fl4AlphaScale ), Four_2ToThe23s );
if ( eSortKeyMode == SORT_KEY_CREATION_TIME )
{
fl4SortKey = *pCreationTimeStamp;
}
if ( bCull || ( eSortKeyMode == SORT_KEY_DISTANCE ) )
{
fltx4 fl4X = pXYZ->x;
fltx4 fl4Y = pXYZ->y;
fltx4 fl4Z = pXYZ->z;
fltx4 Xdiff = SubSIMD( fl4X, EyePos.x );
fltx4 Ydiff = SubSIMD( fl4Y, EyePos.y );
fltx4 Zdiff = SubSIMD( fl4Z, EyePos.z );
if ( bCull )
{
fltx4 dot = AddSIMD( MulSIMD( Xdiff, v4Fwd.x ),
AddSIMD(
MulSIMD( Ydiff, v4Fwd.y ),
MulSIMD( Zdiff, v4Fwd.z ) ) );
fl4FinalAlpha = AndSIMD( fl4FinalAlpha, CmpGeSIMD( dot, Four_Zeros ) );
}
if ( eSortKeyMode == SORT_KEY_DISTANCE )
{
fl4SortKey = AddSIMD( MulSIMD( Xdiff, Xdiff ),
AddSIMD( MulSIMD( Ydiff, Ydiff ),
MulSIMD( Zdiff, Zdiff ) ) );
}
}
// now, we will use simd transpose to write the output
fltx4 i4Indices = AndSIMD( fl4OutIdx, LoadAlignedSIMD( (float *) g_SIMD_Low16BitsMask ) );
TransposeSIMD( fl4SortKey, i4Indices, fl4FinalRadius, fl4FinalAlpha );
pOutUnSorted[0] = fl4SortKey;
pOutUnSorted[1] = i4Indices;
pOutUnSorted[2] = fl4FinalRadius;
pOutUnSorted[3] = fl4FinalAlpha;
pOutUnSorted += 4;
fl4OutIdx = AddSIMD( fl4OutIdx, Four_Fours );
nParticles -= 4;
++pXYZ;
++pAlpha;
++pAlpha2;
++pRadius;
} while( nParticles > 0 ); // we're not called with 0
}
#define TREATASINT(x) ( *( ( (int32 const *)( &(x) ) ) ) )
static bool SortLessFunc( const ParticleRenderData_t &left, const ParticleRenderData_t &right )
{
return TREATASINT( left.m_flSortKey ) < TREATASINT( right.m_flSortKey );
}
int CParticleCollection::GenerateSortedIndexList( ParticleRenderData_t *pOut, Vector vecCamera, CParticleVisibilityData *pVisibilityData, bool bSorted )
{
VPROF_BUDGET( "CParticleCollection::GenerateSortedIndexList", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
int nParticles = m_nActiveParticles;
if ( bSorted )
{
s_GenerateData<SORT_KEY_DISTANCE, false>( pOut, vecCamera, NULL, pVisibilityData, this );
}
else
s_GenerateData<SORT_KEY_NONE, false>( pOut, vecCamera, NULL, pVisibilityData, this );
if ( bSorted )
{
// sort the output in place
std::make_heap( pOut, pOut + nParticles, SortLessFunc );
std::sort_heap( pOut, pOut + nParticles, SortLessFunc );
}
return nParticles;
}
int CParticleCollection::GenerateCulledSortedIndexList(
ParticleRenderData_t *pOut, Vector vecCamera, Vector vecFwd, CParticleVisibilityData *pVisibilityData, bool bSorted )
{
VPROF_BUDGET( "CParticleCollection::GenerateSortedIndexList", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
int nParticles = m_nActiveParticles;
if ( bSorted )
{
s_GenerateData<SORT_KEY_DISTANCE, true>( pOut, vecCamera, &vecFwd, pVisibilityData, this );
}
else
s_GenerateData<SORT_KEY_NONE, true>( pOut, vecCamera, &vecFwd, pVisibilityData, this );
#ifndef SWDS
if ( bSorted )
{
// sort the output in place
std::make_heap( pOut, pOut + nParticles, SortLessFunc );
std::sort_heap( pOut, pOut + nParticles, SortLessFunc );
}
#endif
return nParticles;
}
const ParticleRenderData_t *CParticleCollection::GetRenderList( IMatRenderContext *pRenderContext,
bool bSorted, int *pNparticles,
CParticleVisibilityData *pVisibilityData)
{
if ( bSorted )
bSorted = m_pDef->m_bShouldSort;
Vector vecCamera;
pRenderContext->GetWorldSpaceCameraPosition( &vecCamera );
ParticleRenderData_t *pOut = ( ParticleRenderData_t * ) s_SortBuffer;
// check if the camera is inside the bounding box to see whether culling is worth it
int nParticles;
if ( vecCamera.WithinAABox( m_MinBounds, m_MaxBounds ) )
{
Vector vecFwd, vecRight, vecUp;
pRenderContext->GetWorldSpaceCameraVectors( &vecFwd, &vecRight, &vecUp );
nParticles = GenerateCulledSortedIndexList( pOut,
vecCamera, vecFwd,
pVisibilityData, bSorted );
}
else
{
// outside the bounds. don't bother agressive culling
nParticles = GenerateSortedIndexList( pOut, vecCamera, pVisibilityData, bSorted );
}
*pNparticles = nParticles;
return pOut + nParticles;
}
template<EParticleSortKeyType eSortKeyMode, bool bCull, bool bLerpCoords, class OutType_t, bool bDoColor2, bool bDoNormalVector, class VECTORITERATOR, class SCALARITERATOR>
void GenerateExtendedData(
void *pOutbuf, ParticleFullRenderData_Scalar_View **pIndexBuffer,
Vector CameraPos, Vector *pCameraFwd, CParticleVisibilityData *pVisibilityData, CParticleCollection *pParticles,
float flInterpT )
{
OutType_t * RESTRICT pOutUnSorted = reinterpret_cast<OutType_t*>( pOutbuf );
// interpolated values
VECTORITERATOR pXYZ( PARTICLE_ATTRIBUTE_XYZ, pParticles );
VECTORITERATOR pRGB( PARTICLE_ATTRIBUTE_TINT_RGB, pParticles );
VECTORITERATOR pRGB2;
SCALARITERATOR pAlpha( PARTICLE_ATTRIBUTE_ALPHA, pParticles );
SCALARITERATOR pAlpha2( PARTICLE_ATTRIBUTE_ALPHA2, pParticles );
SCALARITERATOR pRadius( PARTICLE_ATTRIBUTE_RADIUS, pParticles );
SCALARITERATOR pRot( PARTICLE_ATTRIBUTE_ROTATION, pParticles );
SCALARITERATOR pYaw( PARTICLE_ATTRIBUTE_YAW, pParticles );
SCALARITERATOR pGlowAlpha;
// non-interpolated values
CM128AttributeIterator pSeq( PARTICLE_ATTRIBUTE_SEQUENCE_NUMBER, pParticles );
CM128AttributeIterator pSeq1( PARTICLE_ATTRIBUTE_SEQUENCE_NUMBER1, pParticles );
CM128AttributeIterator pCreationTimeStamp( PARTICLE_ATTRIBUTE_CREATION_TIME, pParticles );
if ( bDoColor2 )
{
pGlowAlpha.Init( PARTICLE_ATTRIBUTE_GLOW_ALPHA, pParticles );
pRGB2.Init( PARTICLE_ATTRIBUTE_GLOW_RGB, pParticles );
}
C4VAttributeIterator pNormal;
if ( bDoNormalVector )
{
pNormal.Init( PARTICLE_ATTRIBUTE_NORMAL, pParticles );
}
int nParticles = pParticles->m_nActiveParticles;
fltx4 fl4CurTime;
fltx4 fl4MaximumCreationTimeToDraw = Four_2ToThe23s;
if ( bLerpCoords )
{
fl4CurTime = ReplicateX4( pParticles->m_flTargetDrawTime );
fl4MaximumCreationTimeToDraw = ReplicateX4( pParticles->m_flPrevSimTime );
}
else
{
fl4CurTime = pParticles->m_fl4CurTime;
}
fltx4 Four_256s = ReplicateX4( 256.0 );
fltx4 fl4T = ReplicateX4( flInterpT );
FourVectors EyePos;
EyePos.DuplicateVector( CameraPos );
FourVectors v4Fwd;
if ( bCull )
v4Fwd.DuplicateVector( *pCameraFwd );
fltx4 fl4AlphaVis = ReplicateX4( pVisibilityData->m_flAlphaVisibility );
fltx4 fl4RadVis = ReplicateX4( pVisibilityData->m_flRadiusVisibility );
bool bUseVis = pVisibilityData->m_bUseVisibility;
fltx4 fl4AlphaScale = ReplicateX4( 255.0 );
uint8 **pOutPtrs = reinterpret_cast<uint8 **>( pIndexBuffer );
do
{
// Note: UNDER NO CIRCUMSTANCES should you write through these
// pointers inside the scope of this function! pOutUnSorted is
// marked as __restrict, meaning that we have promised the compiler
// that it is unaliased. Therefore any writes through an alias
// will cause DOOM.
pOutPtrs[0] = reinterpret_cast<uint8 *>( pOutUnSorted );
pOutPtrs[1] = reinterpret_cast<uint8 *>( pOutUnSorted ) + sizeof( float );
pOutPtrs[2] = reinterpret_cast<uint8 *>( pOutUnSorted ) + 2 * sizeof( float );
pOutPtrs[3] = reinterpret_cast<uint8 *>( pOutUnSorted ) + 3 * sizeof( float );
fltx4 fl4FinalAlpha = MulSIMD( pAlpha( fl4T ), pAlpha2( fl4T ) );
fltx4 fl4FinalRadius = pRadius( fl4T );
if ( bUseVis )
{
fl4FinalAlpha = MaxSIMD ( Four_Zeros, MinSIMD( Four_Ones, MulSIMD( fl4FinalAlpha, fl4AlphaVis) ) );
fl4FinalRadius = MulSIMD( fl4FinalRadius, fl4RadVis );
}
// convert float 0..1 to int 0..255
fl4FinalAlpha = AddSIMD( MulSIMD( fl4FinalAlpha, fl4AlphaScale ), Four_2ToThe23s );
fltx4 fl4X = pXYZ.X( fl4T );
fltx4 fl4Y = pXYZ.Y( fl4T );
fltx4 fl4Z = pXYZ.Z( fl4T );
if ( eSortKeyMode == SORT_KEY_CREATION_TIME )
{
pOutUnSorted->m_fl4SortKey = *pCreationTimeStamp;
}
if ( bCull || ( eSortKeyMode == SORT_KEY_DISTANCE ) )
{
fltx4 Xdiff = SubSIMD( fl4X, EyePos.x );
fltx4 Ydiff = SubSIMD( fl4Y, EyePos.y );
fltx4 Zdiff = SubSIMD( fl4Z, EyePos.z );
if ( bCull )
{
fltx4 dot = AddSIMD( MulSIMD( Xdiff, v4Fwd.x ),
AddSIMD(
MulSIMD( Ydiff, v4Fwd.y ),
MulSIMD( Zdiff, v4Fwd.z ) ) );
fl4FinalAlpha = AndSIMD( fl4FinalAlpha, CmpGeSIMD( dot, Four_Zeros ) );
}
if ( eSortKeyMode == SORT_KEY_DISTANCE )
{
pOutUnSorted->m_fl4SortKey = AddSIMD( MulSIMD( Xdiff, Xdiff ),
AddSIMD( MulSIMD( Ydiff, Ydiff ),
MulSIMD( Zdiff, Zdiff ) ) );
}
}
fltx4 fl4Age = SubSIMD( fl4CurTime, *pCreationTimeStamp );
// if we are lerping, we need to supress particles which didn't exist on the last sim
if ( bLerpCoords )
{
fl4FinalAlpha = AndSIMD( fl4FinalAlpha, CmpLtSIMD( *pCreationTimeStamp, fl4MaximumCreationTimeToDraw ) );
}
pOutUnSorted->m_fl4XYZ.x = fl4X;
pOutUnSorted->m_fl4XYZ.y = fl4Y;
pOutUnSorted->m_fl4XYZ.z = fl4Z;
pOutUnSorted->m_fl4Alpha = fl4FinalAlpha;
pOutUnSorted->m_fl4Red = AddSIMD( MulSIMD( pRGB.X( fl4T ), fl4AlphaScale ), Four_2ToThe23s );
pOutUnSorted->m_fl4Green = AddSIMD( MulSIMD( pRGB.Y( fl4T ), fl4AlphaScale ), Four_2ToThe23s );
pOutUnSorted->m_fl4Blue = AddSIMD( MulSIMD( pRGB.Z( fl4T ), fl4AlphaScale ), Four_2ToThe23s );
pOutUnSorted->m_fl4Radius = fl4FinalRadius;
pOutUnSorted->m_fl4AnimationTimeValue = fl4Age;
pOutUnSorted->m_fl4Rotation = pRot( fl4T );
pOutUnSorted->m_fl4Yaw = pYaw( fl4T );
if ( pSeq1.Stride() )
{
pOutUnSorted->m_fl4SequenceID = AddSIMD( AddSIMD( *pSeq, MulSIMD( Four_256s, *pSeq1 ) ), Four_2ToThe23s );
}
else
{
pOutUnSorted->m_fl4SequenceID = AddSIMD( *pSeq, Four_2ToThe23s );
}
if ( bDoColor2 )
{
pOutUnSorted->SetARGB2( pRGB2.X( fl4T ), pRGB2.Y( fl4T ), pRGB2.Z( fl4T ), *pGlowAlpha );
++pRGB2;
++pGlowAlpha;
}
if ( bDoNormalVector )
{
pOutUnSorted->SetNormal( pNormal.X( fl4T ), pNormal.Y( fl4T ), pNormal.Z( fl4T ) );
++pNormal;
}
pOutUnSorted++;
nParticles -= 4;
pOutPtrs += 4;
++pXYZ;
++pAlpha;
++pAlpha2;
++pRadius;
++pRGB;
++pYaw;
++pRot;
++pSeq;
++pSeq1;
++pCreationTimeStamp;
} while( nParticles > 0 ); // we're not called with 0
}
template<EParticleSortKeyType eSortKeyMode, bool bCull, bool bLerpCoords, class OutType_t, bool bDoColor2,
bool bDoNormalVector>
void GenerateExtendedData(
void *pOutbuf, ParticleFullRenderData_Scalar_View **pIndexBuffer,
Vector CameraPos, Vector *pCameraFwd, CParticleVisibilityData *pVisibilityData, CParticleCollection *pParticles,
float flInterpT )
{
if ( bLerpCoords )
{
GenerateExtendedData<eSortKeyMode, bCull, true, OutType_t,
bDoColor2, bDoNormalVector, C4VInterpolatedAttributeIterator, CM128InterpolatedAttributeIterator>(
pOutbuf, pIndexBuffer, CameraPos, pCameraFwd, pVisibilityData, pParticles, flInterpT );
}
else
{
GenerateExtendedData<eSortKeyMode, bCull, false, OutType_t,
bDoColor2, bDoNormalVector, C4VAttributeIterator, CM128AttributeIterator>(
pOutbuf, pIndexBuffer, CameraPos, pCameraFwd, pVisibilityData, pParticles, flInterpT );
}
}
template<bool bCull, bool bLerpCoords, class OutType_t, bool bDoColor2, bool bDoNormal>
void s_GenerateExtendedData(
void *pOutbuf, ParticleFullRenderData_Scalar_View **pIndexBuffer,
Vector CameraPos, Vector *pCameraFwd, CParticleVisibilityData *pVisibilityData, CParticleCollection *pParticles,
float flInterpT, bool bSort )
{
if ( bSort )
{
GenerateExtendedData<SORT_KEY_DISTANCE, bCull, bLerpCoords, OutType_t, bDoColor2, bDoNormal>(
pOutbuf, pIndexBuffer,
CameraPos, pCameraFwd, pVisibilityData,
pParticles, flInterpT );
}
else
{
GenerateExtendedData<SORT_KEY_NONE, bCull, bLerpCoords, OutType_t, bDoColor2, bDoNormal>(
pOutbuf, pIndexBuffer,
CameraPos, pCameraFwd, pVisibilityData,
pParticles, flInterpT );
}
}
static bool SortLessFuncExtended( ParticleFullRenderData_Scalar_View * const &left, const ParticleFullRenderData_Scalar_View * const &right )
{
return left->m_nSortKey < right->m_nSortKey;
}
int GenerateExtendedSortedIndexList( Vector vecCamera, Vector *pCameraFwd, CParticleVisibilityData *pVisibilityData,
CParticleCollection *pParticles, bool bSorted, void *pOutBuf,
ParticleFullRenderData_Scalar_View **pParticlePtrs )
{
// check interpolation
if ( pParticles->IsUsingInterpolatedRendering() )
{
float t = ( pParticles->m_flTargetDrawTime - pParticles->m_flPrevSimTime ) /
( pParticles->m_flCurTime - pParticles->m_flPrevSimTime );
Assert( ( t >= 0.0 ) && ( t <= 1.0 ) );
s_GenerateExtendedData<false, true, ParticleFullRenderData_SIMD_View, false, false>( pOutBuf, pParticlePtrs, vecCamera, NULL, pVisibilityData, pParticles, t, bSorted );
}
else
{
s_GenerateExtendedData<false, false, ParticleFullRenderData_SIMD_View, false, false>( pOutBuf, pParticlePtrs, vecCamera, NULL, pVisibilityData, pParticles, 0., bSorted );
}
int nParticles = pParticles->m_nActiveParticles;
if ( bSorted )
{
// sort the output in place
std::make_heap( pParticlePtrs, pParticlePtrs + nParticles, SortLessFuncExtended );
std::sort_heap( pParticlePtrs, pParticlePtrs + nParticles, SortLessFuncExtended );
}
return nParticles;
}
int GenerateExtendedSortedIndexListWithPerParticleGlow(
Vector vecCamera, Vector *pCameraFwd, CParticleVisibilityData *pVisibilityData,
CParticleCollection *pParticles, bool bSorted, void *pOutBuf,
ParticleRenderDataWithOutlineInformation_Scalar_View **pParticlePtrs )
{
// check interpolation
if ( pParticles->IsUsingInterpolatedRendering() )
{
float t = ( pParticles->m_flTargetDrawTime - pParticles->m_flPrevSimTime ) /
( pParticles->m_flCurTime - pParticles->m_flPrevSimTime );
Assert( ( t >= 0.0 ) && ( t <= 1.0 ) );
s_GenerateExtendedData<false, true, ParticleRenderDataWithOutlineInformation_SIMD_View, true, false>(
pOutBuf, ( ParticleFullRenderData_Scalar_View **) pParticlePtrs, vecCamera, NULL, pVisibilityData, pParticles, t, bSorted );
}
else
{
s_GenerateExtendedData<false, false, ParticleRenderDataWithOutlineInformation_SIMD_View, true, false>(
pOutBuf, ( ParticleFullRenderData_Scalar_View **) pParticlePtrs, vecCamera, NULL, pVisibilityData, pParticles, 0., bSorted );
}
int nParticles = pParticles->m_nActiveParticles;
if ( bSorted )
{
// sort the output in place
std::make_heap( pParticlePtrs, pParticlePtrs + nParticles, SortLessFuncExtended );
std::sort_heap( pParticlePtrs, pParticlePtrs + nParticles, SortLessFuncExtended );
}
return nParticles;
}
int GenerateExtendedSortedIndexListWithNormals(
Vector vecCamera, Vector *pCameraFwd, CParticleVisibilityData *pVisibilityData,
CParticleCollection *pParticles, bool bSorted, void *pOutBuf,
ParticleRenderDataWithNormal_Scalar_View **pParticlePtrs )
{
// check interpolation
if ( pParticles->IsUsingInterpolatedRendering() )
{
float t = ( pParticles->m_flTargetDrawTime - pParticles->m_flPrevSimTime ) /
( pParticles->m_flCurTime - pParticles->m_flPrevSimTime );
Assert( ( t >= 0.0 ) && ( t <= 1.0 ) );
s_GenerateExtendedData<false, true, ParticleRenderDataWithNormal_SIMD_View, false, true>(
pOutBuf, ( ParticleFullRenderData_Scalar_View **) pParticlePtrs, vecCamera, NULL, pVisibilityData, pParticles, t, bSorted );
}
else
{
s_GenerateExtendedData<false, false, ParticleRenderDataWithNormal_SIMD_View, false, true>(
pOutBuf, ( ParticleFullRenderData_Scalar_View **) pParticlePtrs, vecCamera, NULL, pVisibilityData, pParticles, 0., bSorted );
}
int nParticles = pParticles->m_nActiveParticles;
if ( bSorted )
{
// sort the output in place
std::make_heap( pParticlePtrs, pParticlePtrs + nParticles, SortLessFuncExtended );
std::sort_heap( pParticlePtrs, pParticlePtrs + nParticles, SortLessFuncExtended );
}
return nParticles;
}
ParticleFullRenderData_Scalar_View **GetExtendedRenderList( CParticleCollection *pParticles,
IMatRenderContext *pRenderContext,
bool bSorted, int *pNparticles,
CParticleVisibilityData *pVisibilityData)
{
Assert( sizeof( ParticleFullRenderData_Scalar_View ) == sizeof( ParticleFullRenderData_SIMD_View ) );
if ( bSorted )
bSorted = pParticles->m_pDef->m_bShouldSort;
Vector vecCamera;
pRenderContext->GetWorldSpaceCameraPosition( &vecCamera );
int nParticles = GenerateExtendedSortedIndexList( vecCamera, NULL, pVisibilityData, pParticles, bSorted, s_SortBuffer, s_pParticlePtrs );
*pNparticles = nParticles;
return s_pParticlePtrs + nParticles;
}
ParticleRenderDataWithOutlineInformation_Scalar_View **GetExtendedRenderListWithPerParticleGlow(
CParticleCollection *pParticles,
IMatRenderContext *pRenderContext,
bool bSorted, int *pNparticles,
CParticleVisibilityData *pVisibilityData)
{
Assert( sizeof( ParticleRenderDataWithOutlineInformation_Scalar_View ) == sizeof( ParticleRenderDataWithOutlineInformation_SIMD_View ) );
if ( bSorted )
bSorted = pParticles->m_pDef->m_bShouldSort;
Vector vecCamera;
pRenderContext->GetWorldSpaceCameraPosition( &vecCamera );
int nParticles = GenerateExtendedSortedIndexListWithPerParticleGlow(
vecCamera, NULL, pVisibilityData, pParticles, bSorted, s_SortBuffer,
( ParticleRenderDataWithOutlineInformation_Scalar_View ** ) s_pParticlePtrs );
*pNparticles = nParticles;
return ( ParticleRenderDataWithOutlineInformation_Scalar_View ** ) ( s_pParticlePtrs + nParticles );
}
ParticleRenderDataWithNormal_Scalar_View **GetExtendedRenderListWithNormals(
CParticleCollection *pParticles,
IMatRenderContext *pRenderContext,
bool bSorted, int *pNparticles,
CParticleVisibilityData *pVisibilityData)
{
Assert( sizeof( ParticleRenderDataWithNormal_SIMD_View ) == sizeof( ParticleRenderDataWithNormal_Scalar_View ) );
if ( bSorted )
bSorted = pParticles->m_pDef->m_bShouldSort;
Vector vecCamera;
pRenderContext->GetWorldSpaceCameraPosition( &vecCamera );
int nParticles = GenerateExtendedSortedIndexListWithNormals(
vecCamera, NULL, pVisibilityData, pParticles, bSorted, s_SortBuffer,
( ParticleRenderDataWithNormal_Scalar_View ** ) s_pParticlePtrs );
*pNparticles = nParticles;
return ( ParticleRenderDataWithNormal_Scalar_View ** ) ( s_pParticlePtrs + nParticles );
}

4861
particles/particles.cpp Normal file

File diff suppressed because it is too large Load Diff

9
particles/particles.vpc Normal file
View File

@@ -0,0 +1,9 @@
//--------------------------------------------------------------------------------
// PARTICLES.VPC
//
// full particles.lib for the client.
//-----------------------------------------------------------------------------
$Macro PROJNAME "particles"
$include "particles_inc.vpc"

View File

@@ -0,0 +1,13 @@
"vpc_cache"
{
"CacheVersion" "1"
"win32"
{
"CRCFile" "particles.vcxproj.vpc_crc"
"OutputFiles"
{
"0" "particles.vcxproj"
"1" "particles.vcxproj.filters"
}
}
}

View File

@@ -0,0 +1,52 @@
//-----------------------------------------------------------------------------
// PARTICLES_INC.VPC
//
// Project Script template. used to define server and client particle lib projects
//-----------------------------------------------------------------------------
$Macro SRCDIR ".."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler [$WINDOWS || $PS3]
{
$PreprocessorDefinitions "$BASE;$EXTRADEFINES"
}
$Compiler [$X360]
{
$PreprocessorDefinitions "$BASE"
}
}
$Project $PROJNAME
{
$Folder "Source Files"
{
$File "../particles/builtin_constraints.cpp"
$File "../particles/builtin_initializers.cpp"
$File "../particles/builtin_particle_emitters.cpp"
$File "../particles/builtin_particle_forces.cpp"
$File "../particles/addbuiltin_ops.cpp"
$File "../particles/builtin_particle_ops.cpp"
$File "../particles/builtin_particle_render_ops.cpp"
$File "../particles/particle_snapshot.cpp"
$File "../particles/particle_sort.cpp"
$File "../particles/particles.cpp"
}
$Folder "Header Files"
{
$File "$SRCDIR\public\particles\particles.h"
$File "../particles/random_floats.h"
$File "../particles/particles_internal.h"
}
$Folder "Link Libraries" [$WINDOWS||$X360]
{
$Lib "bitmap"
}
}

View File

@@ -0,0 +1,61 @@
//===== Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose: sheet code for particles and other sprite functions
//
//===========================================================================//
#ifndef PARTICLES_INTERNAL_H
#define PARTICLES_INTERNAL_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/UtlStringMap.h"
#include "tier1/utlbuffer.h"
#include "tier2/fileutils.h"
#define MAX_WORLD_PLANAR_CONSTRAINTS ( 26 + 5 + 10 )
#define COLLISION_MODE_PER_PARTICLE_TRACE 0
#define COLLISION_MODE_PER_FRAME_PLANESET 1
#define COLLISION_MODE_INITIAL_TRACE_DOWN 2
#define COLLISION_MODE_USE_NEAREST_TRACE 3
#define PARTICLEBLEND_DEFAULT 0
#define PARTICLEBLEND_OVERLAY 1
#define PARTICLEBLEND_DARKEN 2
#define PARTICLEBLEND_LIGHTEN 3
#define PARTICLEBLEND_MULTIPLY 4
struct CWorldCollideContextData
{
FourVectors m_TraceStartPnt[MAX_WORLD_PLANAR_CONSTRAINTS];
FourVectors m_TraceEndPnt[MAX_WORLD_PLANAR_CONSTRAINTS];
FourVectors m_PointOnPlane[MAX_WORLD_PLANAR_CONSTRAINTS];
FourVectors m_PlaneNormal[MAX_WORLD_PLANAR_CONSTRAINTS];
int m_nActivePlanes;
int m_nNumFixedPlanes;
float m_flLastUpdateTime;
Vector m_vecLastUpdateOrigin;
bool m_bPlaneActive[MAX_WORLD_PLANAR_CONSTRAINTS];
void *operator new( size_t nSize );
void *operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine );
void operator delete(void *pData);
void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine );
void SetBaseTrace( int nIndex, Vector const &rayStart, Vector const &traceDir, int nCollisionGroup, bool bKeepMisses );
void CalculatePlanes( CParticleCollection *pParticles, int nCollisionMode, int nCollisionGroupNumber,
Vector const *pCpOffset = NULL, float flMovementTolerance = 0. );
};
// This is defined in the owner DLL
extern bool UTIL_IsDedicatedServer( void );
#endif // PARTICLES_INTERNAL_H

537
particles/random_floats.h Normal file
View File

@@ -0,0 +1,537 @@
//===== Copyright © 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose: static random floats for deterministic random #s in particle system
//
// $Workfile: $
// $NoKeywords: $
//===========================================================================//
//
// **** DO NOT EDIT THIS FILE. GENERATED BY DATAGEN.PL ****
//
#ifndef RANDOM_FLOATS_H
#define RANDOM_FLOATS_H
#ifdef _WIN32
#pragma once
#endif
ALIGN16 float s_pRandomFloats[]={
0.336914,0.671387,0.539307,0.165039,0.258301,0.146973,0.475342,0.993408,
0.882080,0.733887,0.152588,0.192871,0.873291,0.637939,0.859131,0.836914,
0.277344,0.026367,0.864502,0.327393,0.428711,0.684082,0.916992,0.935547,
0.643311,0.082764,0.033447,0.086182,0.575684,0.121826,0.342285,0.419189,
0.409424,0.177490,0.049072,0.252930,0.459717,0.561035,0.581543,0.470703,
0.662842,0.936035,0.912354,0.965332,0.523682,0.661865,0.484131,0.030029,
0.958984,0.370605,0.626709,0.736084,0.241943,0.307129,0.969482,0.269287,
0.215820,0.995605,0.300781,0.984375,0.621338,0.785645,0.432373,0.895264,
0.098389,0.857178,0.220947,0.981689,0.667969,0.898682,0.603027,0.588623,
0.206055,0.536133,0.245361,0.999023,0.758545,0.152100,0.015869,0.546387,
0.101563,0.920410,0.566650,0.793457,0.077148,0.675049,0.032715,0.645264,
0.654053,0.536377,0.599121,0.300537,0.404053,0.115967,0.646484,0.162842,
0.886230,0.412109,0.552490,0.632080,0.623291,0.846436,0.313965,0.505859,
0.487305,0.644287,0.517578,0.892090,0.146240,0.218750,0.484619,0.904785,
0.551758,0.809814,0.721191,0.871582,0.847656,0.062256,0.647949,0.708252,
0.690186,0.593750,0.061768,0.406982,0.169434,0.874756,0.139893,0.792236,
0.783691,0.855957,0.198975,0.706299,0.594971,0.739746,0.307373,0.123291,
0.480713,0.027100,0.697266,0.534424,0.070068,0.641602,0.472900,0.598145,
0.211670,0.977051,0.145264,0.311279,0.975098,0.904297,0.999268,0.725586,
0.039307,0.669434,0.578369,0.285889,0.867188,0.982666,0.797119,0.755371,
0.950195,0.383789,0.426270,0.337402,0.075439,0.841553,0.794678,0.074707,
0.021240,0.627686,0.036377,0.921143,0.229248,0.208740,0.698730,0.622803,
0.943848,0.673828,0.826416,0.107910,0.366943,0.352539,0.256592,0.930176,
0.556885,0.378418,0.205566,0.286133,0.623047,0.986328,0.781494,0.974609,
0.239014,0.883789,0.859375,0.884277,0.856445,0.521484,0.332764,0.489746,
0.880615,0.553955,0.961182,0.360352,0.489990,0.175781,0.777832,0.020020,
0.346436,0.250732,0.094482,0.900146,0.185547,0.317139,0.686768,0.517334,
0.350342,0.774902,0.978027,0.819580,0.967773,0.811523,0.038574,0.791504,
0.196045,0.543701,0.705566,0.586426,0.585449,0.016846,0.413086,0.583496,
0.772461,0.728271,0.289307,0.482666,0.389404,0.302002,0.331055,0.759277,
0.885742,0.745605,0.444092,0.341797,0.607422,0.436279,0.102783,0.874023,
0.868408,0.662109,0.287354,0.918701,0.892334,0.685791,0.500244,0.433594,
0.664795,0.734863,0.933350,0.078369,0.808105,0.790039,0.404541,0.005371,
0.976318,0.800537,0.482178,0.472412,0.656494,0.835449,0.713135,0.629395,
0.468506,0.038330,0.143555,0.375000,0.140381,0.427734,0.822754,0.267090,
0.253662,0.683350,0.788818,0.531738,0.214600,0.877930,0.659668,0.640381,
0.954346,0.227539,0.167969,0.491211,0.084473,0.272949,0.961670,0.065430,
0.696045,0.625732,0.177734,0.782715,0.934814,0.385742,0.401611,0.018555,
0.686279,0.749023,0.114014,0.106689,0.501709,0.471924,0.151855,0.088623,
0.677734,0.425293,0.910645,0.483398,0.872314,0.782471,0.163330,0.574463,
0.119385,0.809570,0.947510,0.197510,0.887207,0.577637,0.021484,0.020508,
0.641846,0.321533,0.957520,0.893555,0.625488,0.424072,0.612793,0.003906,
0.060059,0.388184,0.724365,0.195068,0.263184,0.919434,0.094971,0.550781,
0.997559,0.763916,0.300293,0.530029,0.583984,0.767578,0.745361,0.691650,
0.170410,0.762695,0.949463,0.349365,0.757324,0.302490,0.498047,0.397217,
0.213379,0.019775,0.587402,0.562988,0.573975,0.360840,0.320313,0.258545,
0.948486,0.186279,0.976563,0.190430,0.865723,0.162598,0.547607,0.339111,
0.392090,0.273193,0.714844,0.797363,0.403564,0.449219,0.747314,0.844238,
0.835205,0.110596,0.134033,0.214355,0.766113,0.109131,0.013184,0.875000,
0.737061,0.320801,0.639893,0.744141,0.751465,0.127197,0.011963,0.353027,
0.693359,0.440674,0.264160,0.780029,0.529785,0.800781,0.671143,0.332031,
0.400635,0.981445,0.770264,0.435059,0.298340,0.437988,0.163574,0.271973,
0.039551,0.043457,0.866943,0.009766,0.651123,0.846680,0.653076,0.125732,
0.530762,0.868896,0.268799,0.958008,0.142578,0.461914,0.303955,0.010986,
0.620850,0.522217,0.510986,0.338135,0.914551,0.411865,0.604004,0.706543,
0.238525,0.510254,0.103271,0.632324,0.422119,0.440186,0.265137,0.277100,
0.221924,0.201172,0.599365,0.244629,0.177002,0.293945,0.368652,0.649902,
0.100586,0.622559,0.905762,0.209961,0.257324,0.249512,0.428467,0.369141,
0.166016,0.635986,0.798340,0.940918,0.993896,0.803467,0.320068,0.929443,
0.650146,0.058594,0.065918,0.609375,0.616943,0.379639,0.221191,0.200684,
0.486084,0.437500,0.871338,0.795898,0.863037,0.700684,0.517090,0.821533,
0.319092,0.397461,0.852295,0.864014,0.591797,0.514404,0.925049,0.715820,
0.384766,0.734131,0.899170,0.703125,0.210938,0.783203,0.687012,0.850586,
0.532471,0.025635,0.975342,0.852051,0.612305,0.910889,0.159668,0.407227,
0.669678,0.096924,0.733398,0.304688,0.015625,0.372803,0.329590,0.858398,
0.033203,0.830811,0.914307,0.022949,0.451416,0.106201,0.664551,0.895752,
0.366455,0.230225,0.595459,0.296631,0.291992,0.375488,0.952393,0.052734,
0.132813,0.549805,0.828125,0.065674,0.318848,0.031494,0.605713,0.534912,
0.611328,0.259766,0.445068,0.660156,0.848633,0.055176,0.323730,0.122803,
0.697510,0.097412,0.989014,0.348877,0.536865,0.442139,0.269043,0.762451,
0.926270,0.118896,0.458740,0.496094,0.253906,0.084717,0.648926,0.754639,
0.648438,0.488281,0.533691,0.048828,0.050781,0.847168,0.431152,0.638184,
0.938232,0.092285,0.970215,0.037354,0.852539,0.586670,0.729248,0.227295,
0.482910,0.051025,0.135254,0.082520,0.812500,0.391602,0.598389,0.605957,
0.949707,0.464600,0.863770,0.024902,0.989502,0.937012,0.435547,0.565186,
0.370850,0.801758,0.143311,0.354492,0.715088,0.423828,0.796387,0.384033,
0.093018,0.813965,0.356201,0.535889,0.229492,0.553711,0.080811,0.711426,
0.082275,0.713623,0.097168,0.847900,0.197754,0.057617,0.970703,0.282959,
0.252686,0.082031,0.847412,0.274658,0.806641,0.027588,0.844727,0.748535,
0.667480,0.200195,0.814941,0.912598,0.463379,0.304199,0.815918,0.481445,
0.345947,0.936279,0.851318,0.796631,0.119141,0.328369,0.185303,0.911621,
0.527100,0.342529,0.652100,0.435303,0.537354,0.051758,0.998535,0.597168,
0.031006,0.056396,0.003174,0.702637,0.262207,0.433838,0.052002,0.776367,
0.993652,0.836182,0.055908,0.694092,0.768311,0.073242,0.908203,0.548584,
0.873535,0.205078,0.551514,0.726074,0.302979,0.136475,0.381348,0.702393,
0.054932,0.796143,0.079346,0.049561,0.539795,0.731201,0.175049,0.570068,
0.171631,0.899902,0.467041,0.623779,0.913086,0.386230,0.451904,0.878418,
0.880371,0.316406,0.468994,0.145752,0.920166,0.162354,0.944092,0.816162,
0.887695,0.802246,0.546631,0.803955,0.491455,0.064453,0.284424,0.153564,
0.291260,0.730713,0.173584,0.942383,0.640137,0.480469,0.552979,0.413818,
0.222656,0.364502,0.736816,0.351074,0.245605,0.183105,0.697754,0.308350,
0.467285,0.333740,0.400391,0.301514,0.601074,0.874512,0.571289,0.994873,
0.438721,0.865234,0.795410,0.476807,0.409912,0.651855,0.375244,0.139404,
0.776611,0.713379,0.406494,0.359619,0.635742,0.261963,0.210449,0.669922,
0.612061,0.363281,0.013916,0.504639,0.113770,0.814697,0.826660,0.016602,
0.079834,0.668945,0.453125,0.591553,0.258789,0.345703,0.271240,0.198486,
0.239258,0.975830,0.203613,0.974121,0.408691,0.775391,0.071777,0.503418,
0.483887,0.223877,0.805420,0.813721,0.326660,0.327148,0.616455,0.615479,
0.430176,0.153076,0.979736,0.611572,0.543457,0.095459,0.897461,0.406250,
0.657471,0.108887,0.002930,0.959961,0.396973,0.901367,0.572998,0.056152,
0.630371,0.762939,0.910156,0.965820,0.397705,0.171143,0.401367,0.453857,
0.493896,0.837158,0.636719,0.596436,0.645752,0.894043,0.990479,0.885254,
0.863525,0.650391,0.761963,0.947266,0.573730,0.941650,0.212891,0.805664,
0.153809,0.957275,0.044678,0.743408,0.579590,0.240967,0.172363,0.056641,
0.327637,0.787842,0.431885,0.652344,0.616699,0.629150,0.893311,0.691406,
0.054199,0.840088,0.930664,0.708008,0.398193,0.988770,0.959717,0.666992,
0.000244,0.696777,0.365967,0.547119,0.127930,0.141113,0.348633,0.531494,
0.584961,0.398926,0.728516,0.709229,0.391113,0.265869,0.244141,0.972900,
0.663086,0.258057,0.317871,0.740723,0.704834,0.138672,0.819092,0.802002,
0.563232,0.072754,0.085938,0.868652,0.521240,0.206543,0.696533,0.420654,
0.897705,0.783936,0.067627,0.686035,0.537598,0.660400,0.784180,0.292725,
0.444336,0.128662,0.862793,0.260742,0.789551,0.820557,0.319824,0.045166,
0.483154,0.533203,0.022705,0.249756,0.201660,0.124023,0.966064,0.117920,
0.129395,0.241699,0.585205,0.481201,0.904053,0.627441,0.979004,0.041992,
0.619141,0.525879,0.682373,0.497803,0.907471,0.303711,0.562012,0.495117,
0.500488,0.674072,0.552734,0.249023,0.088867,0.293213,0.221680,0.457031,
0.187988,0.950439,0.453369,0.014160,0.881348,0.050049,0.686523,0.476318,
0.524170,0.552246,0.077393,0.621826,0.829834,0.030518,0.295654,0.215088,
0.438965,0.271729,0.384277,0.580322,0.191895,0.096680,0.281982,0.984131,
0.675537,0.638672,0.329834,0.426025,0.768799,0.484375,0.287598,0.694824,
0.822510,0.351563,0.736328,0.905029,0.755127,0.661377,0.138916,0.236572,
0.662354,0.299316,0.906250,0.771240,0.680420,0.039063,0.029297,0.246338,
0.876221,0.506348,0.474365,0.476074,0.289063,0.514648,0.751221,0.909424,
0.921631,0.121094,0.628174,0.171875,0.881836,0.819824,0.002441,0.955811,
0.407715,0.288818,0.690918,0.193359,0.090088,0.461670,0.057861,0.597412,
0.247559,0.479492,0.222900,0.106934,0.147705,0.750977,0.322754,0.435791,
0.672852,0.795654,0.036621,0.125488,0.036865,0.224854,0.012695,0.023438,
0.191650,0.816650,0.381592,0.448975,0.112305,0.944336,0.017822,0.645020,
0.113037,0.881104,0.157715,0.692383,0.331299,0.177979,0.771729,0.223145,
0.854004,0.698242,0.821777,0.341553,0.638428,0.161133,0.040039,0.592529,
0.679932,0.558350,0.363770,0.423584,0.710938,0.219482,0.738037,0.339844,
0.433105,0.104736,0.653320,0.688965,0.087402,0.593994,0.387451,0.111328,
0.254639,0.346680,0.615234,0.588379,0.273682,0.141602,0.418701,0.294678,
0.569336,0.442383,0.598877,0.075684,0.677979,0.761230,0.919189,0.861572,
0.320557,0.790771,0.064697,0.144531,0.934570,0.721436,0.684814,0.251465,
0.762207,0.767090,0.528076,0.385498,0.269531,0.879639,0.576416,0.419434,
0.875732,0.672607,0.823242,0.785156,0.877686,0.432861,0.416260,0.066406,
0.233643,0.703857,0.719482,0.352783,0.837646,0.615967,0.593018,0.137451,
0.199951,0.712891,0.885498,0.923828,0.777588,0.669189,0.546875,0.400146,
0.374023,0.455322,0.577881,0.328125,0.954590,0.680908,0.836426,0.699219,
0.803711,0.350586,0.259277,0.878174,0.798096,0.904541,0.314453,0.820313,
0.949951,0.125000,0.782227,0.008057,0.303467,0.976074,0.189941,0.216064,
0.069092,0.070557,0.680176,0.983643,0.182861,0.656250,0.133545,0.389893,
0.277588,0.229004,0.148438,0.193115,0.562500,0.835938,0.172607,0.550293,
0.290527,0.146729,0.334229,0.334717,0.707031,0.023193,0.969727,0.593262,
0.708496,0.884766,0.329346,0.362305,0.305176,0.072021,0.591309,0.135010,
0.434570,0.394287,0.239746,0.532715,0.751709,0.760986,0.083740,0.763184,
0.765381,0.230713,0.312988,0.819336,0.338623,0.619385,0.152832,0.971436,
0.656982,0.585693,0.089844,0.513184,0.732178,0.548828,0.980469,0.022461,
0.340820,0.411377,0.829346,0.644531,0.804443,0.086914,0.468018,0.368164,
0.243408,0.824463,0.350830,0.416748,0.025879,0.156494,0.989990,0.129150,
0.814453,0.574707,0.790527,0.296387,0.510498,0.990234,0.480957,0.565430,
0.550537,0.461182,0.359863,0.966553,0.316650,0.187500,0.032959,0.460693,
0.692871,0.294434,0.857666,0.217041,0.128174,0.207764,0.309814,0.846924,
0.531982,0.047607,0.555664,0.198730,0.049316,0.576904,0.709473,0.518799,
0.069336,0.601563,0.228516,0.048096,0.479980,0.108643,0.080566,0.386719,
0.535400,0.465088,0.472168,0.105957,0.310059,0.489014,0.987549,0.406006,
0.673096,0.366211,0.681885,0.509766,0.600342,0.506592,0.558594,0.875488,
0.413574,0.083984,0.015137,0.559082,0.093750,0.805176,0.933838,0.775635,
0.826172,0.451660,0.779785,0.158691,0.346191,0.601318,0.407471,0.545410,
0.712646,0.845947,0.741211,0.337891,0.393799,0.407959,0.095703,0.817139,
0.198242,0.818359,0.272461,0.051270,0.350098,0.445557,0.485352,0.168945,
0.855469,0.427246,0.189453,0.646973,0.648193,0.717041,0.737305,0.222168,
0.704346,0.235352,0.126221,0.617676,0.108154,0.287842,0.237549,0.544678,
0.761719,0.832764,0.781250,0.501221,0.168213,0.262451,0.325684,0.396240,
0.970459,0.631348,0.134277,0.337158,0.006592,0.217529,0.333496,0.698486,
0.810059,0.391846,0.361572,0.265625,0.919922,0.408447,0.299561,0.524414,
0.076660,0.233887,0.147217,0.247803,0.720459,0.655273,0.178711,0.642822,
0.076904,0.408936,0.113281,0.201416,0.730957,0.200439,0.885010,0.100342,
0.369385,0.395264,0.542480,0.940430,0.684326,0.666504,0.228760,0.699463,
0.127441,0.212646,0.835693,0.029785,0.656006,0.354736,0.278564,0.339600,
0.549561,0.149658,0.593506,0.298096,0.492432,0.447754,0.264648,0.634766,
0.166992,0.515137,0.382568,0.142822,0.783447,0.953125,0.439697,0.267822,
0.121338,0.735840,0.087891,0.507568,0.595703,0.655518,0.610107,0.541748,
0.645508,0.057373,0.624512,0.191406,0.832031,0.702148,0.330566,0.087646,
0.242188,0.099854,0.307861,0.430908,0.684570,0.939453,0.031250,0.924805,
0.462646,0.120361,0.545654,0.789063,0.719971,0.072266,0.353271,0.996826,
0.627930,0.093994,0.920654,0.058105,0.430664,0.403076,0.448486,0.589111,
0.524658,0.148682,0.671875,0.470947,0.851807,0.367188,0.749268,0.746582,
0.429199,0.466064,0.519531,0.645996,0.125977,0.549072,0.547363,0.294189,
0.254883,0.634277,0.663330,0.528320,0.178955,0.730225,0.063232,0.979248,
0.733154,0.543945,0.668213,0.228027,0.896729,0.167480,0.551270,0.174316,
0.271484,0.519043,0.310791,0.664307,0.984619,0.534668,0.541992,0.604492,
0.946045,0.870117,0.161865,0.660889,0.587646,0.770996,0.573486,0.035156,
0.895996,0.812988,0.452881,0.854248,0.404297,0.371094,0.561768,0.132324,
0.009033,0.954834,0.522461,0.134521,0.538574,0.145996,0.968994,0.620117,
0.582275,0.609863,0.325195,0.620361,0.070801,0.633301,0.116455,0.236084,
0.485840,0.519287,0.264404,0.008301,0.632568,0.091553,0.142334,0.050537,
0.358154,0.126953,0.572021,0.471436,0.017334,0.754883,0.735596,0.313232,
0.780518,0.903809,0.314209,0.324951,0.188721,0.586182,0.421875,0.565918,
0.179443,0.723389,0.242676,0.592773,0.818604,0.501465,0.092529,0.126709,
0.250244,0.787354,0.104248,0.758301,0.395508,0.804932,0.090820,0.828857,
0.014893,0.899414,0.716797,0.942871,0.839111,0.493164,0.625244,0.867432,
0.504150,0.718750,0.725098,0.365479,0.256104,0.653564,0.355469,0.808838,
0.933594,0.525146,0.808350,0.454346,0.775879,0.184326,0.052979,0.658936,
0.243896,0.799072,0.603516,0.854980,0.947021,0.004639,0.503174,0.003418,
0.682617,0.492920,0.887451,0.924316,0.475098,0.766602,0.917480,0.964111,
0.971191,0.145020,0.071289,0.722900,0.144775,0.335205,0.613770,0.643066,
0.186035,0.081299,0.393311,0.123047,0.261719,0.196533,0.433350,0.263916,
0.935303,0.278076,0.732422,0.328613,0.937988,0.706787,0.467529,0.203857,
0.279541,0.957764,0.600586,0.226074,0.213867,0.563721,0.132568,0.802490,
0.318359,0.035400,0.606201,0.721680,0.735352,0.917725,0.045898,0.173828,
0.486328,0.241211,0.243164,0.181152,0.637695,0.670166,0.964844,0.367676,
0.826904,0.903076,0.457764,0.041260,0.161377,0.955322,0.752197,0.769043,
0.163818,0.117188,0.971924,0.611084,0.560303,0.319580,0.194824,0.325928,
0.477051,0.264893,0.043213,0.002686,0.690430,0.896240,0.409180,0.765137,
0.741455,0.689941,0.860107,0.704590,0.983887,0.869629,0.452637,0.376953,
0.839355,0.951416,0.378906,0.042969,0.287109,0.064209,0.195801,0.494385,
0.720947,0.139648,0.570313,0.250000,0.181396,0.461426,0.921875,0.939209,
0.690674,0.393555,0.693115,0.614502,0.322266,0.720215,0.636475,0.840820,
0.958496,0.931641,0.063965,0.770020,0.298828,0.606445,0.886719,0.506104,
0.958740,0.525635,0.297119,0.567871,0.358643,0.365234,0.187012,0.570801,
0.116211,0.786621,0.336182,0.388428,0.913330,0.494141,0.696289,0.848145,
0.699951,0.596680,0.276123,0.015381,0.685303,0.677490,0.463623,0.866699,
0.283447,0.909912,0.215332,0.062012,0.495361,0.307617,0.465820,0.005127,
0.937256,0.606934,0.465332,0.379150,0.685547,0.111084,0.753662,0.516113,
0.412354,0.058350,0.553223,0.181885,0.963867,0.639648,0.502930,0.018799,
0.588867,0.974365,0.657227,0.122559,0.773926,0.526367,0.243652,0.254150,
0.618408,0.589355,0.657959,0.209229,0.670898,0.621582,0.523926,0.572510,
0.053223,0.093262,0.187744,0.291504,0.083496,0.229980,0.109375,0.340332,
0.496582,0.659424,0.626221,0.183350,0.059814,0.711914,0.526611,0.425781,
0.995361,0.784424,0.170654,0.275146,0.402344,0.972656,0.624268,0.923584,
0.744385,0.902100,0.361816,0.682861,0.971680,0.441895,0.186768,0.144043,
0.801270,0.853760,0.099121,0.584717,0.443604,0.423096,0.855225,0.976807,
0.326904,0.614014,0.337646,0.821289,0.109863,0.405762,0.000732,0.157471,
0.377441,0.987793,0.766846,0.059570,0.434814,0.186523,0.332275,0.214844,
0.072510,0.640625,0.280029,0.105469,0.280762,0.946533,0.845703,0.028320,
0.044922,0.603760,0.059082,0.255371,0.143799,0.678711,0.182129,0.085205,
0.915771,0.610352,0.457275,0.617188,0.060547,0.774658,0.829590,0.854492,
0.313721,0.592041,0.156006,0.469482,0.743896,0.750732,0.004150,0.352051,
0.853271,0.313477,0.456543,0.841797,0.007080,0.389648,0.849365,0.942627,
0.561279,0.391357,0.214111,0.164551,0.554199,0.246582,0.012939,0.364746,
0.104980,0.046387,0.002197,0.420410,0.802979,0.156738,0.028076,0.115479,
0.405029,0.708984,0.782959,0.851074,0.748291,0.088135,0.681152,0.099365,
0.624756,0.338379,0.642090,0.221436,0.997314,0.548340,0.259521,0.464111,
0.016113,0.793945,0.773193,0.930908,0.316895,0.522705,0.755615,0.361328,
0.923096,0.323242,0.487061,0.474854,0.800293,0.025391,0.417236,0.895020,
0.700195,0.508789,0.031982,0.467773,0.890137,0.450684,0.710693,0.204834,
0.724121,0.707764,0.425537,0.233154,0.716064,0.668701,0.255615,0.388672,
0.893799,0.224609,0.978516,0.195557,0.145508,0.499268,0.890625,0.495850,
0.362793,0.900879,0.902344,0.882324,0.811279,0.579346,0.128418,0.126465,
0.283936,0.406738,0.588135,0.281738,0.358887,0.946289,0.641357,0.616211,
0.747559,0.651611,0.872070,0.858887,0.834717,0.694336,0.005615,0.744873,
0.836670,0.643799,0.602539,0.020996,0.107422,0.055664,0.961426,0.900391,
0.867676,0.133057,0.995850,0.737549,0.807617,0.289795,0.354004,0.972168,
0.139160,0.582520,0.497314,0.514893,0.759033,0.778564,0.128906,0.862549,
0.600830,0.070313,0.966797,0.097900,0.252197,0.758789,0.529541,0.840576,
0.373291,0.268066,0.728760,0.376221,0.394775,0.434082,0.840332,0.729004,
0.759521,0.908691,0.884521,0.504883,0.460449,0.288086,0.983398,0.213623,
0.816406,0.716553,0.629883,0.414307,0.158936,0.828369,0.008545,0.780762,
0.364014,0.204102,0.465576,0.675781,0.666260,0.503906,0.299072,0.171387,
0.511475,0.072998,0.809326,0.248291,0.182373,0.853516,0.364258,0.466797,
0.399902,0.001465,0.722412,0.830566,0.115234,0.740967,0.566406,0.068115,
0.140869,0.107178,0.242432,0.290039,0.079590,0.591064,0.620605,0.515381,
0.229736,0.770752,0.707275,0.455811,0.114502,0.485596,0.628418,0.590088,
0.175293,0.289551,0.077637,0.787109,0.042480,0.357666,0.790283,0.512451,
0.447998,0.825195,0.724609,0.893066,0.769287,0.739014,0.101318,0.152344,
0.096436,0.752441,0.494873,0.020752,0.297852,0.036133,0.907227,0.477295,
0.869385,0.742920,0.952148,0.714600,0.053711,0.687744,0.660645,0.633545,
0.439453,0.888428,0.908936,0.443848,0.030273,0.885986,0.284912,0.238281,
0.933105,0.343750,0.963623,0.194580,0.996338,0.473877,0.545166,0.931885,
0.399658,0.871826,0.398438,0.410400,0.344482,0.921387,0.850830,0.944580,
0.250977,0.150879,0.834229,0.267578,0.734375,0.939697,0.913574,0.636230,
0.283691,0.948730,0.306885,0.557861,0.764648,0.253418,0.582764,0.505615,
0.340088,0.261230,0.727783,0.016357,0.658447,0.559326,0.102051,0.714111,
0.535645,0.650635,0.622314,0.383545,0.916748,0.955566,0.116943,0.018311,
0.750244,0.208252,0.773438,0.281006,0.095215,0.928467,0.426514,0.177246,
0.219727,0.367920,0.495605,0.443115,0.380127,0.175537,0.452148,0.641113,
0.786133,0.602295,0.784668,0.034912,0.061523,0.962891,0.715332,0.580078,
0.363525,0.533936,0.009277,0.740479,0.285156,0.402832,0.821045,0.441406,
0.568848,0.336670,0.185791,0.211182,0.218994,0.492676,0.205811,0.655029,
0.784912,0.676270,0.709717,0.335449,0.081787,0.529053,0.794434,0.301270,
0.449951,0.929932,0.232178,0.717773,0.548096,0.644775,0.590820,0.774170,
0.458252,0.560059,0.117432,0.007324,0.630859,0.096191,0.182617,0.905273,
0.848389,0.587158,0.699707,0.390137,0.618896,0.597656,0.812744,0.998291,
0.590576,0.991699,0.838379,0.331543,0.166504,0.993164,0.525391,0.811768,
0.629639,0.312744,0.285400,0.608643,0.512939,0.621094,0.953369,0.965576,
0.223633,0.295410,0.133301,0.267334,0.678223,0.439941,0.010010,0.693604,
0.619629,0.306641,0.475830,0.952637,0.074951,0.218262,0.873047,0.469238,
0.236328,0.791992,0.310303,0.355957,0.450928,0.274170,0.509033,0.421143,
0.683105,0.839600,0.466309,0.986084,0.516602,0.691895,0.105713,0.724854,
0.695068,0.026123,0.579834,0.617432,0.107666,0.208984,0.496338,0.673584,
0.448242,0.940674,0.999756,0.384521,0.053955,0.807373,0.165283,0.906006,
0.838623,0.844482,0.335693,0.483643,0.133789,0.437012,0.778809,0.544434,
0.755859,0.508301,0.712402,0.705322,0.634033,0.129883,0.013672,0.377686,
0.661133,0.456787,0.888672,0.947998,0.043701,0.356445,0.366699,0.470215,
0.176270,0.639160,0.239502,0.557373,0.342773,0.968506,0.185059,0.518311,
0.378174,0.279053,0.663818,0.673340,0.001221,0.437744,0.188232,0.317383,
0.203369,0.252441,0.226318,0.188477,0.160400,0.703613,0.265381,0.940186,
0.833252,0.636963,0.429932,0.638916,0.208008,0.968262,0.343262,0.130127,
0.650879,0.563965,0.689697,0.044434,0.387207,0.447021,0.773682,0.151611,
0.463867,0.210693,0.889893,0.674316,0.261475,0.927734,0.903320,0.124268,
0.713867,0.234619,0.992432,0.119629,0.606689,0.183838,0.555176,0.266113,
0.618652,0.402100,0.204590,0.083008,0.995117,0.226563,0.417725,0.633789,
0.581299,0.906494,0.948975,0.561523,0.679443,0.768555,0.095947,0.667725,
0.376709,0.075928,0.827637,0.118164,0.502197,0.057129,0.871094,0.602051,
0.891113,0.206299,0.890381,0.581787,0.353760,0.371338,0.653809,0.834473,
0.917236,0.856201,0.939941,0.273926,0.834961,0.322021,0.382080,0.990967,
0.281250,0.564453,0.633057,0.001709,0.614990,0.502686,0.838867,0.219238,
0.266846,0.355225,0.062500,0.075195,0.703369,0.071045,0.907715,0.260254,
0.160645,0.216553,0.863281,0.277832,0.623535,0.883301,0.099609,0.197998,
0.000977,0.590332,0.488037,0.259033,0.918213,0.427979,0.599854,0.263428,
0.913818,0.365723,0.327881,0.912842,0.837891,0.815186,0.255127,0.764893,
0.760254,0.093506,0.739990,0.830322,0.067383,0.138428,0.535156,0.680664,
0.103516,0.817871,0.200928,0.929688,0.248535,0.180664,0.781982,0.966309,
0.860840,0.469727,0.576660,0.436035,0.167236,0.975586,0.450439,0.027832,
0.897217,0.679688,0.666748,0.060303,0.131592,0.400879,0.125244,0.142090,
0.706055,0.402588,0.963379,0.711182,0.831299,0.697998,0.898193,0.532959,
0.530273,0.356689,0.244873,0.837402,0.300049,0.440918,0.157227,0.911377,
0.625000,0.151367,0.917969,0.962646,0.179932,0.471191,0.286377,0.475586,
0.034668,0.748779,0.208496,0.124512,0.471680,0.742432,0.777100,0.812012,
0.991943,0.344727,0.822021,0.729736,0.559570,0.276367,0.906982,0.449707,
0.066650,0.383301,0.769775,0.416504,0.654297,0.988525,0.358398,0.538086,
0.401855,0.385986,0.225586,0.698975,0.909180,0.662598,0.061035,0.098145,
0.136230,0.244385,0.542969,0.827881,0.978271,0.723145,0.922607,0.008789,
0.571533,0.491699,0.498535,0.687256,0.884033,0.311768,0.042236,0.958252,
0.604980,0.237061,0.122314,0.377930,0.575195,0.727295,0.950684,0.608398,
0.231445,0.091064,0.630127,0.347168,0.973389,0.123779,0.817627,0.278320,
0.150391,0.765869,0.368408,0.793701,0.615723,0.012451,0.956299,0.749512,
0.509521,0.529297,0.649170,0.291016,0.956543,0.332520,0.513672,0.916504,
0.012207,0.374512,0.932129,0.418945,0.607178,0.347656,0.825439,0.392578,
0.667236,0.777344,0.123535,0.357422,0.967041,0.439209,0.248047,0.446289,
0.218506,0.445801,0.135742,0.905518,0.915283,0.515869,0.063477,0.740234,
0.910400,0.462158,0.614746,0.996582,0.250488,0.368896,0.555420,0.514160,
0.102539,0.876953,0.464355,0.315186,0.333984,0.114258,0.110352,0.527832,
0.296143,0.786377,0.605469,0.331787,0.377197,0.085449,0.549316,0.796875,
0.110840,0.204346,0.419678,0.105225,0.521973,0.772705,0.670654,0.843750,
0.830078,0.635254,0.280518,0.886963,0.293701,0.473389,0.507813,0.775146,
0.813232,0.986572,0.042725,0.011475,0.134766,0.199463,0.906738,0.256836,
0.044189,0.419922,0.815674,0.822998,0.977783,0.760498,0.541016,0.895508,
0.681641,0.528564,0.632813,0.813477,0.513428,0.373535,0.305664,0.299805,
0.659912,0.460205,0.047363,0.333252,0.372314,0.073486,0.505127,0.771484,
0.336426,0.997803,0.158447,0.960938,0.347900,0.449463,0.502441,0.594238,
0.132080,0.749756,0.941895,0.005859,0.304443,0.149902,0.564209,0.968018,
0.371826,0.199219,0.260498,0.609619,0.089355,0.019287,0.359131,0.413330,
0.817383,0.322510,0.806152,0.176025,0.041748,0.555908,0.950928,0.207520,
0.898926,0.308594,0.367432,0.799805,0.792969,0.842041,0.742188,0.927979,
0.952881,0.370361,0.534180,0.683594,0.380859,0.116699,0.827148,0.665771,
0.292480,0.270508,0.676514,0.230957,0.474609,0.600098,0.428955,0.901855,
0.199707,0.315674,0.349854,0.930420,0.811035,0.077881,0.064941,0.527344,
0.427002,0.459961,0.308105,0.120605,0.468750,0.225830,0.944824,0.010498,
0.718994,0.997070,0.726563,0.715576,0.493652,0.894287,0.338867,0.251221,
0.789795,0.197021,0.114990,0.603271,0.213135,0.357178,0.902832,0.658691,
0.459229,0.224121,0.687988,0.595947,0.862061,0.085693,0.092041,0.360107,
0.347412,0.656738,0.379395,0.218018,0.753906,0.170166,0.390381,0.455566,
0.858154,0.831787,0.779297,0.760010,0.027344,0.553467,0.328857,0.695801,
0.572266,0.443359,0.500977,0.189209,0.424316,0.178467,0.094238,0.013428,
0.792480,0.181641,0.998047,0.501953,0.383057,0.079102,0.721924,0.122070,
0.870361,0.532227,0.424561,0.674805,0.192139,0.482422,0.306152,0.756836,
0.493408,0.843506,0.765625,0.710449,0.321777,0.676025,0.164307,0.567627,
0.081543,0.490479,0.571045,0.943115,0.161621,0.330322,0.537842,0.114746,
0.450195,0.006836,0.392334,0.053467,0.598633,0.977539,0.111572,0.098633,
0.511963,0.069580,0.387695,0.546143,0.941162,0.727051,0.490234,0.861084,
0.928955,0.520508,0.115723,0.649658,0.642578,0.295166,0.965088,0.918457,
0.918945,0.163086,0.312012,0.462891,0.447510,0.420166,0.665527,0.211914,
0.520996,0.846191,0.473633,0.778320,0.736572,0.091797,0.988281,0.436523,
0.040527,0.717529,0.318604,0.432617,0.011230,0.614258,0.810791,0.648682,
0.569580,0.324707,0.750000,0.947754,0.155273,0.788086,0.010742,0.249268,
0.144287,0.349609,0.520752,0.729980,0.806396,0.059326,0.303223,0.067139,
0.421387,0.843994,0.637207,0.858643,0.814209,0.554932,0.251709,0.730469,
0.109619,0.630615,0.379883,0.456055,0.274902,0.349121,0.580811,0.723633,
0.018066,0.541260,0.387939,0.039795,0.040771,0.960205,0.458984,0.343994,
0.141846,0.231934,0.017090,0.791748,0.931152,0.797852,0.731934,0.694580,
0.691162,0.276855,0.785889,0.745850,0.942139,0.487793,0.228271,0.807861,
0.023926,0.889160,0.140625,0.232666,0.110107,0.315918,0.372070,0.582031,
0.121582,0.180176,0.386475,0.058838,0.038086,0.731445,0.202637,0.574951,
0.446533,0.050293,0.542236,0.227051,0.194336,0.850098,0.857422,0.937744,
0.886475,0.232422,0.542725,0.316162,0.880859,0.797607,0.575439,0.953613,
0.066895,0.657715,0.753174,0.283203,0.705811,0.541504,0.220703,0.701172,
0.454102,0.032471,0.452393,0.409668,0.926514,0.903564,0.263672,0.785400,
0.422363,0.841064,0.410889,0.613281,0.004883,0.426758,0.106445,0.738770,
0.291748,0.508545,0.578125,0.565674,0.480225,0.581055,0.415527,0.849854,
0.104004,0.184814,0.418213,0.628662,0.324219,0.348145,0.831543,0.635010,
0.986816,0.583008,0.124756,0.710205,0.382813,0.545898,0.727539,0.890869,
0.869141,0.260986,0.170898,0.654785,0.801025,0.429443,0.442871,0.245117,
0.756104,0.772949,0.577393,0.000488,0.631592,0.659180,0.048584,0.956787,
0.850342,0.153320,0.627197,0.026611,0.025146,0.522949,0.928711,0.507324,
0.028809,0.518066,0.512207,0.031738,0.945068,0.369873,0.692139,0.100830,
0.752686,0.190674,0.510010,0.294922,0.741943,0.478271,0.757568,0.953857,
0.232910,0.000000,0.746094,0.831055,0.915039,0.738525,0.275391,0.069824,
0.354980,0.799561,0.611816,0.363037,0.101807,0.423340,0.934082,0.284668,
0.859863,0.351807,0.652588,0.596191,0.519775,0.286865,0.451172,0.962158,
0.612549,0.587891,0.887939,0.431641,0.169922,0.302246,0.117676,0.725342,
0.049805,0.869873,0.127686,0.677246,0.429688,0.458008,0.172852,0.804688,
0.308838,0.248779,0.491943,0.061279,0.037842,0.864746,0.326172,0.520264,
0.925781,0.268311,0.412598,0.414551,0.352295,0.701904,0.866455,0.574219,
0.074463,0.718018,0.375732,0.704102,0.592285,0.397949,0.239990,0.341309,
0.768066,0.019531,0.174805,0.945313,0.290283,0.865967,0.877441,0.029541,
0.478516,0.389160,0.827393,0.982910,0.868164,0.608154,0.180420,0.103760,
0.257813,0.103027,0.902588,0.670410,0.100098,0.538818,0.045654,0.899658,
0.405518,0.220215,0.381836,0.187256,0.321045,0.987061,0.411133,0.761475,
0.150146,0.809082,0.440430,0.454590,0.155762,0.800049,0.666016,0.084229,
0.810547,0.257080,0.278809,0.410645,0.949219,0.969971,0.948242,0.943604,
0.298584,0.092773,0.370117,0.506836,0.499023,0.237793,0.739258,0.168701,
0.510742,0.900635,0.460938,0.908447,0.539063,0.531006,0.380615,0.230469,
0.159912,0.014648,0.823730,0.931396,0.824951,0.166748,0.324463,0.517822,
0.536621,0.490723,0.279785,0.985352,0.165527,0.586914,0.226807,0.326416,
0.604248,0.119873,0.148926,0.026855,0.689453,0.282471,0.631836,0.235596,
0.828613,0.225342,0.394531,0.877197,0.901123,0.169678,0.399170,0.646729,
0.737793,0.021729,0.135498,0.011719,0.911133,0.554688,0.810303,0.954102,
0.339355,0.605225,0.361084,0.872803,0.360596,0.500000,0.159180,0.162109,
0.108398,0.478760,0.227783,0.343018,0.486816,0.916016,0.861816,0.938965,
0.174561,0.538330,0.078125,0.763428,0.757080,0.071533,0.457520,0.665039,
0.194092,0.567383,0.270752,0.859619,0.791260,0.617920,0.888916,0.165771,
0.202881,0.515625,0.486572,0.746826,0.470459,0.412842,0.714355,0.017578,
0.396484,0.312256,0.311035,0.458496,0.417480,0.922363,0.646240,0.889648,
0.607666,0.946777,0.321289,0.445313,0.479004,0.825684,0.272217,0.301758,
0.274414,0.212402,0.503662,0.484863,0.364990,0.112061,0.302734,0.097656,
0.499512,0.557617,0.742676,0.154541,0.280273,0.595215,0.689209,0.234375,
0.247070,0.839844,0.215576,0.362061,0.853027,0.891846,0.262695,0.424805,
0.193604,0.856689,0.487549,0.190186,0.881592,0.155029,0.076172,0.201904,
0.712158,0.296875,0.314697,0.223389,0.951904,0.416992,0.060791,0.310547,
0.981201,0.702881,0.540283,0.385254,0.297607,0.547852,0.168457,0.184082,
0.870850,0.178223,0.685059,0.268555,0.088379,0.922852,0.418457,0.340576,
0.179688,0.808594,0.041504,0.380371,0.874268,0.131104,0.855713,0.934326,
0.747803,0.820801,0.101074,0.920898,0.774414,0.963135,0.732910,0.746338,
0.728027,0.540039,0.207031,0.972412,0.983154,0.589844,0.589600,0.664063,
0.919678,0.594482,0.174072,0.860596,0.551025,0.479736,0.889404,0.994629,
0.562256,0.188965,0.189697,0.007568,0.430420,0.780273,0.038818,0.148193,
0.743164,0.579102,0.404785,0.354248,0.150635,0.362549,0.982178,0.345215,
0.619873,0.078857,0.212158,0.720703,0.233398,0.257568,0.697021,0.678955,
0.748047,0.915527,0.497559,0.505371,0.160889,0.240479,0.718262,0.992676,
0.021973,0.052490,0.833740,0.851563,0.138184,0.427490,0.104492,0.644043,
0.584229,0.001953,0.991211,0.489502,0.932373,0.511719,0.862305,0.309570,
0.068604,0.843018,0.959229,0.046875,0.823486,0.754395,0.560547,0.672363,
0.028564,0.073730,0.346924,0.860352,0.731689,0.596924,0.539551,0.982422,
0.945801,0.679199,0.481934,0.348389,0.477539,0.991455,0.794922,0.663574,
0.490967,0.812256,0.476563,0.047119,0.892578,0.888184,0.793213,0.033691,
0.312500,0.523193,0.883057,0.334473,0.492188,0.006348,0.990723,0.084961,
0.757813,0.497070,0.172119,0.202148,0.709961,0.624023,0.275635,0.432129,
0.752930,0.974854,0.438232,0.164063,0.388916,0.960693,0.878662,0.802734,
0.192383,0.824707,0.977295,0.309082,0.513916,0.597900,0.305908,0.390869,
0.447266,0.357910,0.754150,0.120117,0.203125,0.113525,0.089600,0.688477,
0.335938,0.537109,0.572754,0.091309,0.098877,0.235107,0.956055,0.833008,
0.196777,0.010254,0.955078,0.080322,0.390625,0.668457,0.701416,0.643555,
0.601807,0.772217,0.035645,0.292236,0.196289,0.375977,0.967529,0.398682,
0.732666,0.225098,0.393066,0.682129,0.938721,0.722168,0.907959,0.719727,
0.681396,0.980957,0.594727,0.454834,0.531250,0.222412,0.717285,0.845459,
0.892822,0.642334,0.479248,0.936523,0.083252,0.879395,0.856934,0.422852,
0.442627,0.156250,0.849609,0.076416,0.550049,0.864990,0.926025,0.568115,
0.989258,0.708740,0.578613,0.896484,0.805908,0.941406,0.778076,0.745117,
0.688232,0.416016,0.245850,0.652832,0.169189,0.571777,0.459473,0.024170,
0.879883,0.861328,0.319336,0.146484,0.700928,0.240234,0.154297,0.197266,
0.472656,0.651367,0.716309,0.854736,0.544189,0.052246,0.981934,0.372559,
0.266357,0.272705,0.035889,0.290771,0.741699,0.359375,0.566162,0.293457,
0.431396,0.167725,0.970947,0.266602,0.875977,0.425049,0.743652,0.935059,
0.173096,0.634521,0.677002,0.927490,0.988037,0.112793,0.494629,0.707520,
0.086670,0.089111,0.943359,0.613037,0.776123,0.832275,0.045410,0.824219,
0.062744,0.415771,0.206787,0.569824,0.507080,0.473145,0.401123,0.438477,
0.345459,0.217773,0.033936,0.865479,0.376465,0.676758,0.330078,0.973145,
0.516357,0.395020,0.464844,0.240723,0.967285,0.231689,0.022217,0.766357,
0.776855,0.216309,0.305420,0.158203,0.019043,0.841309,0.054688,0.131348,
0.270264,0.511230,0.073975,0.671631,0.718506,0.701660,0.009521,0.980713,
0.355713,0.822266,0.023682,0.781006,0.973877,0.509277,0.288574,0.034180,
0.500732,0.176514,0.968750,0.678467,0.334961,0.779541,0.985596,0.726807,
0.006104,0.647705,0.928223,0.979492,0.477783,0.130371,0.209473,0.695313,
0.311523,0.382324,0.504395,0.521729,0.147461,0.909668,0.585938,0.674561,
0.747070,0.041016,0.207275,0.323486,0.558838,0.891357,0.526123,0.722656,
0.985840,0.488770,0.961914,0.481689,0.801514,0.180908,0.788330,0.758057,
0.891602,0.563477,0.466553,0.552002,0.760742,0.577148,0.705078,0.314941,
0.852783,0.323975,0.738281,0.297363,0.136963,0.512695,0.356934,0.210205,
0.378662,0.848877,0.411621,0.978760,0.723877,0.149170,0.635498,0.734619,
0.779053,0.533447,0.610596,0.396729,0.242920,0.448730,0.251953,0.838135,
0.695557,0.499756,0.935791,0.788574,0.247314,0.530518,0.524902,0.137695,
0.231201,0.216797,0.130615,0.436768,0.980225,0.556641,0.807129,0.927246,
0.927002,0.446777,0.599609,0.867920,0.969238,0.217285,0.792725,0.219971,
0.444824,0.878906,0.996094,0.540527,0.341064,0.048340,0.688721,0.744629,
0.604736,0.584473,0.700439,0.444580,0.037109,0.136719,0.131836,0.237305,
0.756348,0.422607,0.901611,0.735107,0.568359,0.756592,0.410156,0.649414,
0.875244,0.090576,0.876465,0.191162,0.626953,0.373779,0.864258,0.051514,
0.999512,0.763672,0.994141,0.374756,0.911865,0.179199,0.415283,0.046143,
0.381104,0.518555,0.675293,0.926758,0.260010,0.951660,0.608887,0.488525,
0.580566,0.932861,0.879150,0.318115,0.613525,0.043945,0.040283,0.719238,
0.353516,0.647461,0.570557,0.994385,0.602783,0.825928,0.394043,0.003662,
0.951172,0.818848,0.786865,0.528809,0.750488,0.255859,0.154053,0.876709,
0.154785,0.485107,0.007813,0.453613,0.034424,0.932617,0.897949,0.558105,
0.030762,0.173340,0.753418,0.403809,0.434326,0.137207,0.282227,0.080078,
0.849121,0.711670,0.065186,0.090332,0.925293,0.883545,0.456299,0.573242,
0.583252,0.325439,0.074219,0.047852,0.392822,0.984863,0.330811,0.560791,
0.441650,0.235840,0.559814,0.395752,0.234131,0.733643,0.520020,0.833984,
0.764160,0.129639,0.446045,0.639404,0.068848,0.024414,0.478027,0.112549,
0.276611,0.270020,0.844971,0.527588,0.566895,0.804199,0.896973,0.183594,
0.631104,0.924072,0.246826,0.094727,0.304932,0.781738,0.118408,0.842529,
0.269775,0.014404,0.626465,0.767822,0.729492,0.190918,0.544922,0.564697,
0.992920,0.317627,0.024658,0.925537,0.414063,0.583740,0.569092,0.143066,
0.655762,0.759766,0.799316,0.056885,0.273438,0.882813,0.281494,0.795166,
0.020264,0.066162,0.523438,0.238037,0.880127,0.157959,0.236816,0.992188,
0.924561,0.578857,0.498291,0.130859,0.344238,0.964600,0.798584,0.672119,
0.622070,0.794189,0.661621,0.474121,0.399414,0.842285,0.166260,0.220459,
0.640869,0.351318,0.764404,0.202393,0.726318,0.498779,0.959473,0.395996,
0.929199,0.415039,0.246094,0.301025,0.516846,0.164795,0.141357,0.789307,
0.286621,0.343506,0.625977,0.147949,0.654541,0.279297,0.770508,0.937500,
0.282715,0.205322,0.833496,0.665283,0.751953,0.964355,0.462402,0.184570,
0.195313,0.557129,0.791016,0.882568,0.610840,0.004395,0.787598,0.556396,
0.209717,0.408203,0.816895,0.373047,0.369629,0.344971,0.870605,0.120850,
0.987305,0.118652,0.658203,0.873779,0.292969,0.692627,0.568604,0.922119,
0.469971,0.575928,0.985107,0.288330,0.192627,0.437256,0.414795,0.628906,
0.647217,0.540771,0.111816,0.342041,0.420898,0.767334,0.224365,0.739502,
0.843262,0.894531,0.916260,0.820068,0.564941,0.256348,0.238770,0.386963,
0.960449,0.284180,0.385010,0.687500,0.683838,0.275879,0.945557,0.936768,
0.032227,0.607910,0.062988,0.322998,0.241455,0.818115,0.567139,0.973633,
0.829102,0.938477,0.046631,0.962402,0.576172,0.309326,0.979980,0.176758,
0.421631,0.329102,0.315430,0.333008,0.160156,0.455078,0.562744,0.417969,
0.898438,0.771973,0.725830,0.159424,0.254395,0.441162,0.371582,0.102295,
0.151123,0.468262,0.637451,0.087158,0.405273,0.063721,0.155518,0.403320,
0.989746,0.957031,0.137939,0.543213,0.428223,0.054443,0.872559,0.823975,
0.815430,0.609131,0.912109,0.806885,0.067871,0.556152,0.923340,0.769531,
0.618164,0.055420,0.803223,0.156982,0.262939,0.693848,0.894775,0.270996,
0.463135,0.998779,0.845215,0.149414,0.081055,0.253174,0.037598,0.842773,
0.526855,0.306396,0.068359,0.078613,0.211426,0.508057,0.295898,0.496826,
0.374268,0.234863,0.832520,0.489258,0.140137,0.193848,0.029053,0.798828,
0.914063,0.086426,0.866211,0.857910,0.914795,0.554443,0.285645,0.135986
};
#define MAX_RANDOM_FLOATS 4096
#define RANDOM_FLOAT_MASK ( MAX_RANDOM_FLOATS - 1 )
#endif // RANDOM_FLOATS

2
particles/vsi.nul Normal file
View File

@@ -0,0 +1,2 @@
SN Visual Studio Integration
IMPORTANT: Do not remove the custom build step for this file