Files
funnygame/game/server/assetmgr.cpp
2026-03-18 18:41:28 +02:00

303 lines
6.9 KiB
C++

#include "assetmgr.h"
#include "tier2/ifilesystem.h"
#include "tier2/fileformats/json.h"
#include "game.h"
#define MAX_MODEL_COUNT 2048
#define MAX_MESH_COUNT 2048
#define MAX_MATERIAL_COUNT 2048
#define MAX_TEXTURE_COUNT 4096
#define MAX_SHADER_COUNT 1024
#define MAX_PHYSICS_COUNT 1024
template<typename T, uint32_t nCount>
class CAssetArc
{
struct ObjectHandle_t
{
CUtlString m_szName;
uint32_t m_uUsageCount;
T *m_pObject;
};
ObjectHandle_t m_objects[nCount] = {};
public:
uint32_t GetOrCreateObject( const char *szName, bool *pbHasBeenCreated )
{
uint32_t uFoundIndex = 1;
for ( uint32_t u = 1; u < nCount; u++ )
{
if (m_objects[u].m_pObject == NULL)
{
continue;
}
if (m_objects[u].m_szName == szName)
{
m_objects[u].m_uUsageCount++;
if (pbHasBeenCreated)
*pbHasBeenCreated = false;
return u;
}
}
for ( auto &m: m_objects)
{
if (m.m_pObject == NULL)
break;
uFoundIndex++;
}
m_objects[uFoundIndex].m_szName = szName;
m_objects[uFoundIndex].m_uUsageCount++;
m_objects[uFoundIndex].m_pObject = (T*)V_malloc(sizeof(T));
if (pbHasBeenCreated)
*pbHasBeenCreated = true;
return uFoundIndex;
}
T *GetObjectPtr( uint32_t uIndex )
{
if (uIndex >= nCount)
return 0;
return m_objects[uIndex].m_pObject;
}
void UnrefObject( uint32_t uIndex )
{
if (uIndex >= nCount)
return;
m_objects[uIndex].m_uUsageCount--;
if (m_objects[uIndex].m_uUsageCount == 0)
{
V_free(m_objects[uIndex].m_pObject);
m_objects[uIndex].m_pObject = NULL;
m_objects[uIndex].m_szName = NULL;
}
}
};
class CAssetManager: public IAssetManager
{
public:
virtual HFunnyModel LoadModel( const char *szName ) override;
virtual FunnyModel_t *GetModelByIndex( HFunnyModel hModel ) override;
virtual void UnrefModel( HFunnyModel uIndex ) override;
virtual HFunnyMesh LoadMesh( const char *szName ) override;
virtual FunnyMesh_t *GetMeshByIndex( HFunnyMesh hMesh ) override;
virtual void UnrefMesh( HFunnyMesh hMesh ) override;
virtual HFunnyMaterial LoadMaterial( const char *szName ) override;
virtual FunnyMaterial_t *GetMaterialByIndex( HFunnyMaterial hMat ) override;
virtual void UnrefMaterial( HFunnyMaterial hMat ) override;
virtual HFunnyPhysics LoadPhysics( const char *szName ) override;
virtual FunnyPhysics_t *GetPhysicsByIndex( HFunnyPhysics hPhysics ) override;
virtual void UnrefPhysics( HFunnyPhysics hPhysics ) override;
CAssetArc<FunnyModel_t, MAX_MODEL_COUNT> m_models = {};
CAssetArc<FunnyMesh_t, MAX_MODEL_COUNT> m_meshes = {};
CAssetArc<FunnyPhysics_t, MAX_PHYSICS_COUNT> m_physics = {};
};
FunnyModel_t *CAssetManager::GetModelByIndex( uint32_t uIndex )
{
return m_models.GetObjectPtr(uIndex);
}
FunnyMaterial_t *CAssetManager::GetMaterialByIndex( uint32_t uIndex )
{
}
FunnyMesh_t *CAssetManager::GetMeshByIndex( uint32_t uIndex )
{
return m_meshes.GetObjectPtr(uIndex);
}
uint32_t CAssetManager::LoadModel( const char *szName )
{
bool bHasBeenCreated = false;
HFunnyModel hModel = m_models.GetOrCreateObject(szName, &bHasBeenCreated);
if (!bHasBeenCreated)
return hModel;
FunnyModel_t *pModel = m_models.GetObjectPtr(hModel);
IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ);
if (!pHandle)
return 0;
CUtlString szProperties = filesystem->ReadString(pHandle);
IJSONValue *pRoot = JSONManager()->ReadString(szProperties);
filesystem->Close(pHandle);
if (!pRoot)
return 0;
IJSONObject *pMainObject;
CUtlString szMeshData;
IVertexBuffer *pVertices;
switch (pRoot->GetType())
{
case JSON_PARAMETER_OBJECT:
{
pMainObject = pRoot->GetObject();
if (!pMainObject)
{
V_printf("Failed to load properties\n");
return 0;
}
IJSONValue *pPhysics = pMainObject->GetValue("Physics");
if (pPhysics)
pModel->m_hPhysics = LoadPhysics(pPhysics->GetStringValue());
return hModel;
}
break;
default:
return 0;
}
return 0;
}
void CAssetManager::UnrefModel( uint32_t uIndex )
{
m_models.UnrefObject(uIndex);
}
uint32_t CAssetManager::LoadMaterial( const char *szName )
{
return 0;
}
void CAssetManager::UnrefMaterial( uint32_t uIndex )
{
}
HFunnyMesh CAssetManager::LoadMesh( const char *szName )
{
bool bHasBeenCreated = false;
HFunnyMesh hAsset = m_meshes.GetOrCreateObject(szName, &bHasBeenCreated);
if (!bHasBeenCreated)
return hAsset;
FunnyMesh_t *pMesh = m_meshes.GetObjectPtr(hAsset);
IFileHandle *hMesh = filesystem->Open(szName, FILEMODE_READ);
if ( hMesh == NULL )
{
V_printf("Failed to load %s\n", szName);
m_meshes.UnrefObject(hAsset);
return 0;
}
*pMesh = {};
pMesh->m_nPositionCount = filesystem->Size(hMesh)/32*3;
pMesh->m_pfPositions = new float[pMesh->m_nPositionCount];
for ( int i = 0; i < filesystem->Size(hMesh) / 32; i++)
{
filesystem->Seek( hMesh, SEEKMODE_RELATIVE_START, 32*i);
filesystem->Read( hMesh, &pMesh->m_pfPositions[i*3], 12);
}
return hAsset;
}
void CAssetManager::UnrefMesh( uint32_t uIndex )
{
}
HFunnyPhysics CAssetManager::LoadPhysics( const char *szName )
{
bool bHasBeenCreated = false;
HFunnyPhysics hPhysics = m_physics.GetOrCreateObject(szName, &bHasBeenCreated);
if (!bHasBeenCreated)
return hPhysics;
FunnyPhysics_t *pPhysics = m_physics.GetObjectPtr(hPhysics);
*pPhysics = {};
IFileHandle *pHandle = filesystem->Open(szName, FILEMODE_READ);
if (!pHandle)
return 0;
CUtlString szProperties = filesystem->ReadString(pHandle);
IJSONValue *pRoot = JSONManager()->ReadString(szProperties);
if (!pRoot)
return 0;
IJSONObject *pMainObject;
switch (pRoot->GetType())
{
case JSON_PARAMETER_OBJECT:
{
pMainObject = pRoot->GetObject();
if (!pMainObject)
{
V_printf("Failed to load properties\n");
m_physics.UnrefObject(hPhysics);
return 0;
}
IJSONValue *pTypeValue = pMainObject->GetValue("Type");
if (!pTypeValue)
{
V_printf("\"Type\" must be specified\n");
m_physics.UnrefObject(hPhysics);
return 0;
}
CUtlString szType = pTypeValue->GetStringValue();
if (szType == "Sphere")
{
pPhysics->m_hShape = g_pPhysics->CreateBall({1.0});
}
if (szType == "TriangleMesh")
{
IJSONValue *pMeshValue = pMainObject->GetValue("Mesh");
if (!pMeshValue)
{
V_printf("\"Mesh\" must be specified\n");
m_physics.UnrefObject(hPhysics);
return 0;
}
CUtlString szMesh = pMeshValue->GetStringValue();
HFunnyMesh hMesh = LoadMesh(szMesh);
FunnyMesh_t *pMesh = GetMeshByIndex(hMesh);
pPhysics->m_hShape = g_pPhysics->CreateTriangleMesh({pMesh->m_pfPositions, pMesh->m_nPositionCount, pMesh->m_puIndicies, pMesh->m_nIndiciesCount});
pPhysics->m_hMesh = hMesh;
}
return hPhysics;
}
break;
default:
return 0;
}
return hPhysics;
}
FunnyPhysics_t *CAssetManager::GetPhysicsByIndex( HFunnyPhysics hPhysics )
{
return m_physics.GetObjectPtr(hPhysics);
}
void CAssetManager::UnrefPhysics( HFunnyPhysics hPhysics )
{
m_physics.UnrefObject(hPhysics);
}
static CAssetManager s_assetmgr;
IAssetManager *g_pAssetManager = &s_assetmgr;