csgo-2018-source/engine/bsplog.cpp

182 lines
5.2 KiB
C++
Raw Normal View History

2021-07-25 12:11:47 +08:00
//===== Copyright <20> Valve Corporation, All rights reserved. ========//
#include "platform.h"
#include "bsplog.h"
#include "qhConvex.h"
#include "cmodel.h"
#include "cmodel_private.h"
#include "utlhashtable.h"
#include "tier1/fmtstr.h"
CBspDebugLog::CBspDebugLog( const char *pName )
{
m_nBaseVertex = 0;
m_File = g_pFullFileSystem->Open( pName, "wt" );
g_pFullFileSystem->FPrintf( m_File, "mtllib bsp_debug_log.mtl\n" );
m_bFlush = false;
m_nBrushCount = 0;
m_nBoxCount = 0;
/*
newmtl initialShadingGroup
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
newmtl start
illum 4
Kd 0.50 1.00 0.50
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
newmtl end
illum 4
Kd 0.50 0.50 1.00
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
newmtl irrelevant
illum 4
Kd 0.50 0.50 0.50
Ka 0.00 0.00 0.00
Tf 0.40 0.40 0.40
Ni 1.00
newmtl relevant
illum 4
Kd 0.75 0.75 0.75
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 1.00
*/
}
CBspDebugLog::~CBspDebugLog()
{
g_pFullFileSystem->Close( m_File );
}
void CBspDebugLog::AddBox( const char *pName, const char *pMtl, const Vector &mins, const Vector &maxs )
{
g_pFullFileSystem->FPrintf( m_File, "g default\nusemtl %s\n", pMtl );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", mins.x, mins.y, maxs.z );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", maxs.x, mins.y, maxs.z );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", mins.x, maxs.y, maxs.z );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", maxs.x, maxs.y, maxs.z );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", mins.x, maxs.y, mins.z );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", maxs.x, maxs.y, mins.z );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", mins.x, mins.y, mins.z );
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", maxs.x, mins.y, mins.z );
int n = m_nBaseVertex;
g_pFullFileSystem->FPrintf( m_File, "g %s\nusemtl %s\n", pName, pMtl );
g_pFullFileSystem->FPrintf( m_File, "f %d %d %d %d\n", n + 1, n + 2, n + 4, n + 3 );
g_pFullFileSystem->FPrintf( m_File, "f %d %d %d %d\n", n + 3, n + 4, n + 6, n + 5 );
g_pFullFileSystem->FPrintf( m_File, "f %d %d %d %d\n", n + 5, n + 6, n + 8, n + 7 );
g_pFullFileSystem->FPrintf( m_File, "f %d %d %d %d\n", n + 7, n + 8, n + 2, n + 1 );
g_pFullFileSystem->FPrintf( m_File, "f %d %d %d %d\n", n + 2, n + 8, n + 6, n + 4 );
g_pFullFileSystem->FPrintf( m_File, "f %d %d %d %d\n", n + 7, n + 1, n + 3, n + 5 );
m_nBaseVertex += 8;
g_pFullFileSystem->FPrintf( m_File, "s off\n" );
if ( m_bFlush )
g_pFullFileSystem->Flush( m_File );
++m_nBoxCount;
}
void CBspDebugLog::AddBrush( const char *pName, const char *pMtl, cbrushside_t * RESTRICT pSides, int nSides )
{
Vector vCenter = vec3_origin;
float flMargin = -0.25f;
float flPadding = -0.5f; // must be deeper than margin
bool bFoundCenter = false;
for ( int nAttempt = 0; nAttempt < 160; ++nAttempt )
{
bFoundCenter = true;
for ( int nSide = 0; nSide < nSides; ++nSide )
{
const cplane_t &plane = *pSides[ nSide ].plane;
float f = DotProduct( vCenter, plane.normal ) - plane.dist;
if ( f < flMargin )
continue;
bFoundCenter = false;
vCenter -= plane.normal * ( f - flPadding );
}
if ( bFoundCenter )
break;
}
if ( !bFoundCenter )
{
Msg( "Cannot find brush %s convex hull", pName );
return;
}
CUtlVector< qhVector3 > dualVerts;
dualVerts.SetCount( nSides );
for ( int i = 0; i < nSides; ++i )
{
const cplane_t &plane = *pSides[ i ].plane;
float d = plane.dist - DotProduct( plane.normal, vCenter );
Vector dv = plane.normal / d;
dualVerts[ i ].X = dv.x;
dualVerts[ i ].Y = dv.y;
dualVerts[ i ].Z = dv.z;
}
qhConvex dualConvex;
dualConvex.Construct( nSides, dualVerts.Base(), 0.00001f );
g_pFullFileSystem->FPrintf( m_File, "g default\nusemtl %s\n", pMtl );
CUtlHashtable< qhFace*, int > dualFaceToPrimalVertexIndex;
CUtlVector< CUtlString > primalFaces;
for ( const qhVertex *pDualVertex = dualConvex.GetVertexList().Begin(); pDualVertex != dualConvex.GetVertexList().End(); pDualVertex = pDualVertex->Next )
{
//Vector dualPos( dualVertex.Position.X, dualVertex.Position.Y, dualVertex.Position.Z );
qhHalfEdge *pEdge = pDualVertex->Edge;
CUtlString primalVerts;
do
{
qhFace *pFace = pEdge->Face;
UtlHashHandle_t nFind = dualFaceToPrimalVertexIndex.Find( pFace );
int nPrimalVert;
if ( nFind == dualFaceToPrimalVertexIndex.InvalidHandle() )
{
Vector vPrimal = vCenter + Vector( pFace->Plane.Normal.X, pFace->Plane.Normal.Y, pFace->Plane.Normal.Z ) / pFace->Plane.Offset;
g_pFullFileSystem->FPrintf( m_File, "v %f %f %f\n", vPrimal.x, vPrimal.y, vPrimal.z );
dualFaceToPrimalVertexIndex.Insert( pFace, nPrimalVert = ++m_nBaseVertex );
}
else
{
nPrimalVert = dualFaceToPrimalVertexIndex.Element( nFind );
}
CUtlString pv;
pv.Format( " %d", nPrimalVert );
primalVerts = pv + primalVerts;
pEdge = pEdge->Twin->Next;
}
while (pEdge != pDualVertex->Edge);
primalFaces.AddToTail( primalVerts );
}
g_pFullFileSystem->FPrintf( m_File, "g %s\nusemtl %s\n", pName, pMtl );
for ( int i = 0; i < primalFaces.Count(); ++i )
{
g_pFullFileSystem->FPrintf( m_File, "f%s\n", primalFaces[ i ].Get() );
}
if ( m_bFlush )
{
g_pFullFileSystem->Flush( m_File );
}
m_nBrushCount++;
}