diff --git a/framework2/GTAData.cpp b/framework2/GTAData.cpp index 8f4fd321..08fa1455 100644 --- a/framework2/GTAData.cpp +++ b/framework2/GTAData.cpp @@ -57,12 +57,16 @@ void GTAData::load() void GTAData::loadIDE(const std::string& name) { - std::cout << "IDE File " << name << std::endl; - - LoaderIDE ideLoader; - if ( ! ideLoader.load(datpath + name)) { - std::cerr << "COULD NOT LOAD IDE FILE '" << name << "' FOR SOME REASON" << std::endl; + std::string lowername = name; + for(size_t t = 0; t < lowername.size(); ++t) + { + lowername[t] = tolower(lowername[t]); + if(lowername[t] == '\\') { + lowername[t] = '/'; + } } + + ideLocations.insert({lowername, datpath+"/"+lowername}); } void GTAData::loadCOL(const size_t zone, const std::string& name) diff --git a/framework2/GTAEngine.cpp b/framework2/GTAEngine.cpp index 908bf8b0..3565a985 100644 --- a/framework2/GTAEngine.cpp +++ b/framework2/GTAEngine.cpp @@ -1,8 +1,9 @@ #include #include +#include GTAEngine::GTAEngine(const std::string& path) -: gameData(path), gameTime(0.f) +: itemCount(0), gameData(path), gameTime(0.f) { } @@ -11,6 +12,13 @@ bool GTAEngine::load() { gameData.load(); + // Loade all of the IDEs. + for(std::map::iterator it = gameData.ideLocations.begin(); + it != gameData.ideLocations.end(); + ++it) { + defineItems(it->second); + } + return true; } @@ -24,7 +32,36 @@ void GTAEngine::logError(const std::string& error) log.push({LogEntry::Error, gameTime, error}); } -bool GTAEngine::loadItems(const std::string& name) +bool GTAEngine::defineItems(const std::string& name) +{ + auto i = gameData.ideLocations.find(name); + std::string path = name; + + if( i != gameData.ideLocations.end()) { + path = i->second; + } + else { + std::cout << "IDE not pre-listed" << std::endl; + } + + LoaderIDE idel; + + if(idel.load(path)) { + for( size_t o = 0; o < idel.OBJSs.size(); ++o) { + objectTypes.insert({ + idel.OBJSs[o].ID, + std::shared_ptr(new LoaderIDE::OBJS_t(idel.OBJSs[o])) + }); + } + } + else { + std::cerr << "Failed to load IDE " << path << std::endl; + } + + return false; +} + +bool GTAEngine::placeItems(const std::string& name) { auto i = gameData.iplLocations.find(name); std::string path = name; @@ -42,8 +79,19 @@ bool GTAEngine::loadItems(const std::string& name) if(ipll.load(path)) { - instances.insert(instances.end(), ipll.m_instances.begin(), ipll.m_instances.end()); + // Find the object. + for( size_t i = 0; i < ipll.m_instances.size(); ++i) { + LoaderIPLInstance& inst = ipll.m_instances[i]; + auto oi = objectTypes.find(inst.id); + if( oi != objectTypes.end()) { + objectInstances.push_back({ inst, oi->second }); + } + else { + std::cerr << "No object for instance " << inst.id << " (" << path << ")" << std::endl; + } + } itemCentroid += ipll.centroid; + itemCount += ipll.m_instances.size(); return true; } else diff --git a/framework2/GTARenderer.cpp b/framework2/GTARenderer.cpp index 8aa19793..b7528f04 100644 --- a/framework2/GTARenderer.cpp +++ b/framework2/GTARenderer.cpp @@ -85,17 +85,28 @@ void GTARenderer::renderWorld(GTAEngine* engine) auto& textureLoader = engine->gameData.textureLoader; - for (size_t i = 0; i < engine->instances.size(); ++i) { - LoaderIPLInstance &obj = engine->instances[i]; + for(size_t i = 0; i < engine->objectInstances.size(); ++i) { + GTAEngine::GTAInstance& inst = engine->objectInstances[i]; + LoaderIPLInstance &obj = inst.instance; std::string modelname = obj.model; - if (modelname.substr(0, 3) == "LOD") - continue; + std::unique_ptr &model = engine->gameData.models[modelname]; glm::quat rot(-obj.rotW, obj.rotX, obj.rotY, obj.rotZ); glm::vec3 pos(obj.posX, obj.posY, obj.posZ); glm::vec3 scale(obj.scaleX, obj.scaleY, obj.scaleZ); + float mindist = glm::length(pos - camera.worldPos); + for (size_t g = 0; g < model->geometries.size(); g++) + { + RW::BSGeometryBounds& bounds = model->geometries[g].geometryBounds; + mindist = std::min(mindist, glm::length((pos+bounds.center) - camera.worldPos) - bounds.radius); + } + if( mindist > inst.object->drawDistance[0] || (inst.object->modelName.substr(0, 3) == "LOD" && mindist > inst.object->drawDistance[0])) { + culled++; + continue; + } + if(!model) { std::cout << "model " << modelname << " not there (" << engine->gameData.models.size() << " models loaded)" << std::endl; diff --git a/framework2/include/renderwure/engine/GTAData.hpp b/framework2/include/renderwure/engine/GTAData.hpp index 72ef2b2c..c5ec3498 100644 --- a/framework2/include/renderwure/engine/GTAData.hpp +++ b/framework2/include/renderwure/engine/GTAData.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,7 @@ public: * Maps the paths in GTA3.dat to the real paths */ std::map iplLocations; + std::map ideLocations; /** * Maps file names to their locations @@ -96,7 +98,7 @@ public: * Loaded models */ std::map> models; - + }; #endif \ No newline at end of file diff --git a/framework2/include/renderwure/engine/GTAEngine.hpp b/framework2/include/renderwure/engine/GTAEngine.hpp index a5ec68e5..9a0b0351 100644 --- a/framework2/include/renderwure/engine/GTAEngine.hpp +++ b/framework2/include/renderwure/engine/GTAEngine.hpp @@ -51,16 +51,31 @@ public: */ void logError(const std::string& error); + /** + * @struct GTAObject + * Stores references to the Object data and the instance + */ + struct GTAInstance { + LoaderIPLInstance instance; + std::shared_ptr object; + }; + + /** + * Loads an IDE into the game + */ + bool defineItems(const std::string& name); + /** * Loads an IPL into the game. * @param name The name of the IPL as it appears in the games' gta.dat */ - bool loadItems(const std::string& name); + bool placeItems(const std::string& name); /** * Roughly the middle of everything */ - glm::vec3 itemCentroid; + glm::vec3 itemCentroid; + size_t itemCount; /** * Game Clock @@ -78,9 +93,15 @@ public: GTARenderer renderer; /** - * Until we have a real "object" class, just store a list of loaed instances. + * Object Definitions */ - std::vector instances; + std::map> objectTypes; + + /** + * Game Objects! + */ + std::vector objectInstances; + }; #endif \ No newline at end of file diff --git a/framework2/include/renderwure/render/ViewCamera.hpp b/framework2/include/renderwure/render/ViewCamera.hpp index cd409525..0f283457 100644 --- a/framework2/include/renderwure/render/ViewCamera.hpp +++ b/framework2/include/renderwure/render/ViewCamera.hpp @@ -9,6 +9,8 @@ public: ViewFrustum frustum; + glm::vec3 worldPos; + ViewCamera() : frustum({0.1f, 5000.f, 80.f, 1.f}) { diff --git a/viewer/main.cpp b/viewer/main.cpp index 0a28aa29..d495f2f2 100644 --- a/viewer/main.cpp +++ b/viewer/main.cpp @@ -55,12 +55,12 @@ void init(std::string gtapath) gta->load(); // Test out a known IPL. - gta->loadItems(gtapath + "/data/maps/industsw/industSW.ipl"); - gta->loadItems(gtapath + "/data/maps/industnw/industNW.ipl"); - gta->loadItems(gtapath + "/data/maps/industse/industSE.ipl"); - gta->loadItems(gtapath + "/data/maps/industne/industNE.ipl"); + gta->placeItems(gtapath + "/data/maps/industsw/industSW.ipl"); + gta->placeItems(gtapath + "/data/maps/industnw/industNW.ipl"); + gta->placeItems(gtapath + "/data/maps/industse/industSE.ipl"); + gta->placeItems(gtapath + "/data/maps/industne/industNE.ipl"); - plyPos = gta->itemCentroid / (float) gta->instances.size(); + plyPos = gta->itemCentroid / (float) gta->itemCount; } void update(float dt) @@ -106,6 +106,7 @@ void update(float dt) view = glm::translate(view, -plyPos); + gta->renderer.camera.worldPos = plyPos; gta->renderer.camera.frustum.view = view; i++;