//=========== Copyright © Valve Corporation, All rights reserved. ============// // // Purpose: Mesh clipping operations. // //===========================================================================// #include "mesh.h" #include "tier1/utlbuffer.h" void ClipTriangle( float *pBackOut, float *pFrontOut, int *pNumBackOut, int *pNumFrontOut, int nStrideFloats, float **ppVertsIn, Vector4D &vClipPlane ) { int nBack = 0; int nFront = 0; Vector vPlaneNormal = vClipPlane.AsVector3D(); const int nVerts = 3; for( int v=0; vm_nVertexCount = backMeshVerts.TellPut() / ( nVertexStrideFloats * sizeof( float ) ); if ( pMeshBack->m_nVertexCount ) { pMeshBack->AllocateMesh( pMeshBack->m_nVertexCount, pMeshBack->m_nVertexCount, nVertexStrideFloats, inputMesh.m_pAttributes, inputMesh.m_nAttributeCount ); Q_memcpy( pMeshBack->m_pVerts, backMeshVerts.Base(), backMeshVerts.TellPut() ); for ( int i=0; im_nIndexCount; ++i ) { pMeshBack->m_pIndices[i] = i; } } } if ( pMeshFront ) { pMeshFront->m_nVertexCount = frontMeshVerts.TellPut() / ( nVertexStrideFloats * sizeof( float ) ); if ( pMeshFront->m_nVertexCount ) { pMeshFront->AllocateMesh( pMeshFront->m_nVertexCount, pMeshFront->m_nVertexCount, nVertexStrideFloats, inputMesh.m_pAttributes, inputMesh.m_nAttributeCount ); Q_memcpy( pMeshFront->m_pVerts, frontMeshVerts.Base(), frontMeshVerts.TellPut() ); for ( int i=0; im_nIndexCount; ++i ) { pMeshFront->m_pIndices[i] = i; } } } return true; } //-------------------------------------------------------------------------------------- void CreateGridCellsForVolume( CUtlVector< GridVolume_t > &outputVolumes, const Vector &vTotalMinBounds, const Vector &vTotalMaxBounds, const Vector &vGridSize ) { // First, determine if we need to be split Vector vDelta = vTotalMaxBounds - vTotalMinBounds; int nX = vDelta.x / vGridSize.x; int nY = vDelta.y / vGridSize.y; int nZ = vDelta.z / vGridSize.z; Vector vEpsilon( 0.1f, 0.1f, 0.1f ); Vector vMinBounds = vTotalMinBounds - vEpsilon; Vector vMaxBounds = vTotalMaxBounds + vEpsilon; if ( nX * nY * nZ < 2 ) { GridVolume_t newbounds; newbounds.m_vMinBounds = vMinBounds; newbounds.m_vMaxBounds = vMaxBounds; outputVolumes.AddToTail( newbounds ); } else { Vector vStep; vStep.z = vDelta.z / nZ; vStep.y = vDelta.y / nY; vStep.x = vDelta.x / nX; // Create the split volumes outputVolumes.EnsureCount( nX * nY * nZ ); int nVolumes = 0; Vector vStart = vMinBounds; for ( int z=0; z &outputRanges, const CMesh &inputMesh, CUtlVector< GridVolume_t > &inputVolumes ) { DuplicateMesh( pOutputMesh, inputMesh ); int nVolumes = inputVolumes.Count(); outputRanges.EnsureCount( nVolumes ); int nFaces = inputMesh.m_nIndexCount / 3; uint32 *pInputIndices = inputMesh.m_pIndices; uint32 *pOutputIndices = pOutputMesh->m_pIndices; int nMeshIndices = 0; // Go though each volume and assign indices to its respective range for ( int v=0; v volume.m_vMinBounds.x && vCenter.x <= volume.m_vMaxBounds.x && vCenter.y > volume.m_vMinBounds.y && vCenter.y <= volume.m_vMaxBounds.y && vCenter.z > volume.m_vMinBounds.z && vCenter.z <= volume.m_vMaxBounds.z ) { // Add the whole triangle pOutputIndices[ nMeshIndices++ ] = i0; pOutputIndices[ nMeshIndices++ ] = i1; pOutputIndices[ nMeshIndices++ ] = i2; } } range.m_nIndexCount = nMeshIndices - range.m_nStartIndex; } Assert( nMeshIndices == inputMesh.m_nIndexCount ); }