You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
485 lines
18 KiB
485 lines
18 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=====================================================================================// |
|
|
|
#include "cbase.h" |
|
#include "StaticCollisionPolyhedronCache.h" |
|
#include "engine/IEngineTrace.h" |
|
#include "edict.h" |
|
|
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
class CPolyhedron_LumpedMemory : public CPolyhedron //we'll be allocating one big chunk of memory for all our polyhedrons. No individual will own any memory. |
|
{ |
|
public: |
|
virtual void Release( void ) { }; |
|
static CPolyhedron_LumpedMemory *AllocateAt( void *pMemory, int iVertices, int iLines, int iIndices, int iPolygons ) |
|
{ |
|
#include "tier0/memdbgoff.h" //the following placement new doesn't compile with memory debugging |
|
CPolyhedron_LumpedMemory *pAllocated = new ( pMemory ) CPolyhedron_LumpedMemory; |
|
#include "tier0/memdbgon.h" |
|
|
|
pAllocated->iVertexCount = iVertices; |
|
pAllocated->iLineCount = iLines; |
|
pAllocated->iIndexCount = iIndices; |
|
pAllocated->iPolygonCount = iPolygons; |
|
pAllocated->pVertices = (Vector *)(pAllocated + 1); //start vertex memory at the end of the class |
|
pAllocated->pLines = (Polyhedron_IndexedLine_t *)(pAllocated->pVertices + iVertices); |
|
pAllocated->pIndices = (Polyhedron_IndexedLineReference_t *)(pAllocated->pLines + iLines); |
|
pAllocated->pPolygons = (Polyhedron_IndexedPolygon_t *)(pAllocated->pIndices + iIndices); |
|
|
|
return pAllocated; |
|
} |
|
}; |
|
|
|
static uint8 *s_BrushPolyhedronMemory = NULL; |
|
static uint8 *s_StaticPropPolyhedronMemory = NULL; |
|
|
|
CStaticCollisionPolyhedronCache g_StaticCollisionPolyhedronCache; |
|
|
|
typedef ICollideable *ICollideablePtr; //needed for key comparison function syntax |
|
static bool CollideablePtr_KeyCompareFunc( const ICollideablePtr &a, const ICollideablePtr &b ) |
|
{ |
|
return a < b; |
|
}; |
|
|
|
CStaticCollisionPolyhedronCache::CStaticCollisionPolyhedronCache( void ) |
|
: m_CollideableIndicesMap( CollideablePtr_KeyCompareFunc ) |
|
{ |
|
|
|
} |
|
|
|
CStaticCollisionPolyhedronCache::~CStaticCollisionPolyhedronCache( void ) |
|
{ |
|
Clear(); |
|
} |
|
|
|
void CStaticCollisionPolyhedronCache::LevelInitPreEntity( void ) |
|
{ |
|
|
|
// FIXME: Fast updates would be nice but this method doesn't work with the recent changes to standard containers. |
|
// For now we're going with the quick fix of always doing a full update. -Jeep |
|
|
|
// if( Q_stricmp( m_CachedMap, MapName() ) != 0 ) |
|
// { |
|
// // New map or the last load was a transition, fully update the cache |
|
// m_CachedMap.Set( MapName() ); |
|
|
|
Update(); |
|
// } |
|
// else |
|
// { |
|
// // No need for a full update, but we need to remap static prop ICollideable's in the old system to the new system |
|
// for( int i = m_CollideableIndicesMap.Count(); --i >= 0; ) |
|
// { |
|
//#ifdef _DEBUG |
|
// StaticPropPolyhedronCacheInfo_t cacheInfo = m_CollideableIndicesMap.Element(i); |
|
//#endif |
|
// m_CollideableIndicesMap.Reinsert( staticpropmgr->GetStaticPropByIndex( m_CollideableIndicesMap.Element(i).iStaticPropIndex ), i ); |
|
// |
|
// Assert( (m_CollideableIndicesMap.Element(i).iStartIndex == cacheInfo.iStartIndex) && |
|
// (m_CollideableIndicesMap.Element(i).iNumPolyhedrons == cacheInfo.iNumPolyhedrons) && |
|
// (m_CollideableIndicesMap.Element(i).iStaticPropIndex == cacheInfo.iStaticPropIndex) ); //I'm assuming this doesn't cause a reindex of the unordered list, if it does then this needs to be rewritten |
|
// } |
|
// } |
|
} |
|
|
|
void CStaticCollisionPolyhedronCache::Shutdown( void ) |
|
{ |
|
Clear(); |
|
} |
|
|
|
|
|
void CStaticCollisionPolyhedronCache::Clear( void ) |
|
{ |
|
//The uses one big lump of memory to store polyhedrons. No need to Release() the polyhedrons. |
|
|
|
//Brushes |
|
{ |
|
m_BrushPolyhedrons.RemoveAll(); |
|
if( s_BrushPolyhedronMemory != NULL ) |
|
{ |
|
delete []s_BrushPolyhedronMemory; |
|
s_BrushPolyhedronMemory = NULL; |
|
} |
|
} |
|
|
|
//Static props |
|
{ |
|
m_CollideableIndicesMap.RemoveAll(); |
|
m_StaticPropPolyhedrons.RemoveAll(); |
|
if( s_StaticPropPolyhedronMemory != NULL ) |
|
{ |
|
delete []s_StaticPropPolyhedronMemory; |
|
s_StaticPropPolyhedronMemory = NULL; |
|
} |
|
} |
|
} |
|
|
|
void CStaticCollisionPolyhedronCache::Update( void ) |
|
{ |
|
Clear(); |
|
|
|
//There's no efficient way to know exactly how much memory we'll need to cache off all these polyhedrons. |
|
//So we're going to allocated temporary workspaces as we need them and consolidate into one allocation at the end. |
|
const size_t workSpaceSize = 1024 * 1024; //1MB. Fairly arbitrary size for a workspace. Brushes usually use 1-3MB in the end. Static props usually use about half as much as brushes. |
|
|
|
uint8 *workSpaceAllocations[256]; |
|
size_t usedSpaceInWorkspace[256]; |
|
unsigned int workSpacesAllocated = 0; |
|
uint8 *pCurrentWorkSpace = new uint8 [workSpaceSize]; |
|
size_t roomLeftInWorkSpace = workSpaceSize; |
|
workSpaceAllocations[workSpacesAllocated] = pCurrentWorkSpace; |
|
usedSpaceInWorkspace[workSpacesAllocated] = 0; |
|
++workSpacesAllocated; |
|
|
|
|
|
//brushes |
|
{ |
|
int iBrush = 0; |
|
CUtlVector<Vector4D> Planes; |
|
|
|
float fStackPlanes[4 * 400]; //400 is a crapload of planes in my opinion |
|
|
|
while( enginetrace->GetBrushInfo( iBrush, &Planes, NULL ) ) |
|
{ |
|
int iPlaneCount = Planes.Count(); |
|
AssertMsg( iPlaneCount != 0, "A brush with no planes???????" ); |
|
|
|
const Vector4D *pReturnedPlanes = Planes.Base(); |
|
|
|
CPolyhedron *pTempPolyhedron; |
|
|
|
if( iPlaneCount > 400 ) |
|
{ |
|
// o_O, we'll have to get more memory to transform this brush |
|
float *pNonstackPlanes = new float [4 * iPlaneCount]; |
|
|
|
for( int i = 0; i != iPlaneCount; ++i ) |
|
{ |
|
pNonstackPlanes[(i * 4) + 0] = pReturnedPlanes[i].x; |
|
pNonstackPlanes[(i * 4) + 1] = pReturnedPlanes[i].y; |
|
pNonstackPlanes[(i * 4) + 2] = pReturnedPlanes[i].z; |
|
pNonstackPlanes[(i * 4) + 3] = pReturnedPlanes[i].w; |
|
} |
|
|
|
pTempPolyhedron = GeneratePolyhedronFromPlanes( pNonstackPlanes, iPlaneCount, 0.01f, true ); |
|
|
|
delete []pNonstackPlanes; |
|
} |
|
else |
|
{ |
|
for( int i = 0; i != iPlaneCount; ++i ) |
|
{ |
|
fStackPlanes[(i * 4) + 0] = pReturnedPlanes[i].x; |
|
fStackPlanes[(i * 4) + 1] = pReturnedPlanes[i].y; |
|
fStackPlanes[(i * 4) + 2] = pReturnedPlanes[i].z; |
|
fStackPlanes[(i * 4) + 3] = pReturnedPlanes[i].w; |
|
} |
|
|
|
pTempPolyhedron = GeneratePolyhedronFromPlanes( fStackPlanes, iPlaneCount, 0.01f, true ); |
|
} |
|
|
|
if( pTempPolyhedron ) |
|
{ |
|
size_t memRequired = (sizeof( CPolyhedron_LumpedMemory )) + |
|
(sizeof( Vector ) * pTempPolyhedron->iVertexCount) + |
|
(sizeof( Polyhedron_IndexedLine_t ) * pTempPolyhedron->iLineCount) + |
|
(sizeof( Polyhedron_IndexedLineReference_t ) * pTempPolyhedron->iIndexCount) + |
|
(sizeof( Polyhedron_IndexedPolygon_t ) * pTempPolyhedron->iPolygonCount); |
|
|
|
Assert( memRequired < workSpaceSize ); |
|
|
|
if( roomLeftInWorkSpace < memRequired ) |
|
{ |
|
usedSpaceInWorkspace[workSpacesAllocated - 1] = workSpaceSize - roomLeftInWorkSpace; |
|
|
|
pCurrentWorkSpace = new uint8 [workSpaceSize]; |
|
roomLeftInWorkSpace = workSpaceSize; |
|
workSpaceAllocations[workSpacesAllocated] = pCurrentWorkSpace; |
|
usedSpaceInWorkspace[workSpacesAllocated] = 0; |
|
++workSpacesAllocated; |
|
} |
|
|
|
CPolyhedron *pWorkSpacePolyhedron = CPolyhedron_LumpedMemory::AllocateAt( pCurrentWorkSpace, |
|
pTempPolyhedron->iVertexCount, |
|
pTempPolyhedron->iLineCount, |
|
pTempPolyhedron->iIndexCount, |
|
pTempPolyhedron->iPolygonCount ); |
|
|
|
pCurrentWorkSpace += memRequired; |
|
roomLeftInWorkSpace -= memRequired; |
|
|
|
memcpy( pWorkSpacePolyhedron->pVertices, pTempPolyhedron->pVertices, pTempPolyhedron->iVertexCount * sizeof( Vector ) ); |
|
memcpy( pWorkSpacePolyhedron->pLines, pTempPolyhedron->pLines, pTempPolyhedron->iLineCount * sizeof( Polyhedron_IndexedLine_t ) ); |
|
memcpy( pWorkSpacePolyhedron->pIndices, pTempPolyhedron->pIndices, pTempPolyhedron->iIndexCount * sizeof( Polyhedron_IndexedLineReference_t ) ); |
|
memcpy( pWorkSpacePolyhedron->pPolygons, pTempPolyhedron->pPolygons, pTempPolyhedron->iPolygonCount * sizeof( Polyhedron_IndexedPolygon_t ) ); |
|
|
|
m_BrushPolyhedrons.AddToTail( pWorkSpacePolyhedron ); |
|
|
|
pTempPolyhedron->Release(); |
|
} |
|
else |
|
{ |
|
m_BrushPolyhedrons.AddToTail( NULL ); |
|
} |
|
|
|
++iBrush; |
|
} |
|
|
|
usedSpaceInWorkspace[workSpacesAllocated - 1] = workSpaceSize - roomLeftInWorkSpace; |
|
|
|
if( usedSpaceInWorkspace[0] != 0 ) //At least a little bit of memory was used. |
|
{ |
|
//consolidate workspaces into a single memory chunk |
|
size_t totalMemoryNeeded = 0; |
|
for( unsigned int i = 0; i != workSpacesAllocated; ++i ) |
|
{ |
|
totalMemoryNeeded += usedSpaceInWorkspace[i]; |
|
} |
|
|
|
uint8 *pFinalDest = new uint8 [totalMemoryNeeded]; |
|
s_BrushPolyhedronMemory = pFinalDest; |
|
|
|
DevMsg( 2, "CStaticCollisionPolyhedronCache: Used %.2f KB to cache %d brush polyhedrons.\n", ((float)totalMemoryNeeded) / 1024.0f, m_BrushPolyhedrons.Count() ); |
|
|
|
int iCount = m_BrushPolyhedrons.Count(); |
|
for( int i = 0; i != iCount; ++i ) |
|
{ |
|
CPolyhedron_LumpedMemory *pSource = (CPolyhedron_LumpedMemory *)m_BrushPolyhedrons[i]; |
|
|
|
if( pSource == NULL ) |
|
continue; |
|
|
|
size_t memRequired = (sizeof( CPolyhedron_LumpedMemory )) + |
|
(sizeof( Vector ) * pSource->iVertexCount) + |
|
(sizeof( Polyhedron_IndexedLine_t ) * pSource->iLineCount) + |
|
(sizeof( Polyhedron_IndexedLineReference_t ) * pSource->iIndexCount) + |
|
(sizeof( Polyhedron_IndexedPolygon_t ) * pSource->iPolygonCount); |
|
|
|
CPolyhedron_LumpedMemory *pDest = (CPolyhedron_LumpedMemory *)pFinalDest; |
|
m_BrushPolyhedrons[i] = pDest; |
|
pFinalDest += memRequired; |
|
|
|
int memoryOffset = ((uint8 *)pDest) - ((uint8 *)pSource); |
|
|
|
memcpy( pDest, pSource, memRequired ); |
|
//move all the pointers to their new location. |
|
pDest->pVertices = (Vector *)(((uint8 *)(pDest->pVertices)) + memoryOffset); |
|
pDest->pLines = (Polyhedron_IndexedLine_t *)(((uint8 *)(pDest->pLines)) + memoryOffset); |
|
pDest->pIndices = (Polyhedron_IndexedLineReference_t *)(((uint8 *)(pDest->pIndices)) + memoryOffset); |
|
pDest->pPolygons = (Polyhedron_IndexedPolygon_t *)(((uint8 *)(pDest->pPolygons)) + memoryOffset); |
|
} |
|
} |
|
} |
|
|
|
unsigned int iBrushWorkSpaces = workSpacesAllocated; |
|
workSpacesAllocated = 1; |
|
pCurrentWorkSpace = workSpaceAllocations[0]; |
|
usedSpaceInWorkspace[0] = 0; |
|
roomLeftInWorkSpace = workSpaceSize; |
|
|
|
//static props |
|
{ |
|
CUtlVector<ICollideable *> StaticPropCollideables; |
|
staticpropmgr->GetAllStaticProps( &StaticPropCollideables ); |
|
|
|
if( StaticPropCollideables.Count() != 0 ) |
|
{ |
|
ICollideable **pCollideables = StaticPropCollideables.Base(); |
|
ICollideable **pStop = pCollideables + StaticPropCollideables.Count(); |
|
|
|
int iStaticPropIndex = 0; |
|
do |
|
{ |
|
ICollideable *pProp = *pCollideables; |
|
vcollide_t *pCollide = modelinfo->GetVCollide( pProp->GetCollisionModel() ); |
|
StaticPropPolyhedronCacheInfo_t cacheInfo; |
|
cacheInfo.iStartIndex = m_StaticPropPolyhedrons.Count(); |
|
|
|
if( pCollide != NULL ) |
|
{ |
|
VMatrix matToWorldPosition = pProp->CollisionToWorldTransform(); |
|
|
|
for( int i = 0; i != pCollide->solidCount; ++i ) |
|
{ |
|
CPhysConvex *ConvexesArray[1024]; |
|
int iConvexes = physcollision->GetConvexesUsedInCollideable( pCollide->solids[i], ConvexesArray, 1024 ); |
|
|
|
for( int j = 0; j != iConvexes; ++j ) |
|
{ |
|
CPolyhedron *pTempPolyhedron = physcollision->PolyhedronFromConvex( ConvexesArray[j], true ); |
|
if( pTempPolyhedron ) |
|
{ |
|
for( int iPointCounter = 0; iPointCounter != pTempPolyhedron->iVertexCount; ++iPointCounter ) |
|
pTempPolyhedron->pVertices[iPointCounter] = matToWorldPosition * pTempPolyhedron->pVertices[iPointCounter]; |
|
|
|
for( int iPolyCounter = 0; iPolyCounter != pTempPolyhedron->iPolygonCount; ++iPolyCounter ) |
|
pTempPolyhedron->pPolygons[iPolyCounter].polyNormal = matToWorldPosition.ApplyRotation( pTempPolyhedron->pPolygons[iPolyCounter].polyNormal ); |
|
|
|
|
|
size_t memRequired = (sizeof( CPolyhedron_LumpedMemory )) + |
|
(sizeof( Vector ) * pTempPolyhedron->iVertexCount) + |
|
(sizeof( Polyhedron_IndexedLine_t ) * pTempPolyhedron->iLineCount) + |
|
(sizeof( Polyhedron_IndexedLineReference_t ) * pTempPolyhedron->iIndexCount) + |
|
(sizeof( Polyhedron_IndexedPolygon_t ) * pTempPolyhedron->iPolygonCount); |
|
|
|
Assert( memRequired < workSpaceSize ); |
|
|
|
if( roomLeftInWorkSpace < memRequired ) |
|
{ |
|
usedSpaceInWorkspace[workSpacesAllocated - 1] = workSpaceSize - roomLeftInWorkSpace; |
|
|
|
if( workSpacesAllocated < iBrushWorkSpaces ) |
|
{ |
|
//re-use a workspace already allocated during brush polyhedron conversion |
|
pCurrentWorkSpace = workSpaceAllocations[workSpacesAllocated]; |
|
usedSpaceInWorkspace[workSpacesAllocated] = 0; |
|
} |
|
else |
|
{ |
|
//allocate a new workspace |
|
pCurrentWorkSpace = new uint8 [workSpaceSize]; |
|
workSpaceAllocations[workSpacesAllocated] = pCurrentWorkSpace; |
|
usedSpaceInWorkspace[workSpacesAllocated] = 0; |
|
} |
|
|
|
roomLeftInWorkSpace = workSpaceSize; |
|
++workSpacesAllocated; |
|
} |
|
|
|
CPolyhedron *pWorkSpacePolyhedron = CPolyhedron_LumpedMemory::AllocateAt( pCurrentWorkSpace, |
|
pTempPolyhedron->iVertexCount, |
|
pTempPolyhedron->iLineCount, |
|
pTempPolyhedron->iIndexCount, |
|
pTempPolyhedron->iPolygonCount ); |
|
|
|
pCurrentWorkSpace += memRequired; |
|
roomLeftInWorkSpace -= memRequired; |
|
|
|
memcpy( pWorkSpacePolyhedron->pVertices, pTempPolyhedron->pVertices, pTempPolyhedron->iVertexCount * sizeof( Vector ) ); |
|
memcpy( pWorkSpacePolyhedron->pLines, pTempPolyhedron->pLines, pTempPolyhedron->iLineCount * sizeof( Polyhedron_IndexedLine_t ) ); |
|
memcpy( pWorkSpacePolyhedron->pIndices, pTempPolyhedron->pIndices, pTempPolyhedron->iIndexCount * sizeof( Polyhedron_IndexedLineReference_t ) ); |
|
memcpy( pWorkSpacePolyhedron->pPolygons, pTempPolyhedron->pPolygons, pTempPolyhedron->iPolygonCount * sizeof( Polyhedron_IndexedPolygon_t ) ); |
|
|
|
m_StaticPropPolyhedrons.AddToTail( pWorkSpacePolyhedron ); |
|
|
|
#ifdef _DEBUG |
|
CPhysConvex *pConvex = physcollision->ConvexFromConvexPolyhedron( *pTempPolyhedron ); |
|
AssertMsg( pConvex != NULL, "Conversion from Convex to Polyhedron was unreversable" ); |
|
if( pConvex ) |
|
{ |
|
physcollision->ConvexFree( pConvex ); |
|
} |
|
#endif |
|
|
|
pTempPolyhedron->Release(); |
|
} |
|
} |
|
} |
|
|
|
cacheInfo.iNumPolyhedrons = m_StaticPropPolyhedrons.Count() - cacheInfo.iStartIndex; |
|
cacheInfo.iStaticPropIndex = iStaticPropIndex; |
|
Assert( staticpropmgr->GetStaticPropByIndex( iStaticPropIndex ) == pProp ); |
|
|
|
m_CollideableIndicesMap.InsertOrReplace( pProp, cacheInfo ); |
|
} |
|
|
|
++iStaticPropIndex; |
|
++pCollideables; |
|
} while( pCollideables != pStop ); |
|
|
|
|
|
usedSpaceInWorkspace[workSpacesAllocated - 1] = workSpaceSize - roomLeftInWorkSpace; |
|
|
|
if( usedSpaceInWorkspace[0] != 0 ) //At least a little bit of memory was used. |
|
{ |
|
//consolidate workspaces into a single memory chunk |
|
size_t totalMemoryNeeded = 0; |
|
for( unsigned int i = 0; i != workSpacesAllocated; ++i ) |
|
{ |
|
totalMemoryNeeded += usedSpaceInWorkspace[i]; |
|
} |
|
|
|
uint8 *pFinalDest = new uint8 [totalMemoryNeeded]; |
|
s_StaticPropPolyhedronMemory = pFinalDest; |
|
|
|
DevMsg( 2, "CStaticCollisionPolyhedronCache: Used %.2f KB to cache %d static prop polyhedrons.\n", ((float)totalMemoryNeeded) / 1024.0f, m_StaticPropPolyhedrons.Count() ); |
|
|
|
int iCount = m_StaticPropPolyhedrons.Count(); |
|
for( int i = 0; i != iCount; ++i ) |
|
{ |
|
CPolyhedron_LumpedMemory *pSource = (CPolyhedron_LumpedMemory *)m_StaticPropPolyhedrons[i]; |
|
|
|
size_t memRequired = (sizeof( CPolyhedron_LumpedMemory )) + |
|
(sizeof( Vector ) * pSource->iVertexCount) + |
|
(sizeof( Polyhedron_IndexedLine_t ) * pSource->iLineCount) + |
|
(sizeof( Polyhedron_IndexedLineReference_t ) * pSource->iIndexCount) + |
|
(sizeof( Polyhedron_IndexedPolygon_t ) * pSource->iPolygonCount); |
|
|
|
CPolyhedron_LumpedMemory *pDest = (CPolyhedron_LumpedMemory *)pFinalDest; |
|
m_StaticPropPolyhedrons[i] = pDest; |
|
pFinalDest += memRequired; |
|
|
|
int memoryOffset = ((uint8 *)pDest) - ((uint8 *)pSource); |
|
|
|
memcpy( pDest, pSource, memRequired ); |
|
//move all the pointers to their new location. |
|
pDest->pVertices = (Vector *)(((uint8 *)(pDest->pVertices)) + memoryOffset); |
|
pDest->pLines = (Polyhedron_IndexedLine_t *)(((uint8 *)(pDest->pLines)) + memoryOffset); |
|
pDest->pIndices = (Polyhedron_IndexedLineReference_t *)(((uint8 *)(pDest->pIndices)) + memoryOffset); |
|
pDest->pPolygons = (Polyhedron_IndexedPolygon_t *)(((uint8 *)(pDest->pPolygons)) + memoryOffset); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if( iBrushWorkSpaces > workSpacesAllocated ) |
|
workSpacesAllocated = iBrushWorkSpaces; |
|
|
|
for( unsigned int i = 0; i != workSpacesAllocated; ++i ) |
|
{ |
|
delete []workSpaceAllocations[i]; |
|
} |
|
} |
|
|
|
|
|
|
|
const CPolyhedron *CStaticCollisionPolyhedronCache::GetBrushPolyhedron( int iBrushNumber ) |
|
{ |
|
Assert( iBrushNumber < m_BrushPolyhedrons.Count() ); |
|
|
|
if( (iBrushNumber < 0) || (iBrushNumber >= m_BrushPolyhedrons.Count()) ) |
|
return NULL; |
|
|
|
return m_BrushPolyhedrons[iBrushNumber]; |
|
} |
|
|
|
int CStaticCollisionPolyhedronCache::GetStaticPropPolyhedrons( ICollideable *pStaticProp, CPolyhedron **pOutputPolyhedronArray, int iOutputArraySize ) |
|
{ |
|
unsigned short iPropIndex = m_CollideableIndicesMap.Find( pStaticProp ); |
|
if( !m_CollideableIndicesMap.IsValidIndex( iPropIndex ) ) //static prop never made it into the cache for some reason (specifically no collision data when this workaround was written) |
|
return 0; |
|
|
|
StaticPropPolyhedronCacheInfo_t cacheInfo = m_CollideableIndicesMap.Element( iPropIndex ); |
|
|
|
if( cacheInfo.iNumPolyhedrons < iOutputArraySize ) |
|
iOutputArraySize = cacheInfo.iNumPolyhedrons; |
|
|
|
for( int i = cacheInfo.iStartIndex, iWriteIndex = 0; iWriteIndex != iOutputArraySize; ++i, ++iWriteIndex ) |
|
{ |
|
pOutputPolyhedronArray[iWriteIndex] = m_StaticPropPolyhedrons[i]; |
|
} |
|
|
|
return iOutputArraySize; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|