1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
3 // -------------------------------------------------------------------------
4 // File name: visareamancompile.cpp
6 // Created: 15/04/2005 by Vladimir Kajalin
7 // Compilers: Visual Studio.NET
8 // Description: check vis
9 // -------------------------------------------------------------------------
12 ////////////////////////////////////////////////////////////////////////////
19 bool CVisAreaManager::GetCompiledData(byte
* pData
, int nDataSize
, std::vector
<struct IStatObj
*>** ppStatObjTable
, std::vector
<IMaterial
*>** ppMatTable
, std::vector
<struct IStatInstGroup
*>** ppStatInstGroupTable
, EEndian eEndian
, SHotUpdateInfo
* pExportInfo
)
21 #if !ENGINE_ENABLE_COMPILATION
22 CryFatalError("serialization code removed, please enable 3DENGINE_ENABLE_COMPILATION in Cry3DEngine/StdAfx.h");
25 float fStartTime
= GetCurAsyncTimeSec();
27 //bool bHMap(!pExportInfo || pExportInfo->nHeigtmap);
28 //bool bObjs(!pExportInfo || pExportInfo->nObjTypeMask);
30 // PrintMessage("Exporting indoor data (%s, %.2f MB) ...",
31 // (bHMap && bObjs) ? "Objects and heightmap" : (bHMap ? "Heightmap" : (bObjs ? "Objects" : "Nothing")), ((float)nDataSize)/1024.f/1024.f);
34 SVisAreaManChunkHeader
* pVisAreaManagerChunkHeader
= (SVisAreaManChunkHeader
*)pData
;
35 pVisAreaManagerChunkHeader
->nVersion
= VISAREAMANAGER_CHUNK_VERSION
;
36 pVisAreaManagerChunkHeader
->nDummy
= 0;
37 pVisAreaManagerChunkHeader
->nFlags
= (eEndian
== eBigEndian
) ? SERIALIZATION_FLAG_BIG_ENDIAN
: 0;
38 pVisAreaManagerChunkHeader
->nFlags2
= 0;
39 pVisAreaManagerChunkHeader
->nChunkSize
= nDataSize
;
41 SwapEndian(*pVisAreaManagerChunkHeader
, eEndian
);
43 UPDATE_PTR_AND_SIZE(pData
, nDataSize
, sizeof(SVisAreaManChunkHeader
));
45 pVisAreaManagerChunkHeader
->nVisAreasNum
= m_lstVisAreas
.Count();
46 pVisAreaManagerChunkHeader
->nPortalsNum
= m_lstPortals
.Count();
47 pVisAreaManagerChunkHeader
->nOcclAreasNum
= m_lstOcclAreas
.Count();
49 for (int i
= 0; i
< m_lstVisAreas
.Count(); i
++)
50 m_lstVisAreas
[i
]->GetData(pData
, nDataSize
, *ppStatObjTable
, *ppMatTable
, *ppStatInstGroupTable
, eEndian
, pExportInfo
);
52 for (int i
= 0; i
< m_lstPortals
.Count(); i
++)
53 m_lstPortals
[i
]->GetData(pData
, nDataSize
, *ppStatObjTable
, *ppMatTable
, *ppStatInstGroupTable
, eEndian
, pExportInfo
);
55 for (int i
= 0; i
< m_lstOcclAreas
.Count(); i
++)
56 m_lstOcclAreas
[i
]->GetData(pData
, nDataSize
, *ppStatObjTable
, *ppMatTable
, *ppStatInstGroupTable
, eEndian
, pExportInfo
);
58 SAFE_DELETE(*ppStatObjTable
);
59 SAFE_DELETE(*ppMatTable
);
60 SAFE_DELETE(*ppStatInstGroupTable
);
63 PrintMessagePlus(" done in %.2f sec", GetCurAsyncTimeSec() - fStartTime
);
65 assert(nDataSize
== 0);
66 return nDataSize
== 0;
70 int CVisAreaManager::GetCompiledDataSize(SHotUpdateInfo
* pExportInfo
)
72 #if !ENGINE_ENABLE_COMPILATION
73 CryFatalError("serialization code removed, please enable 3DENGINE_ENABLE_COMPILATION in Cry3DEngine/StdAfx.h");
81 nDataSize
+= sizeof(SVisAreaManChunkHeader
);
83 for (int i
= 0; i
< m_lstVisAreas
.Count(); i
++)
84 m_lstVisAreas
[i
]->GetData(pData
, nDataSize
, NULL
, NULL
, NULL
, eLittleEndian
, pExportInfo
);
86 for (int i
= 0; i
< m_lstPortals
.Count(); i
++)
87 m_lstPortals
[i
]->GetData(pData
, nDataSize
, NULL
, NULL
, NULL
, eLittleEndian
, pExportInfo
);
89 for (int i
= 0; i
< m_lstOcclAreas
.Count(); i
++)
90 m_lstOcclAreas
[i
]->GetData(pData
, nDataSize
, NULL
, NULL
, NULL
, eLittleEndian
, pExportInfo
);
96 bool CVisAreaManager::Load(FILE*& f
, int& nDataSize
, struct SVisAreaManChunkHeader
* pVisAreaManagerChunkHeader
, std::vector
<struct IStatObj
*>* pStatObjTable
, std::vector
<IMaterial
*>* pMatTable
)
100 // in case of small data amount (console game) load entire file into memory in single operation
101 if (nDataSize
< 4 * 1024 * 1024)
103 _smart_ptr
<IMemoryBlock
> pMemBlock
= gEnv
->pCryPak
->PoolAllocMemoryBlock(nDataSize
+ 8, "LoadIndoors");
104 byte
* pPtr
= (byte
*)pMemBlock
->GetData();
105 while (UINT_PTR(pPtr
) & 3)
108 if (GetPak()->FReadRaw(pPtr
, 1, nDataSize
- sizeof(SVisAreaManChunkHeader
), f
) != nDataSize
- sizeof(SVisAreaManChunkHeader
))
111 bRes
= Load_T(pPtr
, nDataSize
, pVisAreaManagerChunkHeader
, pStatObjTable
, pMatTable
, false, NULL
);
115 bRes
= Load_T(f
, nDataSize
, pVisAreaManagerChunkHeader
, pStatObjTable
, pMatTable
, false, NULL
);
122 bool CVisAreaManager::SetCompiledData(byte
* pData
, int nDataSize
, std::vector
<struct IStatObj
*>** ppStatObjTable
, std::vector
<IMaterial
*>** ppMatTable
, bool bHotUpdate
, SHotUpdateInfo
* pExportInfo
)
124 SVisAreaManChunkHeader
* pChunkHeader
= (SVisAreaManChunkHeader
*)pData
;
125 pData
+= sizeof(SVisAreaManChunkHeader
);
127 SwapEndian(*pChunkHeader
, eLittleEndian
);
129 bool bRes
= Load_T(pData
, nDataSize
, pChunkHeader
, *ppStatObjTable
, *ppMatTable
, bHotUpdate
, pExportInfo
);
131 SAFE_DELETE(*ppStatObjTable
);
132 SAFE_DELETE(*ppMatTable
);
139 inline void HelperUnregisterEngineObjectsInArea(PodArray
<CVisArea
*>& arrayVisArea
, const SHotUpdateInfo
* pExportInfo
, PodArray
<IRenderNode
*>& arrUnregisteredObjects
, bool bOnlyEngineObjects
)
141 for (int i
= 0; i
< arrayVisArea
.Count(); i
++)
143 if (arrayVisArea
[i
]->IsObjectsTreeValid())
145 arrayVisArea
[i
]->GetObjectsTree()->UnregisterEngineObjectsInArea(pExportInfo
, arrUnregisteredObjects
, bOnlyEngineObjects
);
151 void CVisAreaManager::UnregisterEngineObjectsInArea(const SHotUpdateInfo
* pExportInfo
, PodArray
<IRenderNode
*>& arrUnregisteredObjects
, bool bOnlyEngineObjects
)
153 HelperUnregisterEngineObjectsInArea(m_lstVisAreas
, pExportInfo
, arrUnregisteredObjects
, bOnlyEngineObjects
);
154 HelperUnregisterEngineObjectsInArea(m_lstPortals
, pExportInfo
, arrUnregisteredObjects
, bOnlyEngineObjects
);
155 HelperUnregisterEngineObjectsInArea(m_lstOcclAreas
, pExportInfo
, arrUnregisteredObjects
, bOnlyEngineObjects
);
158 void CVisAreaManager::OnVisAreaDeleted(IVisArea
* pArea
)
160 for (int i
= 0, num
= m_lstCallbacks
.size(); i
< num
; i
++)
161 m_lstCallbacks
[i
]->OnVisAreaDeleted(pArea
);
163 m_lstActiveOcclVolumes
.Delete((CVisArea
*)pArea
);
164 m_lstIndoorActiveOcclVolumes
.Delete((CVisArea
*)pArea
);
165 m_lstActiveEntransePortals
.Delete((CVisArea
*)pArea
);
169 bool CVisAreaManager::Load_T(T
*& f
, int& nDataSize
, SVisAreaManChunkHeader
* pVisAreaManagerChunkHeader
, std::vector
<IStatObj
*>* pStatObjTable
, std::vector
<IMaterial
*>* pMatTable
, bool bHotUpdate
, SHotUpdateInfo
* pExportInfo
)
171 if (pVisAreaManagerChunkHeader
->nVersion
!= VISAREAMANAGER_CHUNK_VERSION
)
172 { Error("CVisAreaManager::SetCompiledData: version of file is %d, expected version is %d", pVisAreaManagerChunkHeader
->nVersion
, (int)VISAREAMANAGER_CHUNK_VERSION
); return 0; }
174 if (pVisAreaManagerChunkHeader
->nChunkSize
!= nDataSize
)
175 { Error("CVisAreaManager::SetCompiledData: data size mismatch (%d != %d)", pVisAreaManagerChunkHeader
->nChunkSize
, nDataSize
); return 0; }
177 EEndian eEndian
= (pVisAreaManagerChunkHeader
->nFlags
& SERIALIZATION_FLAG_BIG_ENDIAN
) ? eBigEndian
: eLittleEndian
;
179 PodArray
<IRenderNode
*> arrUnregisteredObjects
;
180 UnregisterEngineObjectsInArea(pExportInfo
, arrUnregisteredObjects
, true);
182 PodArray
<IRenderNode
*> arrUnregisteredEntities
;
183 UnregisterEngineObjectsInArea(NULL
, arrUnregisteredEntities
, false);
187 SAFE_DELETE(m_pAABBTree
);
188 m_pCurArea
= m_pCurPortal
= 0;
192 m_lstVisAreas
.PreAllocate(pVisAreaManagerChunkHeader
->nVisAreasNum
, pVisAreaManagerChunkHeader
->nVisAreasNum
);
193 m_lstPortals
.PreAllocate(pVisAreaManagerChunkHeader
->nPortalsNum
, pVisAreaManagerChunkHeader
->nPortalsNum
);
194 m_lstOcclAreas
.PreAllocate(pVisAreaManagerChunkHeader
->nOcclAreasNum
, pVisAreaManagerChunkHeader
->nOcclAreasNum
);
196 nDataSize
-= sizeof(SVisAreaManChunkHeader
);
199 // PrintMessage("Importing indoor data (%s, %.2f MB) ...",
200 // (bHMap && bObjs) ? "Objects and heightmap" : (bHMap ? "Heightmap" : (bObjs ? "Objects" : "Nothing")), ((float)nDataSize)/1024.f/1024.f);
201 m_visAreas
.PreAllocate(pVisAreaManagerChunkHeader
->nVisAreasNum
);
202 m_visAreaColdData
.PreAllocate(pVisAreaManagerChunkHeader
->nVisAreasNum
);
204 m_portals
.PreAllocate(pVisAreaManagerChunkHeader
->nPortalsNum
);
205 m_portalColdData
.PreAllocate(pVisAreaManagerChunkHeader
->nPortalsNum
);
207 m_occlAreas
.PreAllocate(pVisAreaManagerChunkHeader
->nOcclAreasNum
);
208 m_occlAreaColdData
.PreAllocate(pVisAreaManagerChunkHeader
->nOcclAreasNum
);
210 for (int i
= 0; i
< m_lstVisAreas
.Count(); i
++)
211 m_lstVisAreas
[i
] = CreateTypeVisArea();
212 for (int i
= 0; i
< m_lstPortals
.Count(); i
++)
213 m_lstPortals
[i
] = CreateTypePortal();
214 for (int i
= 0; i
< m_lstOcclAreas
.Count(); i
++)
215 m_lstOcclAreas
[i
] = CreateTypeOcclArea();
219 // load areas content
220 for (int i
= 0; i
< m_lstVisAreas
.Count(); i
++)
221 m_lstVisAreas
[i
]->Load(f
, nDataSize
, pStatObjTable
, pMatTable
, eEndian
, pExportInfo
);
223 for (int i
= 0; i
< m_lstPortals
.Count(); i
++)
224 m_lstPortals
[i
]->Load(f
, nDataSize
, pStatObjTable
, pMatTable
, eEndian
, pExportInfo
);
226 for (int i
= 0; i
< m_lstOcclAreas
.Count(); i
++)
227 m_lstOcclAreas
[i
]->Load(f
, nDataSize
, pStatObjTable
, pMatTable
, eEndian
, pExportInfo
);
230 for (int i
= 0; i
< arrUnregisteredObjects
.Count(); i
++)
231 arrUnregisteredObjects
[i
]->ReleaseNode();
232 arrUnregisteredObjects
.Reset();
234 for (int i
= 0; i
< arrUnregisteredEntities
.Count(); i
++)
235 Get3DEngine()->RegisterEntity(arrUnregisteredEntities
[i
]);
236 arrUnregisteredEntities
.Reset();
238 SAFE_DELETE(m_pAABBTree
);
239 m_pCurArea
= m_pCurPortal
= 0;
242 return nDataSize
== 0;
245 //////////////////////////////////////////////////////////////////////
247 inline bool IsContainBox2D(const AABB
& base
, const AABB
& test
)
249 if (base
.min
.x
< test
.max
.x
&& base
.max
.x
> test
.min
.x
&&
250 base
.min
.y
< test
.max
.y
&& base
.max
.y
> test
.min
.y
)
257 void CVisAreaManager::ResetVisAreaList(PodArray
<CVisArea
*>& lstVisAreas
, PodArray
<CVisArea
*, ReservedVisAreaBytes
>& visAreas
, PodArray
<T
>& visAreaColdData
)
259 for (int i
= 0; i
< visAreas
.Count(); i
++)
261 CVisArea
* pVisArea
= visAreas
[i
];
262 if (pVisArea
->IsObjectsTreeValid())
263 pVisArea
->GetObjectsTree()->SetVisArea(pVisArea
);
264 pVisArea
->SetColdDataPtr(&visAreaColdData
[i
]);
265 lstVisAreas
[i
] = pVisArea
;