diff --git a/r5dev/datacache/mdlcache.cpp b/r5dev/datacache/mdlcache.cpp
index 2250e8c8..91936ca5 100644
--- a/r5dev/datacache/mdlcache.cpp
+++ b/r5dev/datacache/mdlcache.cpp
@@ -29,30 +29,10 @@ std::unordered_set<MDLHandle_t> g_vBadMDLHandles;
 studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
 {
     studiodata_t* pStudioData = cache->GetStudioData(handle);
-    studiohdr_t* pStudioHdr;
 
-    if (pStudioData)
+    if (!pStudioData)
     {
-        if (pStudioData->m_MDLCache &&
-            pStudioData->m_MDLCache != DC_INVALID_HANDLE)
-        {
-            studiohdr_t* pStudioHDR = **reinterpret_cast<studiohdr_t***>(pStudioData);
-
-            if (!g_pMDLFallback->m_hErrorMDL && V_ComparePath(pStudioHDR->name, ERROR_MODEL))
-            {
-                g_pMDLFallback->m_pErrorHDR = pStudioHDR;
-                g_pMDLFallback->m_hErrorMDL = handle;
-            }
-            else if (!g_pMDLFallback->m_hEmptyMDL && V_ComparePath(pStudioHDR->name, EMPTY_MODEL))
-            {
-                g_pMDLFallback->m_pEmptyHDR = pStudioHDR;
-                g_pMDLFallback->m_hEmptyMDL = handle;
-            }
-        }
-    }
-    else
-    {
-        pStudioHdr = GetErrorModel();
+        studiohdr_t* const pStudioHdr = GetErrorModel();
 
         if (!IsKnownBadModel(handle))
         {
@@ -65,28 +45,54 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3)
         return pStudioHdr;
     }
 
-    int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
+    studiocache_t* studioCache = pStudioData->GetStudioCache();
+
+    // Store error and empty fallback models.
+    if (studioCache && studioCache != DC_INVALID_HANDLE)
+    {
+        studiohdr_t* const pStudioHDR = pStudioData->GetStudioCache()->GetStudioHdr();
+
+        if (pStudioHDR)
+        {
+            if (!g_pMDLFallback->m_hErrorMDL && V_ComparePath(pStudioHDR->name, ERROR_MODEL))
+            {
+                g_pMDLFallback->m_pErrorHDR = pStudioHDR;
+                g_pMDLFallback->m_hErrorMDL = handle;
+            }
+            else if (!g_pMDLFallback->m_hEmptyMDL && V_ComparePath(pStudioHDR->name, EMPTY_MODEL))
+            {
+                g_pMDLFallback->m_pEmptyHDR = pStudioHDR;
+                g_pMDLFallback->m_hEmptyMDL = handle;
+            }
+        }
+    }
+
+    const int nFlags = STUDIOHDR_FLAGS_NEEDS_DEFERRED_ADDITIVE | STUDIOHDR_FLAGS_OBSOLETE;
+
     if ((pStudioData->m_nFlags & nFlags))
     {
-        void* pMDLCache = *reinterpret_cast<void**>(pStudioData);
-        if (pStudioData->m_MDLCache)
+        if (studioCache)
         {
             if (a3)
             {
                 FindCachedMDL(cache, pStudioData, a3);
-                pMDLCache = *reinterpret_cast<void**>(pStudioData);
+                studioCache = pStudioData->m_pStudioCache;
             }
 
-            pStudioHdr = *reinterpret_cast<studiohdr_t**>(pMDLCache);
+            studiohdr_t* const pStudioHdr = studioCache->GetStudioHdr();
+
             if (pStudioHdr)
                 return pStudioHdr;
 
             return FindUncachedMDL(cache, handle, pStudioData, a3);
         }
-        pMDLCache = pStudioData->m_pAnimData;
-        if (pMDLCache)
+
+        studioanimcache_t* const animCache = pStudioData->m_pAnimCache;
+
+        if (animCache)
         {
-            pStudioHdr = *reinterpret_cast<studiohdr_t**>(pMDLCache);
+            studiohdr_t* const pStudioHdr = animCache->GetStudioHdr();
+
             if (pStudioHdr)
                 return pStudioHdr;
         }
@@ -129,9 +135,9 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
     AUTO_LOCK(pStudioData->m_Mutex);
 
     const char* szModelName = cache->GetModelName(handle);
-    size_t nFileNameLen = strlen(szModelName);
+    const size_t nFileNameLen = strlen(szModelName);
 
-    studiohdr_t* pStudioHdr;
+    studiohdr_t* pStudioHdr = nullptr;
 
     if (nFileNameLen < 5 ||
         (Q_stricmp(&szModelName[nFileNameLen - 5], ".rmdl") != 0) &&
@@ -150,16 +156,16 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
         return pStudioHdr;
     }
 
-    LOBYTE(pStudioData->m_nGuidLock) = 1;
+    pStudioData->m_bSearchingModelName = true;
     g_pRTech->StringToGuid(szModelName);
-    LOBYTE(pStudioData->m_nGuidLock) = 0;
+    pStudioData->m_bSearchingModelName = false;
 
-    if (!pStudioData->m_MDLCache)
+    if (!pStudioData->m_pStudioCache)
     {
-        studiohdr_t**  pAnimData = (studiohdr_t**)pStudioData->m_pAnimData;
-        if (pAnimData)
+        studioanimcache_t* const animCache = pStudioData->GetAnimCache();
+        if (animCache)
         {
-            pStudioHdr = *pAnimData;
+            pStudioHdr = animCache->GetStudioHdr();
         }
         else
         {
@@ -178,11 +184,11 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
     else
     {
         FindCachedMDL(cache, pStudioData, a4);
-        DataCacheHandle_t dataHandle = pStudioData->m_MDLCache;
+        studiocache_t* const dataCache = pStudioData->GetStudioCache();
 
-        if (dataHandle)
+        if (dataCache)
         {
-            if (dataHandle == DC_INVALID_HANDLE)
+            if (dataCache == DC_INVALID_HANDLE)
             {
                 pStudioHdr = GetErrorModel();
                 if (!IsKnownBadModel(handle))
@@ -194,11 +200,12 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
                 }
             }
             else
-                pStudioHdr = *(studiohdr_t**)dataHandle;
+                pStudioHdr = dataCache->GetStudioHdr();
         }
         else
         {
             pStudioHdr = GetErrorModel();
+
             if (!IsKnownBadModel(handle))
             {
                 if (!pStudioHdr)
@@ -209,6 +216,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
         }
     }
 
+    assert(pStudioHdr);
     return pStudioHdr;
 }
 
@@ -218,30 +226,28 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st
 //          handle - 
 // Output : a pointer to the studiohdr_t object
 //-----------------------------------------------------------------------------
-studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* cache, MDLHandle_t handle)
+vcollide_t* CMDLCache::GetVCollide(CMDLCache* cache, MDLHandle_t handle)
 {
-    studiohdr_t* pStudioHdr = nullptr; // rax
-
     if (!handle)
     {
-        pStudioHdr = GetErrorModel();
-        if (!pStudioHdr)
-            Error(eDLL_T::ENGINE, EXIT_FAILURE, "Attempted to load model with no handle and \"%s\" couldn't be loaded.\n", ERROR_MODEL);
-
-        return pStudioHdr;
+        Error(eDLL_T::ENGINE, NO_ERROR, "Attempted to get vcollide with no handle.\n");
+        return nullptr;
     }
 
-    studiodata_t* pStudioData = cache->GetStudioData(handle);
-    DataCacheHandle_t dataCache = pStudioData->m_MDLCache;
+    const studiodata_t* const pStudioData = cache->GetStudioData(handle);
+    const studiocache_t* const dataCache = pStudioData->GetStudioCache();
 
-    if (dataCache &&
-        dataCache != DC_INVALID_HANDLE)
+    if (dataCache && dataCache != DC_INVALID_HANDLE)
     {
-        void* v4 = *(void**)(*((_QWORD*)dataCache + 1) + 24i64);
-        if (v4)
-            pStudioHdr = (studiohdr_t*)((char*)v4 + 0x10);
+        CStudioVCollide* const pVCollide = dataCache->GetPhysicsCache()->GetStudioVCollide();
+
+        if (pVCollide)
+        {
+            return pVCollide->GetVCollide();
+        }
     }
-    return pStudioHdr;
+
+    return nullptr;
 }
 
 //-----------------------------------------------------------------------------
@@ -252,7 +258,7 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* cache, MDLHandle_t handle)
 //-----------------------------------------------------------------------------
 studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
 {
-    studiodata_t* pStudioData = cache->GetStudioData(handle);
+    const studiodata_t* pStudioData = cache->GetStudioData(handle);
 
     if (!pStudioData)
     {
@@ -264,21 +270,22 @@ studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle)
         pStudioData = cache->GetStudioData(g_pMDLFallback->m_hErrorMDL);
     }
 
-    DataCacheHandle_t dataCache = pStudioData->m_MDLCache;
+    const studiocache_t* const dataCache = pStudioData->GetStudioCache();
 
     if (dataCache)
     {
         if (dataCache == DC_INVALID_HANDLE)
             return nullptr;
 
-        void* pAnimData = (void*)*((_QWORD*)dataCache + 1);
+        studiophysicscache_t* const physicsCache = dataCache->GetPhysicsCache();
 
         AcquireSRWLockExclusive(g_pMDLLock);
-        CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(pAnimData), 1i64); // !!! DECLARED INLINE IN < S3 !!!
+        CStudioHWDataRef__SetFlags(reinterpret_cast<CStudioHWDataRef*>(physicsCache), 1i64); // !!! DECLARED INLINE IN < S3 !!!
         ReleaseSRWLockExclusive(g_pMDLLock);
     }
+
     if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED))
-        return &pStudioData->m_pHardwareRef->m_HardwareData;
+        return pStudioData->GetHardwareDataRef()->GetHardwareData();
     else
         return nullptr;
 }
@@ -313,5 +320,5 @@ void VMDLCache::Detour(const bool bAttach) const
     DetourSetup(&CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL, bAttach);
     DetourSetup(&CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL, bAttach);
     DetourSetup(&CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData, bAttach);
-    DetourSetup(&CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR, bAttach);
+    DetourSetup(&CMDLCache__GetVCollide, &CMDLCache::GetVCollide, bAttach);
 }
diff --git a/r5dev/datacache/mdlcache.h b/r5dev/datacache/mdlcache.h
index e204bb49..cd22535a 100644
--- a/r5dev/datacache/mdlcache.h
+++ b/r5dev/datacache/mdlcache.h
@@ -2,17 +2,12 @@
 #define MDLCACHE_H
 #include "tier0/threadtools.h"
 #include "tier1/utldict.h"
+#include "tier1/refcount.h"
 #include "datacache/idatacache.h"
 #include "datacache/imdlcache.h"
 #include "public/studio.h"
-
-struct RStaticProp_t
-{
-	studiohdr_t* m_pStudioHDR{};
-	CStudioHWDataRef* m_pHardWareData{};
-	const char* m_szPropName{};
-	uint8_t m_pUnknown[0x62]{};
-};
+#include "public/vphysics/vcollide.h"
+#include "public/rtech/ipakfile.h"
 
 struct RMDLFallBack_t
 {
@@ -39,11 +34,78 @@ struct RMDLFallBack_t
 	}
 };
 
+
+struct CStudioVCollide : public CRefCounted<>
+{
+public:
+	//~CStudioVCollide() // TODO: add g_PhysicsCollision to SDK
+	//{
+	//	g_pPhysicsCollision->VCollideUnload(&m_vcollide);
+	//}
+	vcollide_t* GetVCollide()
+	{
+		return &m_vcollide;
+	}
+private:
+	vcollide_t m_vcollide;
+};
+
+class CStudioPhysicsGeoms : public CRefCounted<>
+{
+	int unk1;
+	void* m_pGeomDataDesc;
+	int unk2;
+	__int16 unk3;
+	__int16 unk4;
+};
+
+struct studiophysicscache_t
+{
+	inline CStudioVCollide* GetStudioVCollide() const { return m_pVCollide; }
+	inline CStudioPhysicsGeoms* GetPhysicsGeoms() const { return m_pPhysicsGeoms; }
+
+	int unk0;
+	int unk1;
+	int unk2;
+	int unk3;
+	int unk4;
+	int unk5;
+	CStudioVCollide* m_pVCollide;
+	CStudioPhysicsGeoms* m_pPhysicsGeoms;
+};
+
+struct studiocache_t
+{
+	inline studiohdr_t* GetStudioHdr() const { return m_pStudioHdr; }
+	inline studiophysicscache_t* GetPhysicsCache() const { return m_pPhysicsCache; }
+
+	studiohdr_t* m_pStudioHdr;
+	studiophysicscache_t* m_pPhysicsCache;
+	const char* m_szPropName;
+	uint8_t m_pUnknown[98];
+};
+
+struct studioanimcache_t
+{
+	inline studiohdr_t* GetStudioHdr() const { return m_pStudioHdr; }
+
+	studiohdr_t* m_pStudioHdr;
+	const char* m_pszRigName;
+	int unk0;
+	int m_nSequenceCount;
+	void** m_pAnimSequences;
+	// TODO reverse the rest
+};
+
 // only models with type "mod_studio" have this data
 struct studiodata_t
 {
-	DataCacheHandle_t m_MDLCache;
-	void* m_pAnimData; // !TODO: reverse struct.
+	inline studiocache_t* GetStudioCache() const { return m_pStudioCache; }
+	inline studioanimcache_t* GetAnimCache() const { return m_pAnimCache; }
+	inline CStudioHWDataRef* GetHardwareDataRef() const { return m_pHardwareRef; }
+
+	studiocache_t* m_pStudioCache;
+	studioanimcache_t* m_pAnimCache; // !TODO: reverse struct.
 	unsigned short m_nRefCount;
 	unsigned short m_nFlags;
 	MDLHandle_t m_Handle;
@@ -53,7 +115,8 @@ struct studiodata_t
 	int Unk5;
 	char pad[72];
 	CThreadFastMutex m_Mutex;
-	int m_nGuidLock; // always -1, set to 1 and 0 in CMDLCache::FindUncachedMDL.
+	bool m_bSearchingModelName;
+	PakHandle_t m_PakHandle;
 };
 
 extern RMDLFallBack_t* g_pMDLFallback;
@@ -65,13 +128,14 @@ public:
 	static studiohdr_t* FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3);
 	static void FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3);
 	static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
-	static studiohdr_t* GetStudioHDR(CMDLCache* cache, MDLHandle_t handle);
+
+	static vcollide_t* GetVCollide(CMDLCache* cache, MDLHandle_t handle);
 	static studiohwdata_t* GetHardwareData(CMDLCache* cache, MDLHandle_t handle);
 	static studiohdr_t* GetErrorModel(void);
 	static bool IsKnownBadModel(MDLHandle_t handle);
 
 
-	studiodata_t* GetStudioData(MDLHandle_t handle)
+	inline studiodata_t* GetStudioData(MDLHandle_t handle)
 	{
 		EnterCriticalSection(&m_MDLMutex);
 		studiodata_t* pStudioData = m_MDLDict.Element(handle);
@@ -80,7 +144,7 @@ public:
 		return pStudioData;
 	}
 
-	const char* GetModelName(MDLHandle_t handle)
+	inline const char* GetModelName(MDLHandle_t handle)
 	{
 		EnterCriticalSection(&m_MDLMutex);
 		const char* szModelName = m_MDLDict.GetElementName(handle);
@@ -89,7 +153,7 @@ public:
 		return szModelName;
 	}
 
-	void* GetMaterialTable(MDLHandle_t handle)
+	inline void* GetMaterialTable(MDLHandle_t handle)
 	{
 		EnterCriticalSection(&m_MDLMutex);
 		studiodata_t* pStudioData = m_MDLDict.Element(handle);
@@ -108,7 +172,7 @@ inline studiohdr_t*(*CMDLCache__FindMDL)(CMDLCache* pCache, MDLHandle_t handle,
 inline void(*CMDLCache__FindCachedMDL)(CMDLCache* pCache, studiodata_t* pStudioData, void* a3);
 
 inline studiohdr_t*(*CMDLCache__FindUncachedMDL)(CMDLCache* pCache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4);
-inline studiohdr_t*(*CMDLCache__GetStudioHDR)(CMDLCache* pCache, MDLHandle_t handle);
+inline vcollide_t*(*CMDLCache__GetVCollide)(CMDLCache* pCache, MDLHandle_t handle);
 
 inline studiohwdata_t*(*CMDLCache__GetHardwareData)(CMDLCache* pCache, MDLHandle_t handle);
 inline bool(*CStudioHWDataRef__SetFlags)(CStudioHWDataRef* ref, int64_t flags); // Probably incorrect name.
@@ -124,7 +188,7 @@ class VMDLCache : public IDetour
 		LogFunAdr("CMDLCache::FindMDL", CMDLCache__FindMDL);
 		LogFunAdr("CMDLCache::FindCachedMDL", CMDLCache__FindCachedMDL);
 		LogFunAdr("CMDLCache::FindUncachedMDL", CMDLCache__FindUncachedMDL);
-		LogFunAdr("CMDLCache::GetStudioHDR", CMDLCache__GetStudioHDR);
+		LogFunAdr("CMDLCache::GetVCollide", CMDLCache__GetVCollide);
 		LogFunAdr("CMDLCache::GetHardwareData", CMDLCache__GetHardwareData);
 		LogFunAdr("CStudioHWDataRef::SetFlags", CStudioHWDataRef__SetFlags);
 
@@ -136,7 +200,7 @@ class VMDLCache : public IDetour
 		g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F1 0F B7 EA").GetPtr(CMDLCache__FindMDL);
 		g_GameDll.FindPatternSIMD("4D 85 C0 74 7A 48 89 6C 24 ??").GetPtr(CMDLCache__FindCachedMDL);
 		g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 41 56 48 83 EC 20 48 8B E9 0F B7 FA").GetPtr(CMDLCache__FindUncachedMDL);
-		g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08").GetPtr(CMDLCache__GetStudioHDR);
+		g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 5C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 03 48 8B 48 08").GetPtr(CMDLCache__GetVCollide);
 		g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC 20 48 8D 0D ?? ?? ?? ?? 0F B7 DA FF 15 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 8D 14 5B 48 8D 0D ?? ?? ?? ?? 48 8B 7C D0 ?? FF 15 ?? ?? ?? ?? 48 8B 1F").GetPtr(CMDLCache__GetHardwareData);
 		g_GameDll.FindPatternSIMD("48 83 EC 08 4C 8D 14 12").GetPtr(CStudioHWDataRef__SetFlags);
 	}
diff --git a/r5dev/public/datacache/idatacache.h b/r5dev/public/datacache/idatacache.h
index 0ff683c2..2469ee7d 100644
--- a/r5dev/public/datacache/idatacache.h
+++ b/r5dev/public/datacache/idatacache.h
@@ -6,6 +6,6 @@
 //---------------------------------------------------------
 FORWARD_DECLARE_HANDLE(memhandle_t);
 typedef memhandle_t DataCacheHandle_t;
-#define DC_INVALID_HANDLE ((DataCacheHandle_t)0xDEADFEEDDEADFEED)
+#define DC_INVALID_HANDLE ((void*)0xDEADFEEDDEADFEED)
 
 #endif // IDATACACHE_H
diff --git a/r5dev/public/studio.h b/r5dev/public/studio.h
index e75146d3..e42bd03e 100644
--- a/r5dev/public/studio.h
+++ b/r5dev/public/studio.h
@@ -1066,14 +1066,17 @@ private:
 	CMDLCache* m_pMDLCache;
 };
 
-class CStudioHWDataRef
+template<class T>
+class CStudioAssetEmbeddedRef : public CRefCounted<>
+{
+protected:
+	T m_Embedded;
+};
+
+class CStudioHWDataRef : public CStudioAssetEmbeddedRef<studiohwdata_t>
 {
 public:
-	bool IsDataRef(void) const { return true; }
-
-	CStudioHWDataRef* m_pVTable;
-	uint8_t pad0[0x8];
-	studiohwdata_t m_HardwareData;
+	studiohwdata_t* GetHardwareData() { return &m_Embedded; }
 };
 
 #endif // STUDIO_H