MapReader: Load terrain before entities.

This allows component Init functions to make use of the terrain
immediately, instead of delaying some computations until the first
frame.

This was SVN commit r15262.
This commit is contained in:
Ykkrosh 2014-06-01 18:08:11 +00:00
parent fe3315376c
commit ceb3c3d366
3 changed files with 74 additions and 29 deletions

View File

@ -53,6 +53,7 @@ public:
CModelDecal(CTerrain* terrain, const SDecal& decal)
: m_Terrain(terrain), m_Decal(decal)
{
ENSURE(terrain != NULL);
}
/// Dynamic cast

View File

@ -131,9 +131,15 @@ void CMapReader::LoadMap(const VfsPath& pathname, const CScriptValRooted& setti
RegMemFun(this, &CMapReader::UnpackMap, L"CMapReader::UnpackMap", 1200);
// read the corresponding XML file
RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 5800);
RegMemFun(this, &CMapReader::ReadXML, L"CMapReader::ReadXML", 50);
// apply data to the world
// apply terrain data to the world
RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5);
// read entities
RegMemFun(this, &CMapReader::ReadXMLEntities, L"CMapReader::ReadXMLEntities", 5800);
// apply misc data to the world
RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5);
// load map settings script (must be done after reading map)
@ -189,10 +195,13 @@ void CMapReader::LoadRandomMap(const CStrW& scriptFile, const CScriptValRooted&
// parse RMS results into camera settings
RegMemFun(this, &CMapReader::ParseCamera, L"CMapReader::ParseCamera", 5);
// apply terrain data to the world
RegMemFun(this, &CMapReader::ApplyTerrainData, L"CMapReader::ApplyTerrainData", 5);
// parse RMS results into entities
RegMemFun(this, &CMapReader::ParseEntities, L"CMapReader::ParseEntities", 1000);
// apply data to the world
// apply misc data to the world
RegMemFun(this, &CMapReader::ApplyData, L"CMapReader::ApplyData", 5);
// load map settings script (must be done after reading map)
@ -264,8 +273,7 @@ int CMapReader::UnpackTerrain()
return 0;
}
// ApplyData: take all the input data, and rebuild the scene from it
int CMapReader::ApplyData()
int CMapReader::ApplyTerrainData()
{
if (m_PatchesPerSide == 0)
{
@ -296,6 +304,16 @@ int CMapReader::ApplyData()
}
}
CmpPtr<ICmpTerrain> cmpTerrain(*pSimContext, SYSTEM_ENTITY);
if (cmpTerrain)
cmpTerrain->ReloadTerrain();
return 0;
}
// ApplyData: take all the input data, and rebuild the scene from it
int CMapReader::ApplyData()
{
// copy over the lighting parameters
if (pLightEnv)
*pLightEnv = m_LightEnv;
@ -327,10 +345,6 @@ int CMapReader::ApplyData()
}
}
CmpPtr<ICmpTerrain> cmpTerrain(*pSimContext, SYSTEM_ENTITY);
if (cmpTerrain)
cmpTerrain->ReloadTerrain();
return 0;
}
@ -398,8 +412,11 @@ public:
CStr ReadScriptSettings();
// read everything except for entities
void ReadXML();
// return semantics: see Loader.cpp!LoadFunc.
int ProgressiveRead();
int ProgressiveReadEntities();
private:
CXeromyces xmb_file;
@ -1074,17 +1091,11 @@ int CXMLReader::ReadEntities(XMBElement parent, double end_time)
return 0;
}
int CXMLReader::ProgressiveRead()
void CXMLReader::ReadXML()
{
// yield after this time is reached. balances increased progress bar
// smoothness vs. slowing down loading.
const double end_time = timer_Time() + 200e-3;
int ret;
while (node_idx < nodes.Count)
for (int i = 0; i < nodes.Count; ++i)
{
XMBElement node = nodes.Item(node_idx);
XMBElement node = nodes.Item(i);
CStr name = xmb_file.GetElementString(node.GetNodeName());
if (name == "Terrain")
{
@ -1100,16 +1111,11 @@ int CXMLReader::ProgressiveRead()
}
else if (name == "ScriptSettings")
{
//Already loaded - this is to prevent an assertion
// Already loaded - this is to prevent an assertion
}
else if (name == "Entities")
{
if (!m_MapReader.m_SkipEntities)
{
ret = ReadEntities(node, end_time);
if (ret != 0) // error or timed out
return ret;
}
// Handled by ProgressiveReadEntities instead
}
else if (name == "Paths")
{
@ -1129,6 +1135,30 @@ int CXMLReader::ProgressiveRead()
debug_printf(L"Invalid XML element in map file: %hs\n", name.c_str());
debug_warn(L"Invalid map XML data");
}
}
}
int CXMLReader::ProgressiveReadEntities()
{
// yield after this time is reached. balances increased progress bar
// smoothness vs. slowing down loading.
const double end_time = timer_Time() + 200e-3;
int ret;
while (node_idx < nodes.Count)
{
XMBElement node = nodes.Item(node_idx);
CStr name = xmb_file.GetElementString(node.GetNodeName());
if (name == "Entities")
{
if (!m_MapReader.m_SkipEntities)
{
ret = ReadEntities(node, end_time);
if (ret != 0) // error or timed out
return ret;
}
}
node_idx++;
}
@ -1170,13 +1200,23 @@ int CMapReader::LoadMapSettings()
return 0;
}
// progressive
int CMapReader::ReadXML()
{
if (!xml_reader)
xml_reader = new CXMLReader(filename_xml, *this);
int ret = xml_reader->ProgressiveRead();
xml_reader->ReadXML();
return 0;
}
// progressive
int CMapReader::ReadXMLEntities()
{
if (!xml_reader)
xml_reader = new CXMLReader(filename_xml, *this);
int ret = xml_reader->ProgressiveReadEntities();
// finished or failed
if (ret <= 0)
{

View File

@ -79,10 +79,14 @@ private:
// ApplyData: take all the input data, and rebuild the scene from it
int ApplyData();
int ApplyTerrainData();
// ReadXML: read some other data (entities, etc) in XML format
// read some misc data from the XML file
int ReadXML();
// read entity data from the XML file
int ReadXMLEntities();
// clean up everything used during delayed load
int DelayLoadFinished();