#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 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 m_models = {}; CAssetArc m_meshes = {}; CAssetArc 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;