Skip to content

Commit

Permalink
client/server: refactored code for using meshdesc factory
Browse files Browse the repository at this point in the history
  • Loading branch information
SNMetamorph committed Sep 3, 2023
1 parent 01ffd7f commit e373b6e
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 102 deletions.
1 change: 1 addition & 0 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ list(APPEND CLDLL_SOURCES
"${CMAKE_SOURCE_DIR}/game_shared/mathlib.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/matrix.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/meshdesc.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/meshdesc_factory.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/playermove.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/procbones.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/stringlib.cpp"
Expand Down
5 changes: 5 additions & 0 deletions client/render/gl_rmisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ GNU General Public License for more details.
#include "gl_debug.h"
#include "gl_unit_cube.h"
#include "r_weather.h"
#include "meshdesc_factory.h"

#define DEFAULT_SMOOTHNESS 0.0f
#define FILTER_SIZE 2
Expand Down Expand Up @@ -891,6 +892,10 @@ void R_NewMap( void )
tr.ambient_color = g_vecZero;
tr.smoothing_threshold = 0.642788f; // 50 degrees
}

// flush collision meshes cache on clientside
auto &meshDescFactory = CMeshDescFactory::Instance();
meshDescFactory.ClearCache();
}

/*
Expand Down
17 changes: 9 additions & 8 deletions client/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ GNU General Public License for more details.
#include "r_efx.h"
#include "trace.h"
#include "gl_studio.h"
#include "meshdesc_factory.h"

/*
=============
Expand Down Expand Up @@ -201,7 +202,7 @@ SpriteHandle LoadSprite( const char *pszName )

void Physic_SweepTest(cl_entity_t *pTouch, const Vector &start, const Vector &mins, const Vector &maxs, const Vector &end, trace_t *tr)
{
if (!pTouch->model || !pTouch->model->cache.data)
if (!pTouch->model || !pTouch->model->cache.data || pTouch->model->type != mod_studio)
{
// bad model?
tr->allsolid = false;
Expand All @@ -224,16 +225,16 @@ void Physic_SweepTest(cl_entity_t *pTouch, const Vector &start, const Vector &mi
return;
}

CMeshDesc *bodyMesh = UTIL_GetCollisionMesh(pTouch->curstate.modelindex, pTouch->curstate.body, pTouch->curstate.skin);
auto &meshDescFactory = CMeshDescFactory::Instance();
CMeshDesc &bodyMesh = meshDescFactory.CreateObject(pTouch->curstate.modelindex, pTouch->curstate.body, pTouch->curstate.skin, clipfile::GeometryType::Original);
mmesh_t *pMesh = bodyMesh.GetMesh();

if (!bodyMesh)
{
tr->allsolid = false;
return;
if (!pMesh) {
bodyMesh.StudioConstructMesh();
pMesh = bodyMesh.GetMesh();
}

mmesh_t *pMesh = bodyMesh->GetMesh();
areanode_t *pHeadNode = bodyMesh->GetHeadNode();
areanode_t *pHeadNode = bodyMesh.GetHeadNode();
entity_state_t *pev = &pTouch->curstate;

if (!pMesh)
Expand Down
1 change: 1 addition & 0 deletions server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set(SVDLL_SOURCES
"${CMAKE_SOURCE_DIR}/game_shared/virtualfs.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/trace.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/meshdesc.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/meshdesc_factory.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/filesystem_utils.cpp"
"${CMAKE_SOURCE_DIR}/game_shared/filesystem_manager.cpp"
"${CMAKE_SOURCE_DIR}/public/crclib.cpp"
Expand Down
207 changes: 114 additions & 93 deletions server/novodex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ GNU General Public License for more details.
#include "trace.h"
#include "game.h"
#include "build.h"
#include "meshdesc_factory.h"

#if defined (HAS_PHYSIC_VEHICLE)
#include "NxVehicle.h"
Expand Down Expand Up @@ -575,6 +576,17 @@ void CPhysicNovodex :: StudioCalcBonePosition( mstudiobone_t *pbone, mstudioanim
}
}

clipfile::GeometryType CPhysicNovodex::ShapeTypeToGeomType(NxShapeType shapeType)
{
switch (shapeType)
{
case NX_SHAPE_CONVEX: return clipfile::GeometryType::CookedConvexHull;
case NX_SHAPE_MESH: return clipfile::GeometryType::CookedTriangleMesh;
case NX_SHAPE_BOX: return clipfile::GeometryType::CookedBox;
default: return clipfile::GeometryType::Unknown;
}
}

NxConvexMesh *CPhysicNovodex :: ConvexMeshFromStudio( entvars_t *pev, int modelindex )
{
if( UTIL_GetModelType( modelindex ) != mod_studio )
Expand Down Expand Up @@ -2345,141 +2357,150 @@ void CPhysicNovodex :: SweepTest( CBaseEntity *pTouch, const Vector &start, cons
return;
}

mmesh_t *pMesh;
areanode_t *pHeadNode;
vec3_t scale = pTouch->pev->startpos.Length() < 0.001f ? vec3_t(1.0f) : pTouch->pev->startpos;
matrix4x4 worldToLocalMat = matrix4x4(pTouch->pev->origin, pTouch->pev->angles, scale).InvertFull();
model_t *mod = (model_t *)MODEL_HANDLE(pTouch->pev->modelindex);
NxShape *pShape = pActor->getShapes()[0];
NxShapeType shapeType = pShape->getType();
clipfile::GeometryType geomType = ShapeTypeToGeomType(shapeType);

if (!pTouch->m_CookedMesh.GetMesh())
if (geomType == clipfile::GeometryType::Unknown)
{
// update cache or build from scratch
NxShape *pShape = pActor->getShapes()[0];
int shapeType = pShape->getType();
const NxU32 *indices;
const NxVec3 *verts;
Vector triangle[3];
NxU32 NbTris;

if( shapeType == NX_SHAPE_CONVEX )
{
NxConvexShape *pConvexShape = (NxConvexShape *)pShape;
NxConvexMesh& cm = pConvexShape->getConvexMesh();
// unsupported mesh type, so skip them
tr->allsolid = false;
return;
}

NbTris = cm.getCount( 0, NX_ARRAY_TRIANGLES );
indices = (const NxU32 *)cm.getBase( 0, NX_ARRAY_TRIANGLES );
verts = (const NxVec3 *)cm.getBase( 0, NX_ARRAY_VERTICES );
}
else if( shapeType == NX_SHAPE_MESH )
auto &meshDescFactory = CMeshDescFactory::Instance();
CMeshDesc &cookedMesh = meshDescFactory.CreateObject(pTouch->pev->modelindex, pTouch->pev->body, pTouch->pev->skin, geomType);
if (!cookedMesh.GetMesh())
{
const bool presentInCache = cookedMesh.PresentInCache();
if (!presentInCache)
{
NxTriangleMeshShape *pTriangleMeshShape = (NxTriangleMeshShape *)pShape;
NxTriangleMesh& trm = pTriangleMeshShape->getTriangleMesh();
// update cache or build from scratch
const NxU32 *indices;
const NxVec3 *verts;
Vector triangle[3];
NxU32 NbTris;

NbTris = trm.getCount( 0, NX_ARRAY_TRIANGLES );
indices = (const NxU32 *)trm.getBase( 0, NX_ARRAY_TRIANGLES );
verts = (const NxVec3 *)trm.getBase( 0, NX_ARRAY_VERTICES );
}
else if( shapeType != NX_SHAPE_BOX )
{
// unsupported mesh type, so skip them
tr->allsolid = false;
return;
}
if( shapeType == NX_SHAPE_CONVEX )
{
NxConvexShape *pConvexShape = (NxConvexShape *)pShape;
NxConvexMesh& cm = pConvexShape->getConvexMesh();

if( shapeType == NX_SHAPE_BOX )
{
NxVec3 points[8];
NxVec3 ext, cnt;
NxBounds3 bounds;
NxBox obb;
NbTris = cm.getCount( 0, NX_ARRAY_TRIANGLES );
indices = (const NxU32 *)cm.getBase( 0, NX_ARRAY_TRIANGLES );
verts = (const NxVec3 *)cm.getBase( 0, NX_ARRAY_VERTICES );
}
else if( shapeType == NX_SHAPE_MESH )
{
NxTriangleMeshShape *pTriangleMeshShape = (NxTriangleMeshShape *)pShape;
NxTriangleMesh& trm = pTriangleMeshShape->getTriangleMesh();

// each box shape contain 12 triangles
pTouch->m_CookedMesh.SetModel(mod, pTouch->pev->body, pTouch->pev->skin);
pTouch->m_CookedMesh.SetDebugName(pTouch->GetModel());
pTouch->m_CookedMesh.InitMeshBuild(pActor->getNbShapes() * 12);
NbTris = trm.getCount( 0, NX_ARRAY_TRIANGLES );
indices = (const NxU32 *)trm.getBase( 0, NX_ARRAY_TRIANGLES );
verts = (const NxVec3 *)trm.getBase( 0, NX_ARRAY_VERTICES );
}

for( uint i = 0; i < pActor->getNbShapes(); i++ )
if( shapeType == NX_SHAPE_BOX )
{
NxBoxShape *pBoxShape = (NxBoxShape *)pActor->getShapes()[i];
NxMat33 absRot = pBoxShape->getGlobalOrientation();
NxVec3 absPos = pBoxShape->getGlobalPosition();
NxVec3 points[8];
NxVec3 ext, cnt;
NxBounds3 bounds;
NxBox obb;

// don't use pBoxShape->getWorldAABB it's caused to broke suspension and deadlocks !!!
pBoxShape->getWorldBounds( bounds );
bounds.getExtents( ext );
bounds.getCenter( cnt );
obb = NxBox( cnt, ext, absRot );
// each box shape contain 12 triangles
cookedMesh.InitMeshBuild(pActor->getNbShapes() * 12);

indices = (const NxU32 *)m_pUtils->NxGetBoxTriangles();
m_pUtils->NxComputeBoxPoints( obb, points );
verts = (const NxVec3 *)points;
for( uint i = 0; i < pActor->getNbShapes(); i++ )
{
NxBoxShape *pBoxShape = (NxBoxShape *)pActor->getShapes()[i];
NxMat33 absRot = pBoxShape->getGlobalOrientation();
NxVec3 absPos = pBoxShape->getGlobalPosition();

for( int j = 0; j < 12; j++ )
// don't use pBoxShape->getWorldAABB it's caused to broke suspension and deadlocks !!!
pBoxShape->getWorldBounds( bounds );
bounds.getExtents( ext );
bounds.getCenter( cnt );
obb = NxBox( cnt, ext, absRot );

indices = (const NxU32 *)m_pUtils->NxGetBoxTriangles();
m_pUtils->NxComputeBoxPoints( obb, points );
verts = (const NxVec3 *)points;

for( int j = 0; j < 12; j++ )
{
NxU32 i0 = *indices++;
NxU32 i1 = *indices++;
NxU32 i2 = *indices++;
triangle[0] = verts[i0];
triangle[1] = verts[i1];
triangle[2] = verts[i2];

// transform from world to model space
triangle[0] = worldToLocalMat.VectorTransform(triangle[0]);
triangle[1] = worldToLocalMat.VectorTransform(triangle[1]);
triangle[2] = worldToLocalMat.VectorTransform(triangle[2]);
cookedMesh.AddMeshTrinagle( triangle );
}
}
}
else
{
cookedMesh.InitMeshBuild(NbTris);
while( NbTris-- )
{
NxU32 i0 = *indices++;
NxU32 i1 = *indices++;
NxU32 i2 = *indices++;

triangle[0] = verts[i0];
triangle[1] = verts[i1];
triangle[2] = verts[i2];

// transform from world to model space
triangle[0] = worldToLocalMat.VectorTransform(triangle[0]);
triangle[1] = worldToLocalMat.VectorTransform(triangle[1]);
triangle[2] = worldToLocalMat.VectorTransform(triangle[2]);
pTouch->m_CookedMesh.AddMeshTrinagle( triangle );
cookedMesh.AddMeshTrinagle( triangle );
}
}
}
else
{
pTouch->m_CookedMesh.SetModel(mod, pTouch->pev->body, pTouch->pev->skin);
pTouch->m_CookedMesh.SetDebugName(pTouch->GetModel());
pTouch->m_CookedMesh.InitMeshBuild(NbTris);

while( NbTris-- )
{
NxU32 i0 = *indices++;
NxU32 i1 = *indices++;
NxU32 i2 = *indices++;

triangle[0] = verts[i0];
triangle[1] = verts[i1];
triangle[2] = verts[i2];
pTouch->m_CookedMesh.AddMeshTrinagle( triangle );
}
else {
cookedMesh.LoadFromCacheFile();
}

if( !pTouch->m_CookedMesh.FinishMeshBuild( ))
if (!cookedMesh.FinishMeshBuild())
{
ALERT(at_error, "failed to build cooked mesh from %s\n", pTouch->GetModel());
tr->allsolid = false;
return;
}

if (mod && mod->type == mod_studio)
else
{
pTouch->m_OriginalMesh.CMeshDesc::CMeshDesc();
pTouch->m_OriginalMesh.SetModel(mod, pTouch->pev->body, pTouch->pev->skin);
pTouch->m_OriginalMesh.SetDebugName(pTouch->GetModel());
pTouch->m_OriginalMesh.StudioConstructMesh();

if (!pTouch->m_OriginalMesh.GetMesh())
{
ALERT(at_error, "failed to build original mesh from %s\n", pTouch->GetModel());
if (!presentInCache) {
cookedMesh.SaveToCacheFile();
}
cookedMesh.FreeMeshBuild();
}
}

mmesh_t *pMesh;
areanode_t *pHeadNode;
if (mod->type == mod_studio && FBitSet(gpGlobals->trace_flags, FTRACE_MATERIAL_TRACE))
{
pMesh = pTouch->m_OriginalMesh.GetMesh();
pHeadNode = pTouch->m_OriginalMesh.GetHeadNode();
CMeshDesc &originalMesh = meshDescFactory.CreateObject(pTouch->pev->modelindex, pTouch->pev->body, pTouch->pev->skin, clipfile::GeometryType::Original);
if (!originalMesh.GetMesh())
{
originalMesh.StudioConstructMesh();
if (!originalMesh.GetMesh()) {
ALERT(at_error, "failed to build original mesh from %s\n", pTouch->GetModel());
}
}

pMesh = originalMesh.GetMesh();
pHeadNode = originalMesh.GetHeadNode();
}
else
{
pMesh = pTouch->m_CookedMesh.GetMesh();
pHeadNode = pTouch->m_CookedMesh.GetHeadNode();
pMesh = cookedMesh.GetMesh();
pHeadNode = cookedMesh.GetHeadNode();
}

TraceMesh trm;
Expand Down
3 changes: 2 additions & 1 deletion server/novodex.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ GNU General Public License for more details.
#include "NxCooking.h"
#include "NxTriangle.h"
#include "PhysXLoader.h"
#include "clipfile.h"

#define DENSITY_FACTOR 0.0013f
#define PADDING_FACTOR 0.49f
Expand Down Expand Up @@ -131,6 +132,6 @@ class CPhysicNovodex : public IPhysicLayer

void StudioCalcBoneQuaterion( mstudiobone_t *pbone, mstudioanim_t *panim, Vector4D &q );
void StudioCalcBonePosition( mstudiobone_t *pbone, mstudioanim_t *panim, Vector &pos );

clipfile::GeometryType ShapeTypeToGeomType(NxShapeType shapeType);
bool P_SpeedsMessage( char *out, size_t size );
};
5 changes: 5 additions & 0 deletions server/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "gamerules.h"
#include "teamplay_gamerules.h"
#include "physcallback.h"
#include "meshdesc_factory.h"

extern CGraph WorldGraph;
extern CSoundEnt *pSoundEnt;
Expand Down Expand Up @@ -637,6 +638,10 @@ void CWorld :: Spawn( void )
g_fGameOver = FALSE;
Precache();
SetModel(GetModel());

// flush collision meshes cache on serverside
auto &meshDescFactory = CMeshDescFactory::Instance();
meshDescFactory.ClearCache();
}

void CWorld :: Precache( void )
Expand Down

0 comments on commit e373b6e

Please sign in to comment.