diff --git a/CMakeLists.txt b/CMakeLists.txt index ca747f9a5..d9c60e554 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -255,14 +255,8 @@ if (APPLE) "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) # prepare plugins - if (${CMAKE_BUILD_TYPE} MATCHES "Release") - set(OPENMW_RELEASE_BUILD 1) - endif() - if (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") - set(OPENMW_RELEASE_BUILD 1) - endif() - - if (${OPENMW_RELEASE_BUILD}) + if (${CMAKE_BUILD_TYPE} MATCHES "Release" OR + ${CMAKE_BUILD_TYPE} MATCHES "RelWithDebugInfo") set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) else() set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) diff --git a/components/esm/loadpgrd.cpp b/components/esm/loadpgrd.cpp index b0727b0c0..dc63ce335 100644 --- a/components/esm/loadpgrd.cpp +++ b/components/esm/loadpgrd.cpp @@ -3,32 +3,68 @@ namespace ESM { -void PathGrid::load(ESMReader &esm) +void Pathgrid::load(ESMReader &esm) { esm.getHNT(data, "DATA", 12); cell = esm.getHNString("NAME"); - // Remember this file position - context = esm.getContext(); + // keep track of total connections so we can reserve edge vector size + int edgeCount = 0; - // Check that the sizes match up. Size = 16 * s2 (path points?) if (esm.isNextSub("PGRP")) { - esm.skipHSub(); + esm.getSubHeader(); int size = esm.getSubSize(); - if (size != 16 * data.s2) - esm.fail("Path grid table size mismatch"); + // Check that the sizes match up. Size = 16 * s2 (path points) + if (size != static_cast (sizeof(Point) * data.s2)) + esm.fail("Path point subrecord size mismatch"); + else + { + int pointCount = data.s2; + points.reserve(pointCount); + for (int i = 0; i < pointCount; ++i) + { + Point p; + esm.getExact(&p, sizeof(Point)); + points.push_back(p); + edgeCount += p.connectionNum; + } + } } - // Size varies. Path grid chances? Connections? Multiples of 4 - // suggest either int or two shorts, or perhaps a float. Study - // it later. if (esm.isNextSub("PGRC")) { - esm.skipHSub(); + esm.getSubHeader(); int size = esm.getSubSize(); - if (size % 4 != 0) + if (size % sizeof(int) != 0) esm.fail("PGRC size not a multiple of 4"); + else + { + int rawConnNum = size / sizeof(int); + std::vector rawConnections; + rawConnections.reserve(rawConnNum); + for (int i = 0; i < rawConnNum; ++i) + { + int currentValue; + esm.getT(currentValue); + rawConnections.push_back(currentValue); + } + + std::vector::const_iterator rawIt = rawConnections.begin(); + int pointIndex = 0; + edges.reserve(edgeCount); + for(PointList::const_iterator it = points.begin(); it != points.end(); it++, pointIndex++) + { + unsigned char connectionNum = (*it).connectionNum; + for (int i = 0; i < connectionNum; ++i) { + Edge edge; + edge.v0 = pointIndex; + edge.v1 = *rawIt; + rawIt++; + edges.push_back(edge); + } + } + } } } diff --git a/components/esm/loadpgrd.hpp b/components/esm/loadpgrd.hpp index 8c030d314..6e2c6e134 100644 --- a/components/esm/loadpgrd.hpp +++ b/components/esm/loadpgrd.hpp @@ -9,20 +9,37 @@ namespace ESM /* * Path grid. */ -struct PathGrid +struct Pathgrid { struct DATAstruct { int x, y; // Grid location, matches cell for exterior cells short s1; // ?? Usually but not always a power of 2. Doesn't seem // to have any relation to the size of PGRC. - short s2; // Number of path points? Size of PGRP block is always 16 * s2; + short s2; // Number of path points. }; // 12 bytes + struct Point // path grid point + { + int x, y, z; // Location of point + unsigned char autogenerated; // autogenerated vs. user coloring flag? + unsigned char connectionNum; // number of connections for this point + short unknown; + }; // 16 bytes + + struct Edge // path grid edge + { + int v0, v1; // index of points connected with this edge + }; // 8 bytes + std::string cell; // Cell name DATAstruct data; - ESM_Context context; // Context so we can return here later and - // finish the job + + typedef std::vector PointList; + PointList points; + + typedef std::vector EdgeList; + EdgeList edges; void load(ESMReader &esm); }; diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 20a2e8ff9..4aacf2332 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -390,6 +390,95 @@ namespace ESMS } }; + struct PathgridList : RecList + { + int count; + + // List of grids for interior cells. Indexed by cell name. + typedef std::map IntGrids; + IntGrids intGrids; + + // List of grids for exterior cells. Indexed as extCells[gridX][gridY]. + typedef std::map, ESM::Pathgrid*> ExtGrids; + ExtGrids extGrids; + + PathgridList() : count(0) {} + + ~PathgridList() + { + for (IntGrids::iterator it = intGrids.begin(); it!=intGrids.end(); ++it) + delete it->second; + + for (ExtGrids::iterator it = extGrids.begin(); it!=extGrids.end(); ++it) + delete it->second; + } + + int getSize() { return count; } + + virtual void listIdentifier (std::vector& identifier) const + { + // do nothing + } + + void load(ESMReader &esm, const std::string &id) + { + count++; + ESM::Pathgrid *grid = new ESM::Pathgrid; + grid->load(esm); + if (grid->data.x == 0 && grid->data.y == 0) + { + intGrids[grid->cell] = grid; + } + else + { + extGrids[std::make_pair(grid->data.x, grid->data.y)] = grid; + } + } + + Pathgrid *find(int cellX, int cellY, std::string cellName) const + { + Pathgrid *result = search(cellX, cellY, cellName); + if (!result) + { + throw std::runtime_error("no pathgrid found for cell " + cellName); + } + return result; + } + + Pathgrid *search(int cellX, int cellY, std::string cellName) const + { + Pathgrid *result = NULL; + if (cellX == 0 && cellY == 0) // possibly interior + { + IntGrids::const_iterator it = intGrids.find(cellName); + if (it != intGrids.end()) + result = it->second; + } + else + { + ExtGrids::const_iterator it = extGrids.find(std::make_pair(cellX, cellY)); + if (it != extGrids.end()) + result = it->second; + } + return result; + } + + Pathgrid *search(const ESM::Cell &cell) const + { + int cellX, cellY; + if (cell.data.flags & ESM::Cell::Interior) + { + cellX = cellY = 0; + } + else + { + cellX = cell.data.gridX; + cellY = cell.data.gridY; + } + return search(cellX, cellY, cell.name); + } + }; + template struct ScriptListT : RecList { diff --git a/components/esm_store/store.hpp b/components/esm_store/store.hpp index e3bbf9e82..fab04d3e9 100644 --- a/components/esm_store/store.hpp +++ b/components/esm_store/store.hpp @@ -74,7 +74,8 @@ namespace ESMS ScriptListT