diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/utils/vbsp/disp_ivp.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/utils/vbsp/disp_ivp.cpp')
| -rw-r--r-- | mp/src/utils/vbsp/disp_ivp.cpp | 718 |
1 files changed, 359 insertions, 359 deletions
diff --git a/mp/src/utils/vbsp/disp_ivp.cpp b/mp/src/utils/vbsp/disp_ivp.cpp index 3fe50799..1ed16518 100644 --- a/mp/src/utils/vbsp/disp_ivp.cpp +++ b/mp/src/utils/vbsp/disp_ivp.cpp @@ -1,359 +1,359 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-#include "vbsp.h"
-#include "disp_vbsp.h"
-#include "builddisp.h"
-#include "disp_common.h"
-#include "ivp.h"
-#include "disp_ivp.h"
-#include "vphysics_interface.h"
-#include "vphysics/virtualmesh.h"
-#include "utlrbtree.h"
-#include "tier1/utlbuffer.h"
-#include "materialpatch.h"
-
-struct disp_grid_t
-{
- int gridIndex;
- CUtlVector<int> dispList;
-};
-
-static CUtlVector<disp_grid_t> gDispGridList;
-
-
-
-disp_grid_t &FindOrInsertGrid( int gridIndex )
-{
- // linear search is slow, but only a few grids will be present
- for ( int i = gDispGridList.Count()-1; i >= 0; i-- )
- {
- if ( gDispGridList[i].gridIndex == gridIndex )
- {
- return gDispGridList[i];
- }
- }
- int index = gDispGridList.AddToTail();
- gDispGridList[index].gridIndex = gridIndex;
-
- // must be empty
- Assert( gDispGridList[index].dispList.Count() == 0 );
-
- return gDispGridList[index];
-}
-
-// UNDONE: Tune these or adapt them to map size or triangle count?
-#define DISP_GRID_SIZEX 4096
-#define DISP_GRID_SIZEY 4096
-#define DISP_GRID_SIZEZ 8192
-
-int Disp_GridIndex( CCoreDispInfo *pDispInfo )
-{
- // quick hash the center into the grid and put the whole terrain in that grid
- Vector mins, maxs;
- pDispInfo->GetNode(0)->GetBoundingBox( mins, maxs );
- Vector center;
- center = 0.5 * (mins + maxs);
- // make sure it's positive
- center += Vector(MAX_COORD_INTEGER,MAX_COORD_INTEGER,MAX_COORD_INTEGER);
- int gridX = center.x / DISP_GRID_SIZEX;
- int gridY = center.y / DISP_GRID_SIZEY;
- int gridZ = center.z / DISP_GRID_SIZEZ;
-
- gridX &= 0xFF;
- gridY &= 0xFF;
- gridZ &= 0xFF;
- return MAKEID( gridX, gridY, gridZ, 0 );
-}
-
-void AddToGrid( int gridIndex, int dispIndex )
-{
- disp_grid_t &grid = FindOrInsertGrid( gridIndex );
- grid.dispList.AddToTail( dispIndex );
-}
-
-MaterialSystemMaterial_t GetMatIDFromDisp( mapdispinfo_t *pMapDisp )
-{
- texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo];
- dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
- MaterialSystemMaterial_t matID = FindOriginalMaterial( TexDataStringTable_GetString( pTexData->nameStringTableID ), NULL, true );
- return matID;
-}
-
-// check this and disable virtual mesh if in use
-bool Disp_HasPower4Displacements()
-{
- for ( int i = 0; i < g_CoreDispInfos.Count(); i++ )
- {
- if ( g_CoreDispInfos[i]->GetPower() > 3 )
- {
- return true;
- }
- }
- return false;
-}
-
-// adds all displacement faces as a series of convex objects
-// UNDONE: Only add the displacements for this model?
-void Disp_AddCollisionModels( CUtlVector<CPhysCollisionEntry *> &collisionList, dmodel_t *pModel, int contentsMask)
-{
- int dispIndex;
-
- // Add each displacement to the grid hash
- for ( dispIndex = 0; dispIndex < g_CoreDispInfos.Count(); dispIndex++ )
- {
- CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ];
- mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ];
-
- // not solid for this pass
- if ( !(pMapDisp->contents & contentsMask) )
- continue;
-
- int gridIndex = Disp_GridIndex( pDispInfo );
- AddToGrid( gridIndex, dispIndex );
- }
-
- // now make a polysoup for the terrain in each grid
- for ( int grid = 0; grid < gDispGridList.Count(); grid++ )
- {
- int triCount = 0;
- CPhysPolysoup *pTerrainPhysics = physcollision->PolysoupCreate();
-
- // iterate the displacements in this grid
- for ( int listIndex = 0; listIndex < gDispGridList[grid].dispList.Count(); listIndex++ )
- {
- dispIndex = gDispGridList[grid].dispList[listIndex];
- CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ];
- mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ];
-
- // Get the material id.
- MaterialSystemMaterial_t matID = GetMatIDFromDisp( pMapDisp );
-
- // Build a triangle list. This shares the tesselation code with the engine.
- CUtlVector<unsigned short> indices;
- CVBSPTesselateHelper helper;
- helper.m_pIndices = &indices;
- helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base();
- helper.m_pPowerInfo = pDispInfo->GetPowerInfo();
-
- ::TesselateDisplacement( &helper );
-
- Assert( indices.Count() > 0 );
- Assert( indices.Count() % 3 == 0 ); // Make sure indices are a multiple of 3.
- int nTriCount = indices.Count() / 3;
- triCount += nTriCount;
- if ( triCount >= 65536 )
- {
- // don't put more than 64K tris in any single collision model
- CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false );
- if ( pCollide )
- {
- collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) );
- }
- // Throw this polysoup away and start over for the remaining triangles
- physcollision->PolysoupDestroy( pTerrainPhysics );
- pTerrainPhysics = physcollision->PolysoupCreate();
- triCount = nTriCount;
- }
- Vector tmpVerts[3];
- for ( int iTri = 0; iTri < nTriCount; ++iTri )
- {
- float flAlphaTotal = 0.0f;
- for ( int iTriVert = 0; iTriVert < 3; ++iTriVert )
- {
- pDispInfo->GetVert( indices[iTri*3+iTriVert], tmpVerts[iTriVert] );
- flAlphaTotal += pDispInfo->GetAlpha( indices[iTri*3+iTriVert] );
- }
-
- int nProp = g_SurfaceProperties[texinfo[pMapDisp->face.texinfo].texdata];
- if ( flAlphaTotal > DISP_ALPHA_PROP_DELTA )
- {
- int nProp2 = GetSurfaceProperties2( matID, "surfaceprop2" );
- if ( nProp2 != -1 )
- {
- nProp = nProp2;
- }
- }
- int nMaterialIndex = RemapWorldMaterial( nProp );
- physcollision->PolysoupAddTriangle( pTerrainPhysics, tmpVerts[0], tmpVerts[1], tmpVerts[2], nMaterialIndex );
- }
- }
-
- // convert the whole grid's polysoup to a collide and store in the collision list
- CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false );
- if ( pCollide )
- {
- collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) );
- }
- // now that we have the collide, we're done with the soup
- physcollision->PolysoupDestroy( pTerrainPhysics );
- }
-}
-
-
-class CDispMeshEvent : public IVirtualMeshEvent
-{
-public:
- CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo );
- virtual void GetVirtualMesh( void *userData, virtualmeshlist_t *pList );
- virtual void GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs );
- virtual void GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList );
-
- CUtlVector<Vector> m_verts;
- unsigned short *m_pIndices;
- int m_indexCount;
-};
-
-CDispMeshEvent::CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo )
-{
- m_pIndices = pIndices;
- m_indexCount = indexCount;
- int maxIndex = 0;
- for ( int i = 0; i < indexCount; i++ )
- {
- if ( pIndices[i] > maxIndex )
- {
- maxIndex = pIndices[i];
- }
- }
- for ( int i = 0; i < indexCount/2; i++ )
- {
- V_swap( pIndices[i], pIndices[(indexCount-i)-1] );
- }
- int count = maxIndex + 1;
- m_verts.SetCount( count );
- for ( int i = 0; i < count; i++ )
- {
- m_verts[i] = pDispInfo->GetVert(i);
- }
-}
-
-void CDispMeshEvent::GetVirtualMesh( void *userData, virtualmeshlist_t *pList )
-{
- Assert(userData==((void *)this));
- pList->pVerts = m_verts.Base();
- pList->indexCount = m_indexCount;
- pList->triangleCount = m_indexCount/3;
- pList->vertexCount = m_verts.Count();
- pList->surfacePropsIndex = 0; // doesn't matter here, reset at runtime
- pList->pHull = NULL;
- int indexMax = ARRAYSIZE(pList->indices);
- int indexCount = min(m_indexCount, indexMax);
- Assert(m_indexCount < indexMax);
- Q_memcpy( pList->indices, m_pIndices, sizeof(*m_pIndices) * indexCount );
-}
-
-void CDispMeshEvent::GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs )
-{
- Assert(userData==((void *)this));
- ClearBounds( *pMins, *pMaxs );
- for ( int i = 0; i < m_verts.Count(); i++ )
- {
- AddPointToBounds( m_verts[i], *pMins, *pMaxs );
- }
-}
-
-void CDispMeshEvent::GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList )
-{
- Assert(userData==((void *)this));
- pList->triangleCount = m_indexCount/3;
- int indexMax = ARRAYSIZE(pList->triangleIndices);
- int indexCount = min(m_indexCount, indexMax);
- Assert(m_indexCount < MAX_VIRTUAL_TRIANGLES*3);
- Q_memcpy( pList->triangleIndices, m_pIndices, sizeof(*m_pIndices) * indexCount );
-}
-
-void Disp_BuildVirtualMesh( int contentsMask )
-{
- CUtlVector<CPhysCollide *> virtualMeshes;
- virtualMeshes.EnsureCount( g_CoreDispInfos.Count() );
- for ( int i = 0; i < g_CoreDispInfos.Count(); i++ )
- {
- CCoreDispInfo *pDispInfo = g_CoreDispInfos[ i ];
- mapdispinfo_t *pMapDisp = &mapdispinfo[ i ];
-
- virtualMeshes[i] = NULL;
- // not solid for this pass
- if ( !(pMapDisp->contents & contentsMask) )
- continue;
-
- // Build a triangle list. This shares the tesselation code with the engine.
- CUtlVector<unsigned short> indices;
- CVBSPTesselateHelper helper;
- helper.m_pIndices = &indices;
- helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base();
- helper.m_pPowerInfo = pDispInfo->GetPowerInfo();
-
- ::TesselateDisplacement( &helper );
-
- // validate the collision data
- if ( 1 )
- {
- int triCount = indices.Count() / 3;
- for ( int j = 0; j < triCount; j++ )
- {
- int index = j * 3;
- Vector v0 = pDispInfo->GetVert( indices[index+0] );
- Vector v1 = pDispInfo->GetVert( indices[index+1] );
- Vector v2 = pDispInfo->GetVert( indices[index+2] );
- if ( v0 == v1 || v1 == v2 || v2 == v0 )
- {
- Warning( "Displacement %d has bad geometry near %.2f %.2f %.2f\n", i, v0.x, v0.y, v0.z );
- texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo];
- dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
- const char *pMatName = TexDataStringTable_GetString( pTexData->nameStringTableID );
-
- Error( "Can't compile displacement physics, exiting. Texture is %s\n", pMatName );
- }
- }
-
- }
- CDispMeshEvent meshHandler( indices.Base(), indices.Count(), pDispInfo );
- virtualmeshparams_t params;
- params.buildOuterHull = true;
- params.pMeshEventHandler = &meshHandler;
- params.userData = &meshHandler;
- virtualMeshes[i] = physcollision->CreateVirtualMesh( params );
- }
- unsigned int totalSize = 0;
- CUtlBuffer buf;
- dphysdisp_t header;
- header.numDisplacements = g_CoreDispInfos.Count();
- buf.PutObjects( &header );
-
- CUtlVector<char> dispBuf;
- for ( int i = 0; i < header.numDisplacements; i++ )
- {
- if ( virtualMeshes[i] )
- {
- unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
- totalSize += testSize;
- buf.PutShort( testSize );
- }
- else
- {
- buf.PutShort( -1 );
- }
- }
- for ( int i = 0; i < header.numDisplacements; i++ )
- {
- if ( virtualMeshes[i] )
- {
- unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
- dispBuf.RemoveAll();
- dispBuf.EnsureCount(testSize);
-
- unsigned int outSize = physcollision->CollideWrite( dispBuf.Base(), virtualMeshes[i], false );
- Assert( outSize == testSize );
- buf.Put( dispBuf.Base(), outSize );
- }
- }
- g_PhysDispSize = totalSize + sizeof(dphysdisp_t) + (sizeof(unsigned short) * header.numDisplacements);
- Assert( buf.TellMaxPut() == g_PhysDispSize );
- g_PhysDispSize = buf.TellMaxPut();
- g_pPhysDisp = new byte[g_PhysDispSize];
- Q_memcpy( g_pPhysDisp, buf.Base(), g_PhysDispSize );
-}
-
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// +#include "vbsp.h" +#include "disp_vbsp.h" +#include "builddisp.h" +#include "disp_common.h" +#include "ivp.h" +#include "disp_ivp.h" +#include "vphysics_interface.h" +#include "vphysics/virtualmesh.h" +#include "utlrbtree.h" +#include "tier1/utlbuffer.h" +#include "materialpatch.h" + +struct disp_grid_t +{ + int gridIndex; + CUtlVector<int> dispList; +}; + +static CUtlVector<disp_grid_t> gDispGridList; + + + +disp_grid_t &FindOrInsertGrid( int gridIndex ) +{ + // linear search is slow, but only a few grids will be present + for ( int i = gDispGridList.Count()-1; i >= 0; i-- ) + { + if ( gDispGridList[i].gridIndex == gridIndex ) + { + return gDispGridList[i]; + } + } + int index = gDispGridList.AddToTail(); + gDispGridList[index].gridIndex = gridIndex; + + // must be empty + Assert( gDispGridList[index].dispList.Count() == 0 ); + + return gDispGridList[index]; +} + +// UNDONE: Tune these or adapt them to map size or triangle count? +#define DISP_GRID_SIZEX 4096 +#define DISP_GRID_SIZEY 4096 +#define DISP_GRID_SIZEZ 8192 + +int Disp_GridIndex( CCoreDispInfo *pDispInfo ) +{ + // quick hash the center into the grid and put the whole terrain in that grid + Vector mins, maxs; + pDispInfo->GetNode(0)->GetBoundingBox( mins, maxs ); + Vector center; + center = 0.5 * (mins + maxs); + // make sure it's positive + center += Vector(MAX_COORD_INTEGER,MAX_COORD_INTEGER,MAX_COORD_INTEGER); + int gridX = center.x / DISP_GRID_SIZEX; + int gridY = center.y / DISP_GRID_SIZEY; + int gridZ = center.z / DISP_GRID_SIZEZ; + + gridX &= 0xFF; + gridY &= 0xFF; + gridZ &= 0xFF; + return MAKEID( gridX, gridY, gridZ, 0 ); +} + +void AddToGrid( int gridIndex, int dispIndex ) +{ + disp_grid_t &grid = FindOrInsertGrid( gridIndex ); + grid.dispList.AddToTail( dispIndex ); +} + +MaterialSystemMaterial_t GetMatIDFromDisp( mapdispinfo_t *pMapDisp ) +{ + texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo]; + dtexdata_t *pTexData = GetTexData( pTexInfo->texdata ); + MaterialSystemMaterial_t matID = FindOriginalMaterial( TexDataStringTable_GetString( pTexData->nameStringTableID ), NULL, true ); + return matID; +} + +// check this and disable virtual mesh if in use +bool Disp_HasPower4Displacements() +{ + for ( int i = 0; i < g_CoreDispInfos.Count(); i++ ) + { + if ( g_CoreDispInfos[i]->GetPower() > 3 ) + { + return true; + } + } + return false; +} + +// adds all displacement faces as a series of convex objects +// UNDONE: Only add the displacements for this model? +void Disp_AddCollisionModels( CUtlVector<CPhysCollisionEntry *> &collisionList, dmodel_t *pModel, int contentsMask) +{ + int dispIndex; + + // Add each displacement to the grid hash + for ( dispIndex = 0; dispIndex < g_CoreDispInfos.Count(); dispIndex++ ) + { + CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ]; + mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ]; + + // not solid for this pass + if ( !(pMapDisp->contents & contentsMask) ) + continue; + + int gridIndex = Disp_GridIndex( pDispInfo ); + AddToGrid( gridIndex, dispIndex ); + } + + // now make a polysoup for the terrain in each grid + for ( int grid = 0; grid < gDispGridList.Count(); grid++ ) + { + int triCount = 0; + CPhysPolysoup *pTerrainPhysics = physcollision->PolysoupCreate(); + + // iterate the displacements in this grid + for ( int listIndex = 0; listIndex < gDispGridList[grid].dispList.Count(); listIndex++ ) + { + dispIndex = gDispGridList[grid].dispList[listIndex]; + CCoreDispInfo *pDispInfo = g_CoreDispInfos[ dispIndex ]; + mapdispinfo_t *pMapDisp = &mapdispinfo[ dispIndex ]; + + // Get the material id. + MaterialSystemMaterial_t matID = GetMatIDFromDisp( pMapDisp ); + + // Build a triangle list. This shares the tesselation code with the engine. + CUtlVector<unsigned short> indices; + CVBSPTesselateHelper helper; + helper.m_pIndices = &indices; + helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base(); + helper.m_pPowerInfo = pDispInfo->GetPowerInfo(); + + ::TesselateDisplacement( &helper ); + + Assert( indices.Count() > 0 ); + Assert( indices.Count() % 3 == 0 ); // Make sure indices are a multiple of 3. + int nTriCount = indices.Count() / 3; + triCount += nTriCount; + if ( triCount >= 65536 ) + { + // don't put more than 64K tris in any single collision model + CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false ); + if ( pCollide ) + { + collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) ); + } + // Throw this polysoup away and start over for the remaining triangles + physcollision->PolysoupDestroy( pTerrainPhysics ); + pTerrainPhysics = physcollision->PolysoupCreate(); + triCount = nTriCount; + } + Vector tmpVerts[3]; + for ( int iTri = 0; iTri < nTriCount; ++iTri ) + { + float flAlphaTotal = 0.0f; + for ( int iTriVert = 0; iTriVert < 3; ++iTriVert ) + { + pDispInfo->GetVert( indices[iTri*3+iTriVert], tmpVerts[iTriVert] ); + flAlphaTotal += pDispInfo->GetAlpha( indices[iTri*3+iTriVert] ); + } + + int nProp = g_SurfaceProperties[texinfo[pMapDisp->face.texinfo].texdata]; + if ( flAlphaTotal > DISP_ALPHA_PROP_DELTA ) + { + int nProp2 = GetSurfaceProperties2( matID, "surfaceprop2" ); + if ( nProp2 != -1 ) + { + nProp = nProp2; + } + } + int nMaterialIndex = RemapWorldMaterial( nProp ); + physcollision->PolysoupAddTriangle( pTerrainPhysics, tmpVerts[0], tmpVerts[1], tmpVerts[2], nMaterialIndex ); + } + } + + // convert the whole grid's polysoup to a collide and store in the collision list + CPhysCollide *pCollide = physcollision->ConvertPolysoupToCollide( pTerrainPhysics, false ); + if ( pCollide ) + { + collisionList.AddToTail( new CPhysCollisionEntryStaticMesh( pCollide, NULL ) ); + } + // now that we have the collide, we're done with the soup + physcollision->PolysoupDestroy( pTerrainPhysics ); + } +} + + +class CDispMeshEvent : public IVirtualMeshEvent +{ +public: + CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo ); + virtual void GetVirtualMesh( void *userData, virtualmeshlist_t *pList ); + virtual void GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs ); + virtual void GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList ); + + CUtlVector<Vector> m_verts; + unsigned short *m_pIndices; + int m_indexCount; +}; + +CDispMeshEvent::CDispMeshEvent( unsigned short *pIndices, int indexCount, CCoreDispInfo *pDispInfo ) +{ + m_pIndices = pIndices; + m_indexCount = indexCount; + int maxIndex = 0; + for ( int i = 0; i < indexCount; i++ ) + { + if ( pIndices[i] > maxIndex ) + { + maxIndex = pIndices[i]; + } + } + for ( int i = 0; i < indexCount/2; i++ ) + { + V_swap( pIndices[i], pIndices[(indexCount-i)-1] ); + } + int count = maxIndex + 1; + m_verts.SetCount( count ); + for ( int i = 0; i < count; i++ ) + { + m_verts[i] = pDispInfo->GetVert(i); + } +} + +void CDispMeshEvent::GetVirtualMesh( void *userData, virtualmeshlist_t *pList ) +{ + Assert(userData==((void *)this)); + pList->pVerts = m_verts.Base(); + pList->indexCount = m_indexCount; + pList->triangleCount = m_indexCount/3; + pList->vertexCount = m_verts.Count(); + pList->surfacePropsIndex = 0; // doesn't matter here, reset at runtime + pList->pHull = NULL; + int indexMax = ARRAYSIZE(pList->indices); + int indexCount = min(m_indexCount, indexMax); + Assert(m_indexCount < indexMax); + Q_memcpy( pList->indices, m_pIndices, sizeof(*m_pIndices) * indexCount ); +} + +void CDispMeshEvent::GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs ) +{ + Assert(userData==((void *)this)); + ClearBounds( *pMins, *pMaxs ); + for ( int i = 0; i < m_verts.Count(); i++ ) + { + AddPointToBounds( m_verts[i], *pMins, *pMaxs ); + } +} + +void CDispMeshEvent::GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList ) +{ + Assert(userData==((void *)this)); + pList->triangleCount = m_indexCount/3; + int indexMax = ARRAYSIZE(pList->triangleIndices); + int indexCount = min(m_indexCount, indexMax); + Assert(m_indexCount < MAX_VIRTUAL_TRIANGLES*3); + Q_memcpy( pList->triangleIndices, m_pIndices, sizeof(*m_pIndices) * indexCount ); +} + +void Disp_BuildVirtualMesh( int contentsMask ) +{ + CUtlVector<CPhysCollide *> virtualMeshes; + virtualMeshes.EnsureCount( g_CoreDispInfos.Count() ); + for ( int i = 0; i < g_CoreDispInfos.Count(); i++ ) + { + CCoreDispInfo *pDispInfo = g_CoreDispInfos[ i ]; + mapdispinfo_t *pMapDisp = &mapdispinfo[ i ]; + + virtualMeshes[i] = NULL; + // not solid for this pass + if ( !(pMapDisp->contents & contentsMask) ) + continue; + + // Build a triangle list. This shares the tesselation code with the engine. + CUtlVector<unsigned short> indices; + CVBSPTesselateHelper helper; + helper.m_pIndices = &indices; + helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base(); + helper.m_pPowerInfo = pDispInfo->GetPowerInfo(); + + ::TesselateDisplacement( &helper ); + + // validate the collision data + if ( 1 ) + { + int triCount = indices.Count() / 3; + for ( int j = 0; j < triCount; j++ ) + { + int index = j * 3; + Vector v0 = pDispInfo->GetVert( indices[index+0] ); + Vector v1 = pDispInfo->GetVert( indices[index+1] ); + Vector v2 = pDispInfo->GetVert( indices[index+2] ); + if ( v0 == v1 || v1 == v2 || v2 == v0 ) + { + Warning( "Displacement %d has bad geometry near %.2f %.2f %.2f\n", i, v0.x, v0.y, v0.z ); + texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo]; + dtexdata_t *pTexData = GetTexData( pTexInfo->texdata ); + const char *pMatName = TexDataStringTable_GetString( pTexData->nameStringTableID ); + + Error( "Can't compile displacement physics, exiting. Texture is %s\n", pMatName ); + } + } + + } + CDispMeshEvent meshHandler( indices.Base(), indices.Count(), pDispInfo ); + virtualmeshparams_t params; + params.buildOuterHull = true; + params.pMeshEventHandler = &meshHandler; + params.userData = &meshHandler; + virtualMeshes[i] = physcollision->CreateVirtualMesh( params ); + } + unsigned int totalSize = 0; + CUtlBuffer buf; + dphysdisp_t header; + header.numDisplacements = g_CoreDispInfos.Count(); + buf.PutObjects( &header ); + + CUtlVector<char> dispBuf; + for ( int i = 0; i < header.numDisplacements; i++ ) + { + if ( virtualMeshes[i] ) + { + unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] ); + totalSize += testSize; + buf.PutShort( testSize ); + } + else + { + buf.PutShort( -1 ); + } + } + for ( int i = 0; i < header.numDisplacements; i++ ) + { + if ( virtualMeshes[i] ) + { + unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] ); + dispBuf.RemoveAll(); + dispBuf.EnsureCount(testSize); + + unsigned int outSize = physcollision->CollideWrite( dispBuf.Base(), virtualMeshes[i], false ); + Assert( outSize == testSize ); + buf.Put( dispBuf.Base(), outSize ); + } + } + g_PhysDispSize = totalSize + sizeof(dphysdisp_t) + (sizeof(unsigned short) * header.numDisplacements); + Assert( buf.TellMaxPut() == g_PhysDispSize ); + g_PhysDispSize = buf.TellMaxPut(); + g_pPhysDisp = new byte[g_PhysDispSize]; + Q_memcpy( g_pPhysDisp, buf.Base(), g_PhysDispSize ); +} + |