From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/shared/particlesystemquery.cpp | 1242 ++++++++++++++-------------- 1 file changed, 621 insertions(+), 621 deletions(-) (limited to 'mp/src/game/shared/particlesystemquery.cpp') diff --git a/mp/src/game/shared/particlesystemquery.cpp b/mp/src/game/shared/particlesystemquery.cpp index f6eeb258..b97a334b 100644 --- a/mp/src/game/shared/particlesystemquery.cpp +++ b/mp/src/game/shared/particlesystemquery.cpp @@ -1,621 +1,621 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: particle system definitions -// -//===========================================================================// - -#include "cbase.h" -#include "particles/particles.h" -#include "baseparticleentity.h" -#include "entityparticletrail_shared.h" -#include "collisionutils.h" - -#if defined( CLIENT_DLL ) -#include "c_pixel_visibility.h" -#endif - -#ifdef TF_CLIENT_DLL -#include "tf_shareddefs.h" -#endif - -#ifdef GAME_DLL -#include "ai_utils.h" -#endif - -// memdbgon must be the last include file in a .cpp file!!! -#include "tier0/memdbgon.h" - - -//----------------------------------------------------------------------------- -// Interface to allow the particle system to call back into the game code -//----------------------------------------------------------------------------- -class CParticleSystemQuery : public CBaseAppSystem< IParticleSystemQuery > -{ -public: - // Inherited from IParticleSystemQuery - virtual void GetLightingAtPoint( const Vector& vecOrigin, Color &cTint ); - virtual void TraceLine( const Vector& vecAbsStart, - const Vector& vecAbsEnd, unsigned int mask, - const IHandleEntity *ignore, - int collisionGroup, CBaseTrace *ptr ); - - virtual bool MovePointInsideControllingObject( CParticleCollection *pParticles, - void *pObject, - Vector *pPnt ); - virtual void GetRandomPointsOnControllingObjectHitBox( - CParticleCollection *pParticles, - int nControlPointNumber, - int nNumPtsOut, - float flBBoxScale, - int nNumTrysToGetAPointInsideTheModel, - Vector *pPntsOut, - Vector vecDirectionalBias, - Vector *pHitBoxRelativeCoordOut, - int *pHitBoxIndexOut - ); - - virtual int GetCollisionGroupFromName( const char *pszCollisionGroupName ); - - - virtual int GetControllingObjectHitBoxInfo( - CParticleCollection *pParticles, - int nControlPointNumber, - int nBufSize, // # of output slots available - ModelHitBoxInfo_t *pHitBoxOutputBuffer ); - - virtual bool IsPointInControllingObjectHitBox( - CParticleCollection *pParticles, - int nControlPointNumber, Vector vecPos, bool bBBoxOnly ); - - virtual Vector GetLocalPlayerPos( void ); - virtual void GetLocalPlayerEyeVectors( Vector *pForward, Vector *pRight = NULL, Vector *pUp = NULL ); - - virtual float GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale ); - virtual void SetUpLightingEnvironment( const Vector& pos ); -}; - - -static CParticleSystemQuery s_ParticleSystemQuery; -IParticleSystemQuery *g_pParticleSystemQuery = &s_ParticleSystemQuery; - - -//----------------------------------------------------------------------------- -// Exposes the interface (so tools can get at it) -//----------------------------------------------------------------------------- -#ifdef CLIENT_DLL -EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CParticleSystemQuery, IParticleSystemQuery, PARTICLE_SYSTEM_QUERY_INTERFACE_VERSION, s_ParticleSystemQuery ); -#endif - -static CThreadFastMutex s_LightMutex; -static CThreadFastMutex s_BoneMutex; - -//----------------------------------------------------------------------------- -// Inherited from IParticleSystemQuery -//----------------------------------------------------------------------------- -void CParticleSystemQuery::GetLightingAtPoint( const Vector& vecOrigin, Color &cTint ) -{ -#ifdef GAME_DLL - - // FIXME: Go through to the engine from the server to get these values - cTint.SetColor( 255, 255, 255, 255 ); - -#else - - if ( engine->IsInGame() ) - { - s_LightMutex.Lock(); - // Compute our lighting at our position - Vector totalColor = engine->GetLightForPoint( vecOrigin, true ); - s_LightMutex.Unlock(); - - // Get our lighting information - cTint.SetColor( totalColor.x*255, totalColor.y*255, totalColor.z*255, 0 ); - } - else - { - // FIXME: Go through to the engine from the server to get these values - cTint.SetColor( 255, 255, 255, 255 ); - } - -#endif -} - -void CParticleSystemQuery::SetUpLightingEnvironment( const Vector& pos ) -{ -#ifndef GAME_DLL - if ( !engine->IsInGame() ) - return; - - s_LightMutex.Lock(); - modelrender->SetupLighting( pos ); - s_LightMutex.Unlock(); -#endif -} - -void CParticleSystemQuery::TraceLine( const Vector& vecAbsStart, - const Vector& vecAbsEnd, unsigned int mask, - const IHandleEntity *ignore, - int collisionGroup, CBaseTrace *ptr ) -{ - bool bDoTrace = false; -#ifndef GAME_DLL - bDoTrace = engine->IsInGame(); -#endif - if ( bDoTrace ) - { - trace_t tempTrace; - UTIL_TraceLine( vecAbsStart, vecAbsEnd, mask, ignore, collisionGroup, &tempTrace ); - memcpy( ptr, &tempTrace, sizeof ( CBaseTrace ) ); - } - else - { - ptr->startsolid = 0; - ptr->fraction = 1.0; - } - -} - -bool CParticleSystemQuery::MovePointInsideControllingObject( - CParticleCollection *pParticles, void *pObject, Vector *pPnt ) -{ -#ifdef GAME_DLL - return true; -#else - if (! pObject ) - return true; // accept the input point unmodified - - Ray_t ray; - trace_t tr; - ray.Init( *pPnt, *pPnt ); - enginetrace->ClipRayToEntity( ray, MASK_ALL, (CBaseEntity *) pObject, &tr ); - - return ( tr.startsolid ); -#endif -} - -static float GetSurfaceCoord( float flRand, float flMinX, float flMaxX ) -{ - return Lerp( flRand, flMinX, flMaxX ); - -} - - -void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox( - CParticleCollection *pParticles, - int nControlPointNumber, - int nNumPtsOut, - float flBBoxScale, - int nNumTrysToGetAPointInsideTheModel, - Vector *pPntsOut, - Vector vecDirectionalBias, - Vector *pHitBoxRelativeCoordOut, - int *pHitBoxIndexOut - ) -{ - - bool bSucesss = false; - - -#ifndef GAME_DLL - - EHANDLE *phMoveParent = reinterpret_cast ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); - CBaseEntity *pMoveParent = NULL; - if ( phMoveParent ) - { - pMoveParent = *( phMoveParent ); - } - if ( pMoveParent ) - { - float flRandMax = flBBoxScale; - float flRandMin = 1.0 - flBBoxScale; - Vector vecBasePos; - pParticles->GetControlPointAtTime( nControlPointNumber, pParticles->m_flCurTime, &vecBasePos ); - - s_BoneMutex.Lock(); - C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); - if ( pAnimating ) - { - - matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; - - if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) - { - - studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); - - if ( pStudioHdr ) - { - mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); - - if ( set ) - { - bSucesss = true; - - Vector vecWorldPosition; - float u = 0, v = 0, w = 0; - int nHitbox = 0; - int nNumIters = nNumTrysToGetAPointInsideTheModel; - if (! vecDirectionalBias.IsZero( 0.0001 ) ) - nNumIters = MAX( nNumIters, 5 ); - - for( int i=0 ; i < nNumPtsOut; i++) - { - int nTryCnt = nNumIters; - float flBestPointGoodness = -1.0e20; - do - { - int nTryHitbox = pParticles->RandomInt( 0, set->numhitboxes - 1 ); - mstudiobbox_t *pBox = set->pHitbox(nTryHitbox); - - float flTryU = pParticles->RandomFloat( flRandMin, flRandMax ); - float flTryV = pParticles->RandomFloat( flRandMin, flRandMax ); - float flTryW = pParticles->RandomFloat( flRandMin, flRandMax ); - - Vector vecLocalPosition; - vecLocalPosition.x = GetSurfaceCoord( flTryU, pBox->bbmin.x * pAnimating->GetModelScale(), pBox->bbmax.x * pAnimating->GetModelScale() ); - vecLocalPosition.y = GetSurfaceCoord( flTryV, pBox->bbmin.y * pAnimating->GetModelScale(), pBox->bbmax.y * pAnimating->GetModelScale() ); - vecLocalPosition.z = GetSurfaceCoord( flTryW, pBox->bbmin.z * pAnimating->GetModelScale(), pBox->bbmax.z * pAnimating->GetModelScale() ); - - Vector vecTryWorldPosition; - - VectorTransform( vecLocalPosition, *hitboxbones[pBox->bone], vecTryWorldPosition ); - - - float flPointGoodness = pParticles->RandomFloat( 0, 72 ) - + DotProduct( vecTryWorldPosition - vecBasePos, - vecDirectionalBias ); - - if ( nNumTrysToGetAPointInsideTheModel ) - { - // do a point in solid test - Ray_t ray; - trace_t tr; - ray.Init( vecTryWorldPosition, vecTryWorldPosition ); - enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); - if ( tr.startsolid ) - flPointGoodness += 1000.; // got a point inside! - } - if ( flPointGoodness > flBestPointGoodness ) - { - u = flTryU; - v = flTryV; - w = flTryW; - vecWorldPosition = vecTryWorldPosition; - nHitbox = nTryHitbox; - flBestPointGoodness = flPointGoodness; - } - } while ( nTryCnt-- ); - *( pPntsOut++ ) = vecWorldPosition; - if ( pHitBoxRelativeCoordOut ) - ( pHitBoxRelativeCoordOut++ )->Init( u, v, w ); - if ( pHitBoxIndexOut ) - *( pHitBoxIndexOut++ ) = nHitbox; - } - } - } - } - } - - if ( pMoveParent->IsBrushModel() ) - { - Vector vecMin; - Vector vecMax; - matrix3x4_t matOrientation; - Vector VecOrigin; - pMoveParent->GetRenderBounds( vecMin, vecMax ); - VecOrigin = pMoveParent->GetRenderOrigin(); - matOrientation = pMoveParent->EntityToWorldTransform(); - - - - Vector vecWorldPosition; - float u = 0, v = 0, w = 0; - int nHitbox = 0; - int nNumIters = nNumTrysToGetAPointInsideTheModel; - if (! vecDirectionalBias.IsZero( 0.0001 ) ) - nNumIters = MAX( nNumIters, 5 ); - - for( int i=0 ; i < nNumPtsOut; i++) - { - int nTryCnt = nNumIters; - float flBestPointGoodness = -1.0e20; - do - { - float flTryU = pParticles->RandomFloat( flRandMin, flRandMax ); - float flTryV = pParticles->RandomFloat( flRandMin, flRandMax ); - float flTryW = pParticles->RandomFloat( flRandMin, flRandMax ); - - Vector vecLocalPosition; - vecLocalPosition.x = GetSurfaceCoord( flTryU, vecMin.x, vecMax.x ); - vecLocalPosition.y = GetSurfaceCoord( flTryV, vecMin.y, vecMax.y ); - vecLocalPosition.z = GetSurfaceCoord( flTryW, vecMin.z, vecMax.z ); - - Vector vecTryWorldPosition; - VectorTransform( vecLocalPosition, matOrientation, vecTryWorldPosition ); - - float flPointGoodness = pParticles->RandomFloat( 0, 72 ) - + DotProduct( vecTryWorldPosition - vecBasePos, - vecDirectionalBias ); - - if ( nNumTrysToGetAPointInsideTheModel ) - { - // do a point in solid test - Ray_t ray; - trace_t tr; - ray.Init( vecTryWorldPosition, vecTryWorldPosition ); - enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); - if ( tr.startsolid ) - flPointGoodness += 1000.; // got a point inside! - } - if ( flPointGoodness > flBestPointGoodness ) - { - u = flTryU; - v = flTryV; - w = flTryW; - vecWorldPosition = vecTryWorldPosition; - nHitbox = 0; - flBestPointGoodness = flPointGoodness; - } - } while ( nTryCnt-- ); - *( pPntsOut++ ) = vecWorldPosition; - if ( pHitBoxRelativeCoordOut ) - ( pHitBoxRelativeCoordOut++ )->Init( u, v, w ); - if ( pHitBoxIndexOut ) - *( pHitBoxIndexOut++ ) = nHitbox; - } - } - - s_BoneMutex.Unlock(); - } -#endif - if (! bSucesss ) - { - // don't have a model or am in editor or something - fill return with control point - for( int i=0 ; i < nNumPtsOut; i++) - { - pPntsOut[i] = pParticles->m_ControlPoints[nControlPointNumber].m_Position; // fallback if anything goes wrong - - if ( pHitBoxIndexOut ) - pHitBoxIndexOut[i] = 0; - - if ( pHitBoxRelativeCoordOut ) - pHitBoxRelativeCoordOut[i].Init(); - } - } -} - - -int CParticleSystemQuery::GetControllingObjectHitBoxInfo( - CParticleCollection *pParticles, - int nControlPointNumber, - int nBufSize, // # of output slots available - ModelHitBoxInfo_t *pHitBoxOutputBuffer ) -{ - int nRet = 0; - -#ifndef GAME_DLL - s_BoneMutex.Lock(); - - EHANDLE *phMoveParent = reinterpret_cast ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); - CBaseEntity *pMoveParent = NULL; - if ( phMoveParent ) - { - pMoveParent = *( phMoveParent ); - } - - if ( pMoveParent ) - { - C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); - if ( pAnimating ) - { - matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; - - if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) - { - - studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); - - if ( pStudioHdr ) - { - mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); - - if ( set ) - { - nRet = MIN( nBufSize, set->numhitboxes ); - for( int i=0 ; i < nRet; i++ ) - { - mstudiobbox_t *pBox = set->pHitbox( i ); - pHitBoxOutputBuffer[i].m_vecBoxMins.x = pBox->bbmin.x; - pHitBoxOutputBuffer[i].m_vecBoxMins.y = pBox->bbmin.y; - pHitBoxOutputBuffer[i].m_vecBoxMins.z = pBox->bbmin.z; - - pHitBoxOutputBuffer[i].m_vecBoxMaxes.x = pBox->bbmax.x; - pHitBoxOutputBuffer[i].m_vecBoxMaxes.y = pBox->bbmax.y; - pHitBoxOutputBuffer[i].m_vecBoxMaxes.z = pBox->bbmax.z; - - pHitBoxOutputBuffer[i].m_Transform = *hitboxbones[pBox->bone]; - } - } - } - } - } - if ( pMoveParent->IsBrushModel() ) - { - Vector vecMin; - Vector vecMax; - matrix3x4_t matOrientation; - pMoveParent->GetRenderBounds( vecMin, vecMax ); - matOrientation = pMoveParent->EntityToWorldTransform(); - pHitBoxOutputBuffer[0].m_vecBoxMins = vecMin; - pHitBoxOutputBuffer[0].m_vecBoxMaxes = vecMax; - pHitBoxOutputBuffer[0].m_Transform = matOrientation; - nRet = 1; - } - } - s_BoneMutex.Unlock(); -#endif - return nRet; -} - - - -bool CParticleSystemQuery::IsPointInControllingObjectHitBox( - CParticleCollection *pParticles, - int nControlPointNumber, Vector vecPos, bool bBBoxOnly ) -{ - bool bSuccess = false; -#ifndef GAME_DLL - - EHANDLE *phMoveParent = reinterpret_cast ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); - CBaseEntity *pMoveParent = NULL; - if ( phMoveParent ) - { - pMoveParent = *( phMoveParent ); - } - if ( pMoveParent ) - { - s_BoneMutex.Lock(); - C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); - - bool bInBBox = false; - Vector vecBBoxMin; - Vector vecBBoxMax; - Vector vecOrigin; - - vecBBoxMin = pMoveParent->CollisionProp()->OBBMins(); - vecBBoxMax = pMoveParent->CollisionProp()->OBBMaxs(); - - matrix3x4_t matOrientation; - matOrientation = pMoveParent->EntityToWorldTransform(); - Vector vecLocalPos; - VectorITransform( vecPos, matOrientation, vecLocalPos ); - if ( IsPointInBox( vecLocalPos, vecBBoxMin, vecBBoxMax ) ) - bInBBox = true; - - if ( bInBBox && bBBoxOnly ) - bSuccess = true; - else if ( pAnimating && bInBBox ) - { - matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; - if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) - { - - studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); - - if ( pStudioHdr ) - { - mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); - - if ( set ) - { - // do a point in solid test - Ray_t ray; - trace_t tr; - ray.Init( vecPos, vecPos ); - enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); - if ( tr.startsolid ) - bSuccess = true; - } - } - } - } - else if ( pMoveParent->IsBrushModel() && bInBBox ) - { - // do a point in solid test - Ray_t ray; - trace_t tr; - ray.Init( vecPos, vecPos ); - enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); - if ( tr.startsolid ) - bSuccess = true; - } - - s_BoneMutex.Unlock(); - } -#endif - return bSuccess; -} - - -struct CollisionGroupNameRecord_t -{ - const char *m_pszGroupName; - int m_nGroupID; -}; - - -static CollisionGroupNameRecord_t s_NameMap[]={ - { "NONE", COLLISION_GROUP_NONE }, - { "DEBRIS", COLLISION_GROUP_DEBRIS }, - { "INTERACTIVE", COLLISION_GROUP_INTERACTIVE }, - { "NPC", COLLISION_GROUP_NPC }, - { "ACTOR", COLLISION_GROUP_NPC_ACTOR }, - { "PASSABLE", COLLISION_GROUP_PASSABLE_DOOR }, -#if defined( TF_CLIENT_DLL ) - { "ROCKETS", TFCOLLISION_GROUP_ROCKETS }, -#endif -}; - - -int CParticleSystemQuery::GetCollisionGroupFromName( const char *pszCollisionGroupName ) -{ - for(int i = 0; i < ARRAYSIZE( s_NameMap ); i++ ) - { - if ( ! stricmp( s_NameMap[i].m_pszGroupName, pszCollisionGroupName ) ) - return s_NameMap[i].m_nGroupID; - } - return COLLISION_GROUP_NONE; -} - -Vector CParticleSystemQuery::GetLocalPlayerPos( void ) -{ -#ifdef CLIENT_DLL - C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); - if ( !pPlayer ) - return vec3_origin; - return pPlayer->WorldSpaceCenter(); -#else - CBasePlayer *pPlayer = AI_GetSinglePlayer(); - if ( !pPlayer ) - return vec3_origin; - return pPlayer->WorldSpaceCenter(); -#endif -} - -void CParticleSystemQuery::GetLocalPlayerEyeVectors( Vector *pForward, Vector *pRight, Vector *pUp ) -{ -#ifdef CLIENT_DLL - C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); - if ( !pPlayer ) - { - *pForward = vec3_origin; - *pRight = vec3_origin; - *pUp = vec3_origin; - return; - } - pPlayer->EyeVectors( pForward, pRight, pUp ); -#else - CBasePlayer *pPlayer = AI_GetSinglePlayer(); - if ( !pPlayer ) - { - *pForward = vec3_origin; - *pRight = vec3_origin; - *pUp = vec3_origin; - return; - } - pPlayer->EyeVectors( pForward, pRight, pUp ); -#endif -} - -float CParticleSystemQuery::GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale ) -{ -#ifdef CLIENT_DLL - pixelvis_queryparams_t params; - params.Init( vecOrigin, flScale, 1.0 ); - float flVisibility = PixelVisibility_FractionVisible( params, pQueryHandle ); - flVisibility = MAX( 0.0f, flVisibility ); - return flVisibility; -#else - return 0.0f; -#endif -} +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: particle system definitions +// +//===========================================================================// + +#include "cbase.h" +#include "particles/particles.h" +#include "baseparticleentity.h" +#include "entityparticletrail_shared.h" +#include "collisionutils.h" + +#if defined( CLIENT_DLL ) +#include "c_pixel_visibility.h" +#endif + +#ifdef TF_CLIENT_DLL +#include "tf_shareddefs.h" +#endif + +#ifdef GAME_DLL +#include "ai_utils.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Interface to allow the particle system to call back into the game code +//----------------------------------------------------------------------------- +class CParticleSystemQuery : public CBaseAppSystem< IParticleSystemQuery > +{ +public: + // Inherited from IParticleSystemQuery + virtual void GetLightingAtPoint( const Vector& vecOrigin, Color &cTint ); + virtual void TraceLine( const Vector& vecAbsStart, + const Vector& vecAbsEnd, unsigned int mask, + const IHandleEntity *ignore, + int collisionGroup, CBaseTrace *ptr ); + + virtual bool MovePointInsideControllingObject( CParticleCollection *pParticles, + void *pObject, + Vector *pPnt ); + virtual void GetRandomPointsOnControllingObjectHitBox( + CParticleCollection *pParticles, + int nControlPointNumber, + int nNumPtsOut, + float flBBoxScale, + int nNumTrysToGetAPointInsideTheModel, + Vector *pPntsOut, + Vector vecDirectionalBias, + Vector *pHitBoxRelativeCoordOut, + int *pHitBoxIndexOut + ); + + virtual int GetCollisionGroupFromName( const char *pszCollisionGroupName ); + + + virtual int GetControllingObjectHitBoxInfo( + CParticleCollection *pParticles, + int nControlPointNumber, + int nBufSize, // # of output slots available + ModelHitBoxInfo_t *pHitBoxOutputBuffer ); + + virtual bool IsPointInControllingObjectHitBox( + CParticleCollection *pParticles, + int nControlPointNumber, Vector vecPos, bool bBBoxOnly ); + + virtual Vector GetLocalPlayerPos( void ); + virtual void GetLocalPlayerEyeVectors( Vector *pForward, Vector *pRight = NULL, Vector *pUp = NULL ); + + virtual float GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale ); + virtual void SetUpLightingEnvironment( const Vector& pos ); +}; + + +static CParticleSystemQuery s_ParticleSystemQuery; +IParticleSystemQuery *g_pParticleSystemQuery = &s_ParticleSystemQuery; + + +//----------------------------------------------------------------------------- +// Exposes the interface (so tools can get at it) +//----------------------------------------------------------------------------- +#ifdef CLIENT_DLL +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CParticleSystemQuery, IParticleSystemQuery, PARTICLE_SYSTEM_QUERY_INTERFACE_VERSION, s_ParticleSystemQuery ); +#endif + +static CThreadFastMutex s_LightMutex; +static CThreadFastMutex s_BoneMutex; + +//----------------------------------------------------------------------------- +// Inherited from IParticleSystemQuery +//----------------------------------------------------------------------------- +void CParticleSystemQuery::GetLightingAtPoint( const Vector& vecOrigin, Color &cTint ) +{ +#ifdef GAME_DLL + + // FIXME: Go through to the engine from the server to get these values + cTint.SetColor( 255, 255, 255, 255 ); + +#else + + if ( engine->IsInGame() ) + { + s_LightMutex.Lock(); + // Compute our lighting at our position + Vector totalColor = engine->GetLightForPoint( vecOrigin, true ); + s_LightMutex.Unlock(); + + // Get our lighting information + cTint.SetColor( totalColor.x*255, totalColor.y*255, totalColor.z*255, 0 ); + } + else + { + // FIXME: Go through to the engine from the server to get these values + cTint.SetColor( 255, 255, 255, 255 ); + } + +#endif +} + +void CParticleSystemQuery::SetUpLightingEnvironment( const Vector& pos ) +{ +#ifndef GAME_DLL + if ( !engine->IsInGame() ) + return; + + s_LightMutex.Lock(); + modelrender->SetupLighting( pos ); + s_LightMutex.Unlock(); +#endif +} + +void CParticleSystemQuery::TraceLine( const Vector& vecAbsStart, + const Vector& vecAbsEnd, unsigned int mask, + const IHandleEntity *ignore, + int collisionGroup, CBaseTrace *ptr ) +{ + bool bDoTrace = false; +#ifndef GAME_DLL + bDoTrace = engine->IsInGame(); +#endif + if ( bDoTrace ) + { + trace_t tempTrace; + UTIL_TraceLine( vecAbsStart, vecAbsEnd, mask, ignore, collisionGroup, &tempTrace ); + memcpy( ptr, &tempTrace, sizeof ( CBaseTrace ) ); + } + else + { + ptr->startsolid = 0; + ptr->fraction = 1.0; + } + +} + +bool CParticleSystemQuery::MovePointInsideControllingObject( + CParticleCollection *pParticles, void *pObject, Vector *pPnt ) +{ +#ifdef GAME_DLL + return true; +#else + if (! pObject ) + return true; // accept the input point unmodified + + Ray_t ray; + trace_t tr; + ray.Init( *pPnt, *pPnt ); + enginetrace->ClipRayToEntity( ray, MASK_ALL, (CBaseEntity *) pObject, &tr ); + + return ( tr.startsolid ); +#endif +} + +static float GetSurfaceCoord( float flRand, float flMinX, float flMaxX ) +{ + return Lerp( flRand, flMinX, flMaxX ); + +} + + +void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox( + CParticleCollection *pParticles, + int nControlPointNumber, + int nNumPtsOut, + float flBBoxScale, + int nNumTrysToGetAPointInsideTheModel, + Vector *pPntsOut, + Vector vecDirectionalBias, + Vector *pHitBoxRelativeCoordOut, + int *pHitBoxIndexOut + ) +{ + + bool bSucesss = false; + + +#ifndef GAME_DLL + + EHANDLE *phMoveParent = reinterpret_cast ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); + CBaseEntity *pMoveParent = NULL; + if ( phMoveParent ) + { + pMoveParent = *( phMoveParent ); + } + if ( pMoveParent ) + { + float flRandMax = flBBoxScale; + float flRandMin = 1.0 - flBBoxScale; + Vector vecBasePos; + pParticles->GetControlPointAtTime( nControlPointNumber, pParticles->m_flCurTime, &vecBasePos ); + + s_BoneMutex.Lock(); + C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); + if ( pAnimating ) + { + + matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; + + if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) + { + + studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); + + if ( pStudioHdr ) + { + mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); + + if ( set ) + { + bSucesss = true; + + Vector vecWorldPosition; + float u = 0, v = 0, w = 0; + int nHitbox = 0; + int nNumIters = nNumTrysToGetAPointInsideTheModel; + if (! vecDirectionalBias.IsZero( 0.0001 ) ) + nNumIters = MAX( nNumIters, 5 ); + + for( int i=0 ; i < nNumPtsOut; i++) + { + int nTryCnt = nNumIters; + float flBestPointGoodness = -1.0e20; + do + { + int nTryHitbox = pParticles->RandomInt( 0, set->numhitboxes - 1 ); + mstudiobbox_t *pBox = set->pHitbox(nTryHitbox); + + float flTryU = pParticles->RandomFloat( flRandMin, flRandMax ); + float flTryV = pParticles->RandomFloat( flRandMin, flRandMax ); + float flTryW = pParticles->RandomFloat( flRandMin, flRandMax ); + + Vector vecLocalPosition; + vecLocalPosition.x = GetSurfaceCoord( flTryU, pBox->bbmin.x * pAnimating->GetModelScale(), pBox->bbmax.x * pAnimating->GetModelScale() ); + vecLocalPosition.y = GetSurfaceCoord( flTryV, pBox->bbmin.y * pAnimating->GetModelScale(), pBox->bbmax.y * pAnimating->GetModelScale() ); + vecLocalPosition.z = GetSurfaceCoord( flTryW, pBox->bbmin.z * pAnimating->GetModelScale(), pBox->bbmax.z * pAnimating->GetModelScale() ); + + Vector vecTryWorldPosition; + + VectorTransform( vecLocalPosition, *hitboxbones[pBox->bone], vecTryWorldPosition ); + + + float flPointGoodness = pParticles->RandomFloat( 0, 72 ) + + DotProduct( vecTryWorldPosition - vecBasePos, + vecDirectionalBias ); + + if ( nNumTrysToGetAPointInsideTheModel ) + { + // do a point in solid test + Ray_t ray; + trace_t tr; + ray.Init( vecTryWorldPosition, vecTryWorldPosition ); + enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); + if ( tr.startsolid ) + flPointGoodness += 1000.; // got a point inside! + } + if ( flPointGoodness > flBestPointGoodness ) + { + u = flTryU; + v = flTryV; + w = flTryW; + vecWorldPosition = vecTryWorldPosition; + nHitbox = nTryHitbox; + flBestPointGoodness = flPointGoodness; + } + } while ( nTryCnt-- ); + *( pPntsOut++ ) = vecWorldPosition; + if ( pHitBoxRelativeCoordOut ) + ( pHitBoxRelativeCoordOut++ )->Init( u, v, w ); + if ( pHitBoxIndexOut ) + *( pHitBoxIndexOut++ ) = nHitbox; + } + } + } + } + } + + if ( pMoveParent->IsBrushModel() ) + { + Vector vecMin; + Vector vecMax; + matrix3x4_t matOrientation; + Vector VecOrigin; + pMoveParent->GetRenderBounds( vecMin, vecMax ); + VecOrigin = pMoveParent->GetRenderOrigin(); + matOrientation = pMoveParent->EntityToWorldTransform(); + + + + Vector vecWorldPosition; + float u = 0, v = 0, w = 0; + int nHitbox = 0; + int nNumIters = nNumTrysToGetAPointInsideTheModel; + if (! vecDirectionalBias.IsZero( 0.0001 ) ) + nNumIters = MAX( nNumIters, 5 ); + + for( int i=0 ; i < nNumPtsOut; i++) + { + int nTryCnt = nNumIters; + float flBestPointGoodness = -1.0e20; + do + { + float flTryU = pParticles->RandomFloat( flRandMin, flRandMax ); + float flTryV = pParticles->RandomFloat( flRandMin, flRandMax ); + float flTryW = pParticles->RandomFloat( flRandMin, flRandMax ); + + Vector vecLocalPosition; + vecLocalPosition.x = GetSurfaceCoord( flTryU, vecMin.x, vecMax.x ); + vecLocalPosition.y = GetSurfaceCoord( flTryV, vecMin.y, vecMax.y ); + vecLocalPosition.z = GetSurfaceCoord( flTryW, vecMin.z, vecMax.z ); + + Vector vecTryWorldPosition; + VectorTransform( vecLocalPosition, matOrientation, vecTryWorldPosition ); + + float flPointGoodness = pParticles->RandomFloat( 0, 72 ) + + DotProduct( vecTryWorldPosition - vecBasePos, + vecDirectionalBias ); + + if ( nNumTrysToGetAPointInsideTheModel ) + { + // do a point in solid test + Ray_t ray; + trace_t tr; + ray.Init( vecTryWorldPosition, vecTryWorldPosition ); + enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); + if ( tr.startsolid ) + flPointGoodness += 1000.; // got a point inside! + } + if ( flPointGoodness > flBestPointGoodness ) + { + u = flTryU; + v = flTryV; + w = flTryW; + vecWorldPosition = vecTryWorldPosition; + nHitbox = 0; + flBestPointGoodness = flPointGoodness; + } + } while ( nTryCnt-- ); + *( pPntsOut++ ) = vecWorldPosition; + if ( pHitBoxRelativeCoordOut ) + ( pHitBoxRelativeCoordOut++ )->Init( u, v, w ); + if ( pHitBoxIndexOut ) + *( pHitBoxIndexOut++ ) = nHitbox; + } + } + + s_BoneMutex.Unlock(); + } +#endif + if (! bSucesss ) + { + // don't have a model or am in editor or something - fill return with control point + for( int i=0 ; i < nNumPtsOut; i++) + { + pPntsOut[i] = pParticles->m_ControlPoints[nControlPointNumber].m_Position; // fallback if anything goes wrong + + if ( pHitBoxIndexOut ) + pHitBoxIndexOut[i] = 0; + + if ( pHitBoxRelativeCoordOut ) + pHitBoxRelativeCoordOut[i].Init(); + } + } +} + + +int CParticleSystemQuery::GetControllingObjectHitBoxInfo( + CParticleCollection *pParticles, + int nControlPointNumber, + int nBufSize, // # of output slots available + ModelHitBoxInfo_t *pHitBoxOutputBuffer ) +{ + int nRet = 0; + +#ifndef GAME_DLL + s_BoneMutex.Lock(); + + EHANDLE *phMoveParent = reinterpret_cast ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); + CBaseEntity *pMoveParent = NULL; + if ( phMoveParent ) + { + pMoveParent = *( phMoveParent ); + } + + if ( pMoveParent ) + { + C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); + if ( pAnimating ) + { + matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; + + if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) + { + + studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); + + if ( pStudioHdr ) + { + mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); + + if ( set ) + { + nRet = MIN( nBufSize, set->numhitboxes ); + for( int i=0 ; i < nRet; i++ ) + { + mstudiobbox_t *pBox = set->pHitbox( i ); + pHitBoxOutputBuffer[i].m_vecBoxMins.x = pBox->bbmin.x; + pHitBoxOutputBuffer[i].m_vecBoxMins.y = pBox->bbmin.y; + pHitBoxOutputBuffer[i].m_vecBoxMins.z = pBox->bbmin.z; + + pHitBoxOutputBuffer[i].m_vecBoxMaxes.x = pBox->bbmax.x; + pHitBoxOutputBuffer[i].m_vecBoxMaxes.y = pBox->bbmax.y; + pHitBoxOutputBuffer[i].m_vecBoxMaxes.z = pBox->bbmax.z; + + pHitBoxOutputBuffer[i].m_Transform = *hitboxbones[pBox->bone]; + } + } + } + } + } + if ( pMoveParent->IsBrushModel() ) + { + Vector vecMin; + Vector vecMax; + matrix3x4_t matOrientation; + pMoveParent->GetRenderBounds( vecMin, vecMax ); + matOrientation = pMoveParent->EntityToWorldTransform(); + pHitBoxOutputBuffer[0].m_vecBoxMins = vecMin; + pHitBoxOutputBuffer[0].m_vecBoxMaxes = vecMax; + pHitBoxOutputBuffer[0].m_Transform = matOrientation; + nRet = 1; + } + } + s_BoneMutex.Unlock(); +#endif + return nRet; +} + + + +bool CParticleSystemQuery::IsPointInControllingObjectHitBox( + CParticleCollection *pParticles, + int nControlPointNumber, Vector vecPos, bool bBBoxOnly ) +{ + bool bSuccess = false; +#ifndef GAME_DLL + + EHANDLE *phMoveParent = reinterpret_cast ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); + CBaseEntity *pMoveParent = NULL; + if ( phMoveParent ) + { + pMoveParent = *( phMoveParent ); + } + if ( pMoveParent ) + { + s_BoneMutex.Lock(); + C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); + + bool bInBBox = false; + Vector vecBBoxMin; + Vector vecBBoxMax; + Vector vecOrigin; + + vecBBoxMin = pMoveParent->CollisionProp()->OBBMins(); + vecBBoxMax = pMoveParent->CollisionProp()->OBBMaxs(); + + matrix3x4_t matOrientation; + matOrientation = pMoveParent->EntityToWorldTransform(); + Vector vecLocalPos; + VectorITransform( vecPos, matOrientation, vecLocalPos ); + if ( IsPointInBox( vecLocalPos, vecBBoxMin, vecBBoxMax ) ) + bInBBox = true; + + if ( bInBBox && bBBoxOnly ) + bSuccess = true; + else if ( pAnimating && bInBBox ) + { + matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; + if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) + { + + studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); + + if ( pStudioHdr ) + { + mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); + + if ( set ) + { + // do a point in solid test + Ray_t ray; + trace_t tr; + ray.Init( vecPos, vecPos ); + enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); + if ( tr.startsolid ) + bSuccess = true; + } + } + } + } + else if ( pMoveParent->IsBrushModel() && bInBBox ) + { + // do a point in solid test + Ray_t ray; + trace_t tr; + ray.Init( vecPos, vecPos ); + enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); + if ( tr.startsolid ) + bSuccess = true; + } + + s_BoneMutex.Unlock(); + } +#endif + return bSuccess; +} + + +struct CollisionGroupNameRecord_t +{ + const char *m_pszGroupName; + int m_nGroupID; +}; + + +static CollisionGroupNameRecord_t s_NameMap[]={ + { "NONE", COLLISION_GROUP_NONE }, + { "DEBRIS", COLLISION_GROUP_DEBRIS }, + { "INTERACTIVE", COLLISION_GROUP_INTERACTIVE }, + { "NPC", COLLISION_GROUP_NPC }, + { "ACTOR", COLLISION_GROUP_NPC_ACTOR }, + { "PASSABLE", COLLISION_GROUP_PASSABLE_DOOR }, +#if defined( TF_CLIENT_DLL ) + { "ROCKETS", TFCOLLISION_GROUP_ROCKETS }, +#endif +}; + + +int CParticleSystemQuery::GetCollisionGroupFromName( const char *pszCollisionGroupName ) +{ + for(int i = 0; i < ARRAYSIZE( s_NameMap ); i++ ) + { + if ( ! stricmp( s_NameMap[i].m_pszGroupName, pszCollisionGroupName ) ) + return s_NameMap[i].m_nGroupID; + } + return COLLISION_GROUP_NONE; +} + +Vector CParticleSystemQuery::GetLocalPlayerPos( void ) +{ +#ifdef CLIENT_DLL + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pPlayer ) + return vec3_origin; + return pPlayer->WorldSpaceCenter(); +#else + CBasePlayer *pPlayer = AI_GetSinglePlayer(); + if ( !pPlayer ) + return vec3_origin; + return pPlayer->WorldSpaceCenter(); +#endif +} + +void CParticleSystemQuery::GetLocalPlayerEyeVectors( Vector *pForward, Vector *pRight, Vector *pUp ) +{ +#ifdef CLIENT_DLL + C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pPlayer ) + { + *pForward = vec3_origin; + *pRight = vec3_origin; + *pUp = vec3_origin; + return; + } + pPlayer->EyeVectors( pForward, pRight, pUp ); +#else + CBasePlayer *pPlayer = AI_GetSinglePlayer(); + if ( !pPlayer ) + { + *pForward = vec3_origin; + *pRight = vec3_origin; + *pUp = vec3_origin; + return; + } + pPlayer->EyeVectors( pForward, pRight, pUp ); +#endif +} + +float CParticleSystemQuery::GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale ) +{ +#ifdef CLIENT_DLL + pixelvis_queryparams_t params; + params.Init( vecOrigin, flScale, 1.0 ); + float flVisibility = PixelVisibility_FractionVisible( params, pQueryHandle ); + flVisibility = MAX( 0.0f, flVisibility ); + return flVisibility; +#else + return 0.0f; +#endif +} -- cgit v1.2.3