Skip to content

Commit

Permalink
server: novodex: refactored input/output streams
Browse files Browse the repository at this point in the history
  • Loading branch information
SNMetamorph committed Sep 14, 2023
1 parent 6fea70e commit 3e44eb3
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 131 deletions.
47 changes: 29 additions & 18 deletions server/novodex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,8 @@ PxConvexMesh *CPhysicNovodex :: ConvexMeshFromBmodel( entvars_t *pev, int modeli
meshDesc.points.count = numVerts;
meshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;

MemoryWriteBuffer buf;
bool status = m_pCooking->cookConvexMesh( meshDesc, buf );
MemoryWriteBuffer outputBuffer;
bool status = m_pCooking->cookConvexMesh(meshDesc, outputBuffer);
delete [] verts;

if( !status )
Expand All @@ -337,7 +337,8 @@ PxConvexMesh *CPhysicNovodex :: ConvexMeshFromBmodel( entvars_t *pev, int modeli
return NULL;
}

pHull = m_pPhysics->createConvexMesh( MemoryReadBuffer( buf.data ));
MemoryReadBuffer inputBuffer(outputBuffer.getData(), outputBuffer.getSize());
pHull = m_pPhysics->createConvexMesh(inputBuffer);
if( !pHull ) ALERT( at_error, "failed to create convex mesh from %s\n", bmodel->name );

return pHull;
Expand Down Expand Up @@ -422,8 +423,8 @@ PxTriangleMesh *CPhysicNovodex :: TriangleMeshFromBmodel( entvars_t *pev, int mo
PX_ASSERT(res);
#endif

MemoryWriteBuffer buf;
bool status = m_pCooking->cookTriangleMesh( meshDesc, buf );
MemoryWriteBuffer outputBuffer;
bool status = m_pCooking->cookTriangleMesh(meshDesc, outputBuffer);
delete [] indices;

if( !status )
Expand All @@ -432,7 +433,8 @@ PxTriangleMesh *CPhysicNovodex :: TriangleMeshFromBmodel( entvars_t *pev, int mo
return NULL;
}

pMesh = m_pPhysics->createTriangleMesh( MemoryReadBuffer( buf.data ));
MemoryReadBuffer inputBuffer(outputBuffer.getData(), outputBuffer.getSize());
pMesh = m_pPhysics->createTriangleMesh(inputBuffer);
if( !pMesh )
ALERT( at_error, "failed to create triangle mesh from %s\n", bmodel->name );

Expand Down Expand Up @@ -513,7 +515,8 @@ PxConvexMesh *CPhysicNovodex :: ConvexMeshFromStudio( entvars_t *pev, int modeli
if (CheckFileTimes(smodel->name, cacheFileName.string().c_str()))
{
// hull is never than studiomodel. Trying to load it
pHull = m_pPhysics->createConvexMesh( UserStream( cacheFileName.string().c_str(), true ));
UserStream cacheFileStream(cacheFileName.string().c_str(), true);
pHull = m_pPhysics->createConvexMesh(cacheFileStream);

if( !pHull )
{
Expand Down Expand Up @@ -659,7 +662,8 @@ PxConvexMesh *CPhysicNovodex :: ConvexMeshFromStudio( entvars_t *pev, int modeli
meshDesc.points.stride = sizeof(Vector);
meshDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;

bool status = m_pCooking->cookConvexMesh( meshDesc, UserStream( cacheFileName.string().c_str(), false ));
UserStream outputFileStream(cacheFileName.string().c_str(), false);
bool status = m_pCooking->cookConvexMesh(meshDesc, outputFileStream);

delete [] verts;
delete [] m_verts;
Expand All @@ -671,7 +675,8 @@ PxConvexMesh *CPhysicNovodex :: ConvexMeshFromStudio( entvars_t *pev, int modeli
return NULL;
}

pHull = m_pPhysics->createConvexMesh( UserStream( cacheFileName.string().c_str(), true ));
UserStream inputFileStream(cacheFileName.string().c_str(), true);
pHull = m_pPhysics->createConvexMesh(inputFileStream);
if( !pHull ) ALERT( at_error, "failed to create convex mesh from %s\n", smodel->name );

return pHull;
Expand Down Expand Up @@ -720,7 +725,8 @@ PxTriangleMesh *CPhysicNovodex::TriangleMeshFromStudio(entvars_t *pev, int model
if (CheckFileTimes(smodel->name, cacheFilePath.string().c_str()) && !m_fWorldChanged)
{
// hull is never than studiomodel. Trying to load it
pMesh = m_pPhysics->createTriangleMesh(UserStream(cacheFilePath.string().c_str(), true));
UserStream cacheFileStream(cacheFilePath.string().c_str(), true);
pMesh = m_pPhysics->createTriangleMesh(cacheFileStream);

if (!pMesh)
{
Expand Down Expand Up @@ -907,7 +913,8 @@ PxTriangleMesh *CPhysicNovodex::TriangleMeshFromStudio(entvars_t *pev, int model
PX_ASSERT(res);
#endif

bool status = m_pCooking->cookTriangleMesh(meshDesc, UserStream(cacheFilePath.string().c_str(), false));
UserStream outputFileStream(cacheFilePath.string().c_str(), false);
bool status = m_pCooking->cookTriangleMesh(meshDesc, outputFileStream);
delete[] verts;
delete[] indices;

Expand All @@ -917,7 +924,8 @@ PxTriangleMesh *CPhysicNovodex::TriangleMeshFromStudio(entvars_t *pev, int model
return NULL;
}

pMesh = m_pPhysics->createTriangleMesh(UserStream(cacheFilePath.string().c_str(), true));
UserStream inputFileStream(cacheFilePath.string().c_str(), true);
pMesh = m_pPhysics->createTriangleMesh(inputFileStream);
if (!pMesh) ALERT(at_error, "failed to create triangle mesh from %s\n", smodel->name);

return pMesh;
Expand Down Expand Up @@ -1852,12 +1860,13 @@ int CPhysicNovodex :: FLoadTree( char *szMapName )
}

// save off mapname
strcpy ( m_szMapName, szMapName );
strcpy(m_szMapName, szMapName);

char szHullFilename[MAX_PATH];

Q_snprintf( szHullFilename, sizeof( szHullFilename ), "cache/maps/%s.bin", szMapName );
m_pSceneMesh = m_pPhysics->createTriangleMesh( UserStream( szHullFilename, true ));
UserStream cacheFileStream(szHullFilename, true);
m_pSceneMesh = m_pPhysics->createTriangleMesh(cacheFileStream);
m_fWorldChanged = FALSE;

return (m_pSceneMesh != NULL) ? TRUE : FALSE;
Expand Down Expand Up @@ -2038,14 +2047,16 @@ int CPhysicNovodex :: BuildCollisionTree( char *szMapName )
char szHullFilename[MAX_PATH];
Q_snprintf( szHullFilename, sizeof( szHullFilename ), "cache/maps/%s.bin", szMapName );

if( m_pCooking )
if (m_pCooking)
{
bool status = m_pCooking->cookTriangleMesh( levelDesc, UserStream( szHullFilename, false ));
}
UserStream outputFileStream(szHullFilename, false);
bool status = m_pCooking->cookTriangleMesh(levelDesc, outputFileStream);
}

delete [] indices;

m_pSceneMesh = m_pPhysics->createTriangleMesh( UserStream( szHullFilename, true ));
UserStream inputFileStream(szHullFilename, true);
m_pSceneMesh = m_pPhysics->createTriangleMesh(inputFileStream);
m_fWorldChanged = TRUE;

return (m_pSceneMesh != NULL) ? TRUE : FALSE;
Expand Down
174 changes: 78 additions & 96 deletions server/physics/NxUserStream.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
NxUserStream.cpp - this file is a part of Novodex physics engine implementation
Copyright (C) 2012 Uncle Mike
Copyright (C) 2023 SNMetamorph
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -17,164 +18,145 @@ GNU General Public License for more details.

#include "extdll.h"
#include "util.h"
//#include "Pxf.h"
#include "NxUserStream.h"
#include <direct.h>

using namespace physx;

// user stream. constructor
UserStream :: UserStream( const char* filename, bool load ) : fp(NULL)
UserStream::UserStream(const char *filePath, bool precacheToMemory)
{
load_file = load;
m_offset = 0;
m_fileCached = precacheToMemory;
m_fileHandle = nullptr;

if( load_file )
{
int size;

// load from pack or disk
buffer = LOAD_FILE( filename, &size );
m_iLength = size;
m_iOffset = 0;
if (m_fileCached) {
fs::LoadFileToBuffer(filePath, m_dataBuffer);
}
else
{
// make sure the directories have been made
char szFilePath[MAX_PATH];
char szFullPath[MAX_PATH];

// make sure directories have been made
GET_GAME_DIR( szFilePath );

Q_snprintf( szFullPath, sizeof( szFullPath ), "%s/%s", szFilePath, filename );
CreatePath( szFullPath ); // make sure what all folders are existing

// write to disk
fp = fopen( szFullPath, "wb" );
ASSERT( fp != NULL );
m_fileHandle = fs::Open(filePath, "wb");
ASSERT(m_fileHandle != nullptr);
}
}

UserStream :: ~UserStream()
UserStream::~UserStream()
{
if( load_file )
{
FREE_FILE( buffer );
m_iOffset = m_iLength = 0;
buffer = NULL;
}
else
if (m_fileCached)
{
if( fp ) fclose( fp );
fp = NULL;
m_offset = 0;
m_dataBuffer.clear();
}
}

void UserStream :: CreatePath( char *path )
{
char *ofs, save;

for( ofs = path+1; *ofs; ofs++ )
else
{
if( *ofs == '/' || *ofs == '\\' )
{
// create the directory
save = *ofs;
*ofs = 0;
_mkdir( path );
*ofs = save;
if (m_fileHandle) {
fs::Close(m_fileHandle);
}
m_fileHandle = nullptr;
}
}

// Loading API
uint32_t UserStream::read( void *outbuf, uint32_t size )
uint32_t UserStream::read(void *outputBuf, uint32_t size)
{
if( size == 0 )
if (size == 0) {
return 0;
}

#ifdef _DEBUG
// in case we failed to loading file
memset( outbuf, 0x00, size );
memset(outputBuf, 0x00, size);
#endif
if( !buffer || !outbuf )

size_t bufferLength = m_dataBuffer.size();
if (!bufferLength || !outputBuf)
return 0;

// check for enough room
if( m_iOffset >= m_iLength )
if (m_offset >= bufferLength) {
ALERT(at_warning, "UserStream::read: precached file buffer overrun\n");
return 0; // hit EOF
}

size_t read_size = 0;

if( m_iOffset + size <= m_iLength )
if (m_offset + size <= bufferLength)
{
memcpy( outbuf, buffer + m_iOffset, size );
(size_t)m_iOffset += size;
read_size = size;
memcpy(outputBuf, m_dataBuffer.data() + m_offset, size);
m_offset += size;
return size;
}
else
{
size_t reduced_size = m_iLength - m_iOffset;
memcpy( outbuf, buffer + m_iOffset, reduced_size );
(size_t)m_iOffset += reduced_size;
read_size = reduced_size;
ALERT( at_warning, "readBuffer: buffer is overrun\n" );
ALERT(at_warning, "UserStream::read: precached file buffer overrun\n");
size_t reducedSize = bufferLength - m_offset;
memcpy(outputBuf, m_dataBuffer.data() + m_offset, reducedSize);
m_offset += reducedSize;
return reducedSize;
}

return read_size;
}

// Saving API
uint32_t UserStream::write( const void *buffer, uint32_t size )
uint32_t UserStream::write(const void *inputBuf, uint32_t size)
{
size_t w = fwrite( buffer, size, 1, fp );
return w;
ASSERT(m_fileHandle != nullptr);
return fs::Write(const_cast<void*>(inputBuf), size, m_fileHandle);
}

MemoryWriteBuffer::MemoryWriteBuffer() : currentSize(0), maxSize(0), data(NULL)
MemoryWriteBuffer::MemoryWriteBuffer()
{
m_currentSize = 0;
}

MemoryWriteBuffer::~MemoryWriteBuffer()
{
free( data );
m_dataBuffer.clear();
}

uint32_t MemoryWriteBuffer::write( const void *buffer, uint32_t size )
uint32_t MemoryWriteBuffer::write(const void *inputBuf, uint32_t size)
{
PxU32 expectedSize = currentSize + size;
if( expectedSize > maxSize )
{
maxSize = expectedSize + 4096;

PxU8 *newData = (PxU8 *)malloc( maxSize );
if( data )
{
memcpy( newData, data, currentSize );
free( data );
}
data = newData;
const size_t growthSize = 4096;
size_t expectedSize = m_currentSize + size;
if (expectedSize > m_dataBuffer.size()) {
m_dataBuffer.resize(expectedSize + growthSize);
}

memcpy( data + currentSize, buffer, size );
currentSize += size;
memcpy(m_dataBuffer.data() + m_currentSize, inputBuf, size);
m_currentSize += size;
return size;
}

MemoryReadBuffer::MemoryReadBuffer(const PxU8* data) : buffer(data)
size_t MemoryWriteBuffer::getSize() const
{
return m_dataBuffer.size();
}

const uint8_t *MemoryWriteBuffer::getData() const
{
return m_dataBuffer.data();
}

MemoryReadBuffer::MemoryReadBuffer(const uint8_t *data, size_t dataSize)
{
m_dataSize = dataSize;
m_dataOffset = 0;
m_buffer = data;
}

MemoryReadBuffer::~MemoryReadBuffer()
{
// We don't own the data => no delete
}

uint32_t MemoryReadBuffer::read(void *dest, uint32_t count)
uint32_t MemoryReadBuffer::read(void *outputBuf, uint32_t count)
{
memcpy(dest, buffer, count);
buffer += count;
return count;
if (m_dataOffset >= m_dataSize) {
ALERT(at_warning, "MemoryReadBuffer::read: input buffer is overrun\n");
return 0;
}

size_t bytesToRead = count;
if (m_dataOffset + count > m_dataSize) {
ALERT(at_warning, "MemoryReadBuffer::read: input buffer is overrun\n");
bytesToRead = m_dataSize - m_dataOffset;
}

memcpy(outputBuf, m_buffer + m_dataOffset, bytesToRead);
m_dataOffset += bytesToRead;
return bytesToRead;
}

#endif // USE_PHYSICS_ENGINE
Loading

0 comments on commit 3e44eb3

Please sign in to comment.