From 02309ba0785b894100c0d74720b0dddd79f69a87 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Sun, 8 Mar 2020 17:23:32 +0100 Subject: [PATCH 1/6] Make ZenCache a class --- src/CMakeLists.txt | 2 ++ .../{LoadCachedZEN.cpp => ZenCache.cpp} | 18 ++++++++---------- .../{LoadCachedZEN.hpp => ZenCache.hpp} | 6 ++++-- 3 files changed, 14 insertions(+), 12 deletions(-) rename src/world/internals/{LoadCachedZEN.cpp => ZenCache.cpp} (69%) rename src/world/internals/{LoadCachedZEN.hpp => ZenCache.hpp} (97%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 909f55ff..7d1b37b9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -176,6 +176,8 @@ add_library(REGothEngine STATIC world/internals/ConstructFromZEN.hpp world/internals/ImportSingleVob.cpp world/internals/ImportSingleVob.hpp + world/internals/ZenCache.cpp + world/internals/ZenCache.hpp ) target_link_libraries(REGothEngine PUBLIC bsf BsZenLib) diff --git a/src/world/internals/LoadCachedZEN.cpp b/src/world/internals/ZenCache.cpp similarity index 69% rename from src/world/internals/LoadCachedZEN.cpp rename to src/world/internals/ZenCache.cpp index 89e45eb9..9b30bc14 100644 --- a/src/world/internals/LoadCachedZEN.cpp +++ b/src/world/internals/ZenCache.cpp @@ -1,4 +1,4 @@ -#include "LoadCachedZEN.hpp" +#include "ZenCache.hpp" #include #include #include @@ -7,9 +7,7 @@ namespace REGoth { - namespace World - { - bs::HSceneObject loadCachedZEN(const bs::String& zenFile) + bs::HSceneObject ZenCache::loadCachedZEN(const bs::String& zenFile) { if (!hasCachedZEN(zenFile)) { @@ -23,23 +21,23 @@ namespace REGoth return prefab->instantiate(); } - void saveCacheForZEN(bs::HSceneObject root, const bs::String& zenFile) + void ZenCache::saveCacheForZEN(bs::HSceneObject root, const bs::String& zenFile) { bs::HPrefab cached = bs::Prefab::create(root); enum { - Overwrite = true, - KeepExisting = false, + overwrite = true, + keepExisting = false, }; bs::Path path = BsZenLib::GothicPathToCachedWorld(zenFile); - bs::gResources().save(cached, path, Overwrite); + bs::gResources().save(cached, path, overwrite); } - bool hasCachedZEN(const bs::String& zenFile) + bool ZenCache::hasCachedZEN(const bs::String& zenFile) { return bs::FileSystem::exists(BsZenLib::GothicPathToCachedWorld(zenFile)); } - } // namespace World + } // namespace REGoth diff --git a/src/world/internals/LoadCachedZEN.hpp b/src/world/internals/ZenCache.hpp similarity index 97% rename from src/world/internals/LoadCachedZEN.hpp rename to src/world/internals/ZenCache.hpp index 053b2a17..249657a1 100644 --- a/src/world/internals/LoadCachedZEN.hpp +++ b/src/world/internals/ZenCache.hpp @@ -3,8 +3,9 @@ namespace REGoth { - namespace World + class ZenCache { + public: /** * Loads the cached ZEN with the given name. * @@ -46,5 +47,6 @@ namespace REGoth * @See loadCachedZEN() to load it. */ bool hasCachedZEN(const bs::String& zenFile); - } + }; + } // namespace REGoth From 2e124123e9ce28fbecfde0de597e082b46db606a Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Sun, 8 Mar 2020 17:26:35 +0100 Subject: [PATCH 2/6] Make VobImporter a class --- src/CMakeLists.txt | 4 ++-- src/world/internals/ConstructFromZEN.cpp | 4 ++-- .../internals/{ImportSingleVob.cpp => VobImporter.cpp} | 4 ++-- .../internals/{ImportSingleVob.hpp => VobImporter.hpp} | 8 +++++--- 4 files changed, 11 insertions(+), 9 deletions(-) rename src/world/internals/{ImportSingleVob.cpp => VobImporter.cpp} (99%) rename src/world/internals/{ImportSingleVob.hpp => VobImporter.hpp} (81%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7d1b37b9..0f2fcaa6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -174,8 +174,8 @@ add_library(REGothEngine STATIC scripting/daedalus/REGothDaedalusVM.hpp world/internals/ConstructFromZEN.cpp world/internals/ConstructFromZEN.hpp - world/internals/ImportSingleVob.cpp - world/internals/ImportSingleVob.hpp + world/internals/VobImporter.cpp + world/internals/VobImporter.hpp world/internals/ZenCache.cpp world/internals/ZenCache.hpp ) diff --git a/src/world/internals/ConstructFromZEN.cpp b/src/world/internals/ConstructFromZEN.cpp index 84a253a9..1b18266d 100644 --- a/src/world/internals/ConstructFromZEN.cpp +++ b/src/world/internals/ConstructFromZEN.cpp @@ -1,5 +1,5 @@ #include "ConstructFromZEN.hpp" -#include "ImportSingleVob.hpp" +#include "VobImporter.hpp" #include #include #include @@ -84,7 +84,7 @@ namespace REGoth { for (const auto& v : zenParent.childVobs) { - bs::HSceneObject so = Internals::importSingleVob(v, bsfParent, gameWorld); + bs::HSceneObject so = VobImporter::importSingleVob(v, bsfParent, gameWorld); if (so) { diff --git a/src/world/internals/ImportSingleVob.cpp b/src/world/internals/VobImporter.cpp similarity index 99% rename from src/world/internals/ImportSingleVob.cpp rename to src/world/internals/VobImporter.cpp index f270f507..a0239d90 100644 --- a/src/world/internals/ImportSingleVob.cpp +++ b/src/world/internals/VobImporter.cpp @@ -1,4 +1,4 @@ -#include "ImportSingleVob.hpp" +#include "VobImporter.hpp" #include #include #include @@ -55,7 +55,7 @@ namespace REGoth static void addCollisionTo(bs::HSceneObject sceneObject); static bs::Transform transformFromVob(const ZenLoad::zCVobData& vob); - bs::HSceneObject Internals::importSingleVob(const ZenLoad::zCVobData& vob, + bs::HSceneObject VobImporter::importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { if (vob.objectClass == "zCVob") diff --git a/src/world/internals/ImportSingleVob.hpp b/src/world/internals/VobImporter.hpp similarity index 81% rename from src/world/internals/ImportSingleVob.hpp rename to src/world/internals/VobImporter.hpp index 2ebf045b..d48d2fbc 100644 --- a/src/world/internals/ImportSingleVob.hpp +++ b/src/world/internals/VobImporter.hpp @@ -15,8 +15,9 @@ namespace REGoth class GameWorld; using HGameWorld = bs::GameObjectHandle; - namespace Internals + class VobImporter { + public: /** * Imports a single vob and creates a bs:f object as similar as possible. * @@ -26,7 +27,8 @@ namespace REGoth * * @return Scene object modeled after the vob */ - bs::HSceneObject importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + static bs::HSceneObject importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld); - } // namespace Worlds + }; + } // namespace REGoth From 735bec968fa8b252245397cb9b3c173b6bbff28b Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Sun, 8 Mar 2020 17:31:28 +0100 Subject: [PATCH 3/6] Make ZenImporter a class --- src/CMakeLists.txt | 4 ++-- src/components/GameWorld.cpp | 4 ++-- .../{ConstructFromZEN.cpp => ZenImporter.cpp} | 4 ++-- .../{ConstructFromZEN.hpp => ZenImporter.hpp} | 10 ++++++---- 4 files changed, 12 insertions(+), 10 deletions(-) rename src/world/internals/{ConstructFromZEN.cpp => ZenImporter.cpp} (98%) rename src/world/internals/{ConstructFromZEN.hpp => ZenImporter.hpp} (77%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f2fcaa6..8e0d662b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -172,8 +172,8 @@ add_library(REGothEngine STATIC scripting/daedalus/DaedalusVMForGameWorld.hpp scripting/daedalus/REGothDaedalusVM.cpp scripting/daedalus/REGothDaedalusVM.hpp - world/internals/ConstructFromZEN.cpp - world/internals/ConstructFromZEN.hpp + world/internals/ZenImporter.cpp + world/internals/ZenImporter.hpp world/internals/VobImporter.cpp world/internals/VobImporter.hpp world/internals/ZenCache.cpp diff --git a/src/components/GameWorld.cpp b/src/components/GameWorld.cpp index 00c1908d..397a3931 100644 --- a/src/components/GameWorld.cpp +++ b/src/components/GameWorld.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include namespace REGoth { @@ -67,7 +67,7 @@ namespace REGoth if (!mZenFile.empty()) { // Import the ZEN and add all scene objects as children to this SO. - bs::HSceneObject so = Internals::constructFromZEN(thisWorld, mZenFile); + bs::HSceneObject so = ZenImporter::constructFromZEN(thisWorld, mZenFile); if (!so) { diff --git a/src/world/internals/ConstructFromZEN.cpp b/src/world/internals/ZenImporter.cpp similarity index 98% rename from src/world/internals/ConstructFromZEN.cpp rename to src/world/internals/ZenImporter.cpp index 1b18266d..4091a6e8 100644 --- a/src/world/internals/ConstructFromZEN.cpp +++ b/src/world/internals/ZenImporter.cpp @@ -1,4 +1,4 @@ -#include "ConstructFromZEN.hpp" +#include "ZenImporter.hpp" #include "VobImporter.hpp" #include #include @@ -35,7 +35,7 @@ namespace REGoth static void walkVobTree(bs::HSceneObject bsfParent, HGameWorld gameWorld, const ZenLoad::zCVobData& zenParent); - bs::HSceneObject Internals::constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile) + bs::HSceneObject ZenImporter::constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile) { OriginalZen zen; diff --git a/src/world/internals/ConstructFromZEN.hpp b/src/world/internals/ZenImporter.hpp similarity index 77% rename from src/world/internals/ConstructFromZEN.hpp rename to src/world/internals/ZenImporter.hpp index 89a7c178..44f22c49 100644 --- a/src/world/internals/ConstructFromZEN.hpp +++ b/src/world/internals/ZenImporter.hpp @@ -10,8 +10,9 @@ namespace REGoth class GameWorld; using HGameWorld = bs::GameObjectHandle; - namespace Internals + class ZenImporter { + public: /** * This function will load the given zenFile from the virtual file system * and fully convert it into a bs::f scene. @@ -21,7 +22,7 @@ namespace REGoth * * @return Root of the created scene. */ - bs::HSceneObject constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile); + static bs::HSceneObject constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile); /** * Will load the given ZEN, but only add its world mesh to the scene. @@ -30,6 +31,7 @@ namespace REGoth * * @return Root of the created scene. */ - bs::HSceneObject loadWorldMeshFromZEN(const bs::String& zenFile); - } // namespace Internals + static bs::HSceneObject loadWorldMeshFromZEN(const bs::String& zenFile); + }; + } // namespace REGoth From 1845a0ce04c8deffb26ea32aa574f13c31f37310 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Sun, 8 Mar 2020 18:05:18 +0100 Subject: [PATCH 4/6] Convert all functions to methods --- src/components/GameWorld.cpp | 3 +- src/components/GameWorld.hpp | 3 ++ src/main_WorldMeshViewer.cpp | 5 +- src/world/internals/VobImporter.cpp | 74 +++++++++-------------------- src/world/internals/VobImporter.hpp | 36 +++++++++++++- src/world/internals/ZenCache.hpp | 4 ++ src/world/internals/ZenImporter.cpp | 30 ++++-------- src/world/internals/ZenImporter.hpp | 25 +++++++++- 8 files changed, 99 insertions(+), 81 deletions(-) diff --git a/src/components/GameWorld.cpp b/src/components/GameWorld.cpp index 397a3931..95846cdd 100644 --- a/src/components/GameWorld.cpp +++ b/src/components/GameWorld.cpp @@ -21,7 +21,6 @@ #include #include #include -#include namespace REGoth { @@ -67,7 +66,7 @@ namespace REGoth if (!mZenFile.empty()) { // Import the ZEN and add all scene objects as children to this SO. - bs::HSceneObject so = ZenImporter::constructFromZEN(thisWorld, mZenFile); + bs::HSceneObject so = mZenImporter.constructFromZEN(thisWorld, mZenFile); if (!so) { diff --git a/src/components/GameWorld.hpp b/src/components/GameWorld.hpp index 6d76870d..7ae50a7d 100644 --- a/src/components/GameWorld.hpp +++ b/src/components/GameWorld.hpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -376,6 +377,8 @@ namespace REGoth void findAllItems(); void findAllFocusables(); + ZenImporter mZenImporter; + /** * ZEN-File this world was created from, e.g. `NEWWORLD.ZEN`. */ diff --git a/src/main_WorldMeshViewer.cpp b/src/main_WorldMeshViewer.cpp index 84e2add1..18670834 100644 --- a/src/main_WorldMeshViewer.cpp +++ b/src/main_WorldMeshViewer.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include class REGothWorldMeshViewer : public REGoth::EmptyGame { @@ -21,11 +21,12 @@ class REGothWorldMeshViewer : public REGoth::EmptyGame void setupScene() override { - REGoth::Internals::loadWorldMeshFromZEN("ADDONWORLD.ZEN"); + mZenImporter.loadWorldMeshFromZEN("ADDONWORLD.ZEN"); } protected: bs::HFPSCamera mFPSCamera; + REGoth::ZenImporter mZenImporter; }; int main(int argc, char** argv) diff --git a/src/world/internals/VobImporter.cpp b/src/world/internals/VobImporter.cpp index a0239d90..3e93bf2b 100644 --- a/src/world/internals/VobImporter.cpp +++ b/src/world/internals/VobImporter.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -14,46 +13,9 @@ #include #include #include -#include - -namespace -{ - static bs::Matrix4 convertMatrix(const ZMath::Matrix& m) - { - bs::Matrix4 bs = {m.mv[0], m.mv[1], m.mv[2], m.mv[3], m.mv[4], m.mv[5], m.mv[6], m.mv[7], - m.mv[8], m.mv[9], m.mv[10], m.mv[11], m.mv[12], m.mv[13], m.mv[14], m.mv[15]}; - - return bs.transpose(); - } -} // namespace namespace REGoth { - static bs::HSceneObject import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - static bs::HSceneObject import_zCVobLight(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - static bs::HSceneObject import_zCVobStartpoint(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - static bs::HSceneObject import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - static bs::HSceneObject import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - static bs::HSceneObject import_zCVobSound(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - static bs::HSceneObject import_zCVobAnimate(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - static bs::HSceneObject import_oCMobInter(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - static bs::HSceneObject import_oCMobContainer(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - static bs::HSceneObject import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - static bs::HSceneObject import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - static void addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName); - static void addCollisionTo(bs::HSceneObject sceneObject); - static bs::Transform transformFromVob(const ZenLoad::zCVobData& vob); bs::HSceneObject VobImporter::importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) @@ -111,7 +73,7 @@ namespace REGoth } } - static bs::Transform transformFromVob(const ZenLoad::zCVobData& vob) + bs::Transform VobImporter::transformFromVob(const ZenLoad::zCVobData& vob) { bs::Transform result = bs::Transform::IDENTITY; @@ -136,7 +98,7 @@ namespace REGoth * * @note Not all object types will call `import_zCVob`! */ - static bs::HSceneObject import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + bs::HSceneObject VobImporter::import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = bs::SceneObject::create(vob.vobName.c_str()); @@ -166,7 +128,7 @@ namespace REGoth * Lights can be pointlights or spotlights, although spotlights are not * used within the original game as it seems. */ - static bs::HSceneObject import_zCVobLight(const ZenLoad::zCVobData& vob, + bs::HSceneObject VobImporter::import_zCVobLight(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -190,7 +152,7 @@ namespace REGoth /** * The startpoint of the player in the current world. There should be only one. */ - static bs::HSceneObject import_zCVobStartpoint(const ZenLoad::zCVobData& vob, + bs::HSceneObject VobImporter::import_zCVobStartpoint(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -209,7 +171,7 @@ namespace REGoth /** * Spots like free-points. */ - static bs::HSceneObject import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + bs::HSceneObject VobImporter::import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -219,7 +181,7 @@ namespace REGoth return so; } - static bs::HSceneObject import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + bs::HSceneObject VobImporter::import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { if (vob.oCItem.instanceName.empty()) @@ -239,7 +201,7 @@ namespace REGoth return item->SO(); } - static bs::HSceneObject import_zCVobSound(const ZenLoad::zCVobData& vob, + bs::HSceneObject VobImporter::import_zCVobSound(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -249,7 +211,7 @@ namespace REGoth return so; } - static bs::HSceneObject import_zCVobAnimate(const ZenLoad::zCVobData& vob, + bs::HSceneObject VobImporter::import_zCVobAnimate(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -259,7 +221,7 @@ namespace REGoth return so; } - static bs::HSceneObject import_oCMobInter(const ZenLoad::zCVobData& vob, + bs::HSceneObject VobImporter::import_oCMobInter(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -269,7 +231,7 @@ namespace REGoth return so; } - static bs::HSceneObject import_oCMobContainer(const ZenLoad::zCVobData& vob, + bs::HSceneObject VobImporter::import_oCMobContainer(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -279,7 +241,7 @@ namespace REGoth return so; } - static bs::HSceneObject import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + bs::HSceneObject VobImporter::import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -289,7 +251,7 @@ namespace REGoth return so; } - static bs::HSceneObject import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + bs::HSceneObject VobImporter::import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); @@ -303,7 +265,7 @@ namespace REGoth * Adds the given visual to the scene object. If that's not possible * nothing will be added. */ - static void addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName) + void VobImporter::addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName) { bool hasAdded = Visual::addToSceneObject(sceneObject, visualName); @@ -318,7 +280,7 @@ namespace REGoth * scene object has a renderable with a mesh set. The mesh must also have * CPU-caching enabled, so we get access to the mesh data. */ - static void addCollisionTo(bs::HSceneObject sceneObject) + void VobImporter::addCollisionTo(bs::HSceneObject sceneObject) { bs::HRenderable renderable = sceneObject->getComponent(); @@ -356,4 +318,12 @@ namespace REGoth collider->setMesh(physicsMesh); } + bs::Matrix4 VobImporter::convertMatrix(const ZMath::Matrix& m) + { + bs::Matrix4 bs = {m.mv[0], m.mv[1], m.mv[2], m.mv[3], m.mv[4], m.mv[5], m.mv[6], m.mv[7], + m.mv[8], m.mv[9], m.mv[10], m.mv[11], m.mv[12], m.mv[13], m.mv[14], m.mv[15]}; + + return bs.transpose(); + } + } // namespace REGoth diff --git a/src/world/internals/VobImporter.hpp b/src/world/internals/VobImporter.hpp index d48d2fbc..451e0ba5 100644 --- a/src/world/internals/VobImporter.hpp +++ b/src/world/internals/VobImporter.hpp @@ -4,6 +4,8 @@ #pragma once #include +#include +#include namespace ZenLoad { @@ -18,6 +20,9 @@ namespace REGoth class VobImporter { public: + VobImporter() = default; + ~VobImporter() = default; + /** * Imports a single vob and creates a bs:f object as similar as possible. * @@ -27,8 +32,37 @@ namespace REGoth * * @return Scene object modeled after the vob */ - static bs::HSceneObject importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + bs::HSceneObject importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld); + + private: + bs::Matrix4 convertMatrix(const ZMath::Matrix& m); + bs::HSceneObject import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_zCVobLight(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_zCVobStartpoint(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_zCVobSound(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_zCVobAnimate(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_oCMobInter(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_oCMobContainer(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + void addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName); + void addCollisionTo(bs::HSceneObject sceneObject); + bs::Transform transformFromVob(const ZenLoad::zCVobData& vob); + }; } // namespace REGoth diff --git a/src/world/internals/ZenCache.hpp b/src/world/internals/ZenCache.hpp index 249657a1..1dafe2b2 100644 --- a/src/world/internals/ZenCache.hpp +++ b/src/world/internals/ZenCache.hpp @@ -3,9 +3,13 @@ namespace REGoth { + class ZenCache { public: + ZenCache() = default; + ~ZenCache() = default; + /** * Loads the cached ZEN with the given name. * diff --git a/src/world/internals/ZenImporter.cpp b/src/world/internals/ZenImporter.cpp index 4091a6e8..8bc17d04 100644 --- a/src/world/internals/ZenImporter.cpp +++ b/src/world/internals/ZenImporter.cpp @@ -1,5 +1,4 @@ #include "ZenImporter.hpp" -#include "VobImporter.hpp" #include #include #include @@ -21,20 +20,7 @@ namespace REGoth { - struct OriginalZen - { - bs::String fileName; - ZenLoad::oCWorldData vobTree; - ZenLoad::PackedMesh worldMesh; - }; - - static bool importZEN(const bs::String& zenFile, OriginalZen& result); - static bs::HSceneObject importWorldMesh(const OriginalZen& zen); - static void importVobs(bs::HSceneObject sceneRoot, HGameWorld gameWorld, const OriginalZen& zen); - static void importWaynet(bs::HSceneObject sceneRoot, const OriginalZen& zen); - static void walkVobTree(bs::HSceneObject bsfParent, HGameWorld gameWorld, - const ZenLoad::zCVobData& zenParent); - + bs::HSceneObject ZenImporter::constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile) { OriginalZen zen; @@ -56,7 +42,7 @@ namespace REGoth return worldMesh; } - bs::HSceneObject Internals::loadWorldMeshFromZEN(const bs::String& zenFile) + bs::HSceneObject ZenImporter::loadWorldMeshFromZEN(const bs::String& zenFile) { OriginalZen zen; @@ -71,7 +57,7 @@ namespace REGoth return importWorldMesh(zen); } - static void importVobs(bs::HSceneObject sceneRoot, HGameWorld gameWorld, const OriginalZen& zen) + void ZenImporter::importVobs(bs::HSceneObject sceneRoot, HGameWorld gameWorld, const OriginalZen& zen) { for (const ZenLoad::zCVobData& root : zen.vobTree.rootVobs) { @@ -79,12 +65,12 @@ namespace REGoth } } - static void walkVobTree(bs::HSceneObject bsfParent, HGameWorld gameWorld, + void ZenImporter::walkVobTree(bs::HSceneObject bsfParent, HGameWorld gameWorld, const ZenLoad::zCVobData& zenParent) { for (const auto& v : zenParent.childVobs) { - bs::HSceneObject so = VobImporter::importSingleVob(v, bsfParent, gameWorld); + bs::HSceneObject so = mVobImporter.importSingleVob(v, bsfParent, gameWorld); if (so) { @@ -96,7 +82,7 @@ namespace REGoth /** * Import a zenfile and load it into datastructures to work with */ - static bool importZEN(const bs::String& zenFile, OriginalZen& result) + bool ZenImporter::importZEN(const bs::String& zenFile, OriginalZen& result) { ZenLoad::ZenParser zenParser(zenFile.c_str(), gVirtualFileSystem().getFileIndex()); @@ -117,7 +103,7 @@ namespace REGoth /** * Create a bs:f scene object holding the world mesh. */ - static bs::HSceneObject importWorldMesh(const OriginalZen& zen) + bs::HSceneObject ZenImporter::importWorldMesh(const OriginalZen& zen) { bs::String meshFileName = zen.fileName + ".worldmesh"; @@ -175,7 +161,7 @@ namespace REGoth return meshSO; } - static void importWaynet(bs::HSceneObject sceneRoot, const OriginalZen& zen) + void ZenImporter::importWaynet(bs::HSceneObject sceneRoot, const OriginalZen& zen) { const ZenLoad::zCWayNetData& zenWaynet = zen.vobTree.waynet; diff --git a/src/world/internals/ZenImporter.hpp b/src/world/internals/ZenImporter.hpp index 44f22c49..b8763c5d 100644 --- a/src/world/internals/ZenImporter.hpp +++ b/src/world/internals/ZenImporter.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include "VobImporter.hpp" namespace REGoth { @@ -13,6 +14,9 @@ namespace REGoth class ZenImporter { public: + ZenImporter() = default; + ~ZenImporter() = default; + /** * This function will load the given zenFile from the virtual file system * and fully convert it into a bs::f scene. @@ -22,7 +26,7 @@ namespace REGoth * * @return Root of the created scene. */ - static bs::HSceneObject constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile); + bs::HSceneObject constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile); /** * Will load the given ZEN, but only add its world mesh to the scene. @@ -31,7 +35,24 @@ namespace REGoth * * @return Root of the created scene. */ - static bs::HSceneObject loadWorldMeshFromZEN(const bs::String& zenFile); + bs::HSceneObject loadWorldMeshFromZEN(const bs::String& zenFile); + + private: + VobImporter mVobImporter; + + struct OriginalZen + { + bs::String fileName; + ZenLoad::oCWorldData vobTree; + ZenLoad::PackedMesh worldMesh; + }; + + bool importZEN(const bs::String& zenFile, OriginalZen& result); + bs::HSceneObject importWorldMesh(const OriginalZen& zen); + void importVobs(bs::HSceneObject sceneRoot, HGameWorld gameWorld, const OriginalZen& zen); + void importWaynet(bs::HSceneObject sceneRoot, const OriginalZen& zen); + void walkVobTree(bs::HSceneObject bsfParent, HGameWorld gameWorld, + const ZenLoad::zCVobData& zenParent); }; } // namespace REGoth From 1c00e4cc8b75b727362c11dac9c7d6460ffb2736 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Sun, 8 Mar 2020 19:01:53 +0100 Subject: [PATCH 5/6] Initial Importer rework --- src/components/GameWorld.cpp | 3 +-- src/components/GameWorld.hpp | 7 +++++-- src/core/Gothic1Game.cpp | 2 +- src/core/Gothic2Game.cpp | 2 +- src/main_WorldViewer.cpp | 2 +- src/world/internals/VobImporter.cpp | 6 ++---- src/world/internals/VobImporter.hpp | 10 +++++++++- src/world/internals/ZenImporter.hpp | 5 +++++ 8 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/components/GameWorld.cpp b/src/components/GameWorld.cpp index 95846cdd..1c9071cd 100644 --- a/src/components/GameWorld.cpp +++ b/src/components/GameWorld.cpp @@ -24,8 +24,6 @@ namespace REGoth { - const char* const WORLD_STARTPOINT = "STARTPOINT"; - GameWorld::GameWorld(const bs::HSceneObject& parent, const bs::String& zenFile) : bs::Component(parent) , mZenFile(zenFile) @@ -172,6 +170,7 @@ namespace REGoth return character; } + //FIXME: deprecate String as spawnpoint, use Startpoint or Waypoint directly HCharacter GameWorld::insertCharacter(const bs::String& instance, const bs::String& spawnPoint) { bs::HSceneObject spawnPointSO = findObjectByName(spawnPoint); diff --git a/src/components/GameWorld.hpp b/src/components/GameWorld.hpp index 7ae50a7d..265af0c5 100644 --- a/src/components/GameWorld.hpp +++ b/src/components/GameWorld.hpp @@ -29,8 +29,6 @@ namespace REGoth class Waypoint; using HWaypoint = bs::GameObjectHandle; - extern const char* const WORLD_STARTPOINT; - namespace Scripting { class ScriptVMForGameWorld; @@ -141,6 +139,11 @@ namespace REGoth return mWaynet; } + bs::HSceneObject getWorldStartPoint() + { + return mZenImporter.getWorldStartPoint(); + } + /** * @return Handle to the GameClock of the world. */ diff --git a/src/core/Gothic1Game.cpp b/src/core/Gothic1Game.cpp index 2ab6abcd..9d5b1e67 100644 --- a/src/core/Gothic1Game.cpp +++ b/src/core/Gothic1Game.cpp @@ -31,7 +31,7 @@ void Gothic1Game::setupScene() { world = GameWorld::importZEN(WORLD); - HCharacter hero = world->insertCharacter("PC_HERO", WORLD_STARTPOINT); + HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartPoint()->getName()); hero->useAsHero(); hero->SO()->addComponent(world); diff --git a/src/core/Gothic2Game.cpp b/src/core/Gothic2Game.cpp index a436cff7..7983e894 100644 --- a/src/core/Gothic2Game.cpp +++ b/src/core/Gothic2Game.cpp @@ -30,7 +30,7 @@ void Gothic2Game::setupScene() { world = GameWorld::importZEN(WORLD); - HCharacter hero = world->insertCharacter("PC_HERO", WORLD_STARTPOINT); + HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartPoint()->getName()); hero->useAsHero(); hero->SO()->addComponent(world); diff --git a/src/main_WorldViewer.cpp b/src/main_WorldViewer.cpp index 8d3e1716..a7372831 100644 --- a/src/main_WorldViewer.cpp +++ b/src/main_WorldViewer.cpp @@ -100,7 +100,7 @@ class REGothWorldViewer : public REGoth::Engine { world = GameWorld::importZEN(config()->world); - HCharacter hero = world->insertCharacter("PC_HERO", WORLD_STARTPOINT); + HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartPoint()->getName()); hero->useAsHero(); hero->SO()->addComponent(world); diff --git a/src/world/internals/VobImporter.cpp b/src/world/internals/VobImporter.cpp index 3e93bf2b..b4d3ace5 100644 --- a/src/world/internals/VobImporter.cpp +++ b/src/world/internals/VobImporter.cpp @@ -155,15 +155,13 @@ namespace REGoth bs::HSceneObject VobImporter::import_zCVobStartpoint(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld) { + //FIXME: Rotate by 180Degrees bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); // Startpoint is found by name of the scene object REGOTH_LOG(Info, Uncategorized, "[ImportSingleVob] Found startpoint: {0}", so->getName()); - // A startpoint has an arbitrary names, which makes it hard to find it at a later point. - // Thus, rename it to a known constant. As there should always only be one startpoint in - // a world, this should cause no conflicts. - so->setName(WORLD_STARTPOINT); + mStartpoint = so; return so; } diff --git a/src/world/internals/VobImporter.hpp b/src/world/internals/VobImporter.hpp index 451e0ba5..825107b3 100644 --- a/src/world/internals/VobImporter.hpp +++ b/src/world/internals/VobImporter.hpp @@ -34,8 +34,16 @@ namespace REGoth */ bs::HSceneObject importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld); - + + //FIXME: Come up with a better way, possibly by reworking the importer into one, so there only need to be 2 getters instead of 3 + bs::HSceneObject getWorldStartPoint() + { + return mStartpoint; + } + private: + bs::HSceneObject mStartpoint; + bs::Matrix4 convertMatrix(const ZMath::Matrix& m); bs::HSceneObject import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, HGameWorld gameWorld); diff --git a/src/world/internals/ZenImporter.hpp b/src/world/internals/ZenImporter.hpp index b8763c5d..e43fa37f 100644 --- a/src/world/internals/ZenImporter.hpp +++ b/src/world/internals/ZenImporter.hpp @@ -37,6 +37,11 @@ namespace REGoth */ bs::HSceneObject loadWorldMeshFromZEN(const bs::String& zenFile); + bs::HSceneObject getWorldStartPoint() + { + return mVobImporter.getWorldStartPoint(); + } + private: VobImporter mVobImporter; From d3842c40ff89eeb5708f00d1d701d9d20a1bb009 Mon Sep 17 00:00:00 2001 From: KirmesBude Date: Sun, 8 Mar 2020 22:38:25 +0100 Subject: [PATCH 6/6] Improved the Importer? --- src/CMakeLists.txt | 2 - src/components/GameWorld.cpp | 1 - src/components/GameWorld.hpp | 7 +- src/core/Gothic1Game.cpp | 2 +- src/core/Gothic2Game.cpp | 2 +- src/main_WorldViewer.cpp | 2 +- src/world/internals/VobImporter.cpp | 327 --------------------------- src/world/internals/VobImporter.hpp | 76 ------- src/world/internals/ZenImporter.cpp | 333 +++++++++++++++++++++++++++- src/world/internals/ZenImporter.hpp | 63 +++++- 10 files changed, 396 insertions(+), 419 deletions(-) delete mode 100644 src/world/internals/VobImporter.cpp delete mode 100644 src/world/internals/VobImporter.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e0d662b..aabcadfe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -174,8 +174,6 @@ add_library(REGothEngine STATIC scripting/daedalus/REGothDaedalusVM.hpp world/internals/ZenImporter.cpp world/internals/ZenImporter.hpp - world/internals/VobImporter.cpp - world/internals/VobImporter.hpp world/internals/ZenCache.cpp world/internals/ZenCache.hpp ) diff --git a/src/components/GameWorld.cpp b/src/components/GameWorld.cpp index 1c9071cd..0ad08e6a 100644 --- a/src/components/GameWorld.cpp +++ b/src/components/GameWorld.cpp @@ -170,7 +170,6 @@ namespace REGoth return character; } - //FIXME: deprecate String as spawnpoint, use Startpoint or Waypoint directly HCharacter GameWorld::insertCharacter(const bs::String& instance, const bs::String& spawnPoint) { bs::HSceneObject spawnPointSO = findObjectByName(spawnPoint); diff --git a/src/components/GameWorld.hpp b/src/components/GameWorld.hpp index 265af0c5..a56daf63 100644 --- a/src/components/GameWorld.hpp +++ b/src/components/GameWorld.hpp @@ -139,9 +139,9 @@ namespace REGoth return mWaynet; } - bs::HSceneObject getWorldStartPoint() + bs::HSceneObject getWorldStartpoint() { - return mZenImporter.getWorldStartPoint(); + return mZenImporter.getStartpoint(); } /** @@ -380,6 +380,9 @@ namespace REGoth void findAllItems(); void findAllFocusables(); + /** + * ZEN-File Importer. + */ ZenImporter mZenImporter; /** diff --git a/src/core/Gothic1Game.cpp b/src/core/Gothic1Game.cpp index 9d5b1e67..628b3bbf 100644 --- a/src/core/Gothic1Game.cpp +++ b/src/core/Gothic1Game.cpp @@ -31,7 +31,7 @@ void Gothic1Game::setupScene() { world = GameWorld::importZEN(WORLD); - HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartPoint()->getName()); + HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartpoint()->getName()); hero->useAsHero(); hero->SO()->addComponent(world); diff --git a/src/core/Gothic2Game.cpp b/src/core/Gothic2Game.cpp index 7983e894..fc068b84 100644 --- a/src/core/Gothic2Game.cpp +++ b/src/core/Gothic2Game.cpp @@ -30,7 +30,7 @@ void Gothic2Game::setupScene() { world = GameWorld::importZEN(WORLD); - HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartPoint()->getName()); + HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartpoint()->getName()); hero->useAsHero(); hero->SO()->addComponent(world); diff --git a/src/main_WorldViewer.cpp b/src/main_WorldViewer.cpp index a7372831..02641297 100644 --- a/src/main_WorldViewer.cpp +++ b/src/main_WorldViewer.cpp @@ -100,7 +100,7 @@ class REGothWorldViewer : public REGoth::Engine { world = GameWorld::importZEN(config()->world); - HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartPoint()->getName()); + HCharacter hero = world->insertCharacter("PC_HERO", world->getWorldStartpoint()->getName()); hero->useAsHero(); hero->SO()->addComponent(world); diff --git a/src/world/internals/VobImporter.cpp b/src/world/internals/VobImporter.cpp deleted file mode 100644 index b4d3ace5..00000000 --- a/src/world/internals/VobImporter.cpp +++ /dev/null @@ -1,327 +0,0 @@ -#include "VobImporter.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace REGoth -{ - - bs::HSceneObject VobImporter::importSingleVob(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld) - { - if (vob.objectClass == "zCVob") - { - return import_zCVob(vob, bsfParent, gameWorld); - } - else if (vob.objectClass == "zCVobLight:zCVob") - { - return import_zCVobLight(vob, bsfParent, gameWorld); - } - else if (vob.objectClass == "zCVobStartpoint:zCVob") - { - return import_zCVobStartpoint(vob, bsfParent, gameWorld); - } - else if (vob.objectClass == "zCVobSpot:zCVob") - { - return import_zCVobSpot(vob, bsfParent, gameWorld); - } - else if (vob.objectClass == "zCVobSound:zCVob") - { - return import_zCVobSound(vob, bsfParent, gameWorld); - } - else if (vob.objectClass == "oCItem:zCVob") - { - return import_oCItem(vob, bsfParent, gameWorld); - } - else if (vob.objectClass == "zCVobAnimate:zCVob") - { - return import_zCVobAnimate(vob, bsfParent, gameWorld); - } - // else if (vob.objectClass == "oCMobInter:oCMOB:zCVob") - // { - // return import_oCMobInter(vob, bsfParent, gameWorld); - // } - // else if (vob.objectClass == "oCMobContainer:oCMobInter:oCMOB:zCVob") - // { - // return import_oCMobContainer(vob, bsfParent, gameWorld); - // } - // else if (vob.objectClass == "oCMobBed:oCMobInter:oCMOB:zCVob") - // { - // return import_oCMobBed(vob, bsfParent, gameWorld); - // } - // else if (vob.objectClass == "oCMobDoor:oCMobInter:oCMOB:zCVob") - // { - // return import_oCMobDoor(vob, bsfParent, gameWorld); - // } - else - { - REGOTH_LOG(Warning, Uncategorized, "[ImportSingleVob] Unsupported vob class: {0}", - bs::String(vob.objectClass.c_str())); - - return {}; - } - } - - bs::Transform VobImporter::transformFromVob(const ZenLoad::zCVobData& vob) - { - bs::Transform result = bs::Transform::IDENTITY; - - bs::Matrix4 worldMatrix = convertMatrix(vob.worldMatrix); - bs::Quaternion rotation; - rotation.fromRotationMatrix(worldMatrix.get3x3()); - - bs::Vector3 positionCM = bs::Vector3(vob.position.x, vob.position.y, vob.position.z); - - float centimetersToMeters = 0.01f; - - result.setPosition(positionCM * centimetersToMeters); - result.setRotation(rotation); - - return result; - } - - /** - * The zCVob is the most basic object class we will encounter. It is - * the base class of most other objects, so it makes sense to handle - * position, rotation and the visual here as these are used by most vobs. - * - * @note Not all object types will call `import_zCVob`! - */ - bs::HSceneObject VobImporter::import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld) - { - bs::HSceneObject so = bs::SceneObject::create(vob.vobName.c_str()); - - so->setParent(gameWorld->SO()); - - bs::Transform transform = transformFromVob(vob); - - so->setPosition(transform.pos()); - so->setRotation(transform.rot()); - - if (!vob.visual.empty()) - { - addVisualTo(so, vob.visual.c_str()); - } - - // cdDyn seems to be the general "this is supposed to collide with stuff"-flag. - if (vob.cdDyn) - { - addCollisionTo(so); - } - - return so; - } - - /** - * Lights can be pointlights or spotlights, although spotlights are not - * used within the original game as it seems. - */ - bs::HSceneObject VobImporter::import_zCVobLight(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // FIXME: Put lights back in - return so; -#if 0 - bs::HLight light = so->addComponent(); - - auto lightColor = bs::Color::fromRGBA(vob.zCVobLight.color); - - light->setType(bs::LightType::Radial); - light->setUseAutoAttenuation(false); - light->setAttenuationRadius(vob.zCVobLight.range); - light->setColor(lightColor); - - return so; -#endif - } - - /** - * The startpoint of the player in the current world. There should be only one. - */ - bs::HSceneObject VobImporter::import_zCVobStartpoint(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld) - { - //FIXME: Rotate by 180Degrees - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // Startpoint is found by name of the scene object - REGOTH_LOG(Info, Uncategorized, "[ImportSingleVob] Found startpoint: {0}", so->getName()); - - mStartpoint = so; - - return so; - } - - /** - * Spots like free-points. - */ - bs::HSceneObject VobImporter::import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - so->addComponent(); - - return so; - } - - bs::HSceneObject VobImporter::import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld) - { - if (vob.oCItem.instanceName.empty()) - { - REGOTH_LOG(Warning, Uncategorized, "[ImportSingleVob] Item with empty script instance: {0}", - bs::String(vob.vobName.c_str())); - return {}; - } - - bs::Transform transform = transformFromVob(vob); - - // Items are interactable, they need to be registered within the GameWorld - HItem item = gameWorld->insertItem(vob.oCItem.instanceName.c_str(), transform); - - item->SO()->setParent(bsfParent); - - return item->SO(); - } - - bs::HSceneObject VobImporter::import_zCVobSound(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // TODO: Implement - - return so; - } - - bs::HSceneObject VobImporter::import_zCVobAnimate(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // TODO: Implement - - return so; - } - - bs::HSceneObject VobImporter::import_oCMobInter(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // TODO: Implement - - return so; - } - - bs::HSceneObject VobImporter::import_oCMobContainer(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // TODO: Implement - - return so; - } - - bs::HSceneObject VobImporter::import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // TODO: Implement - - return so; - } - - bs::HSceneObject VobImporter::import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld) - { - bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); - - // TODO: Implement - - return so; - } - - /** - * Adds the given visual to the scene object. If that's not possible - * nothing will be added. - */ - void VobImporter::addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName) - { - bool hasAdded = Visual::addToSceneObject(sceneObject, visualName); - - if (!hasAdded) - { - REGOTH_LOG(Warning, Uncategorized, "[ImportSingleVob] Unsupported visual: {0}", visualName); - } - } - - /** - * Adds a triangle physics mesh to the given scene object. Only works if the - * scene object has a renderable with a mesh set. The mesh must also have - * CPU-caching enabled, so we get access to the mesh data. - */ - void VobImporter::addCollisionTo(bs::HSceneObject sceneObject) - { - bs::HRenderable renderable = sceneObject->getComponent(); - - if (!renderable) return; - - auto mesh = renderable->getMesh(); - - if (!mesh) return; - - auto meshData = mesh->getCachedData(); - - if (!meshData) return; - - bs::Path physicsMeshPath = BsZenLib::GothicPathToCachedStaticMesh(mesh->getName() + ".physics"); - - bs::HPhysicsMesh physicsMesh; - if (bs::FileSystem::exists(physicsMeshPath)) - { - physicsMesh = bs::gResources().load(physicsMeshPath); - } - else - { - REGOTH_LOG(Info, Uncategorized, "[ImportSingleVob] Caching physics mesh for {0}", - mesh->getName()); - - physicsMesh = bs::PhysicsMesh::create(meshData, bs::PhysicsMeshType::Triangle); - - BsZenLib::AddToResourceManifest(physicsMesh, physicsMeshPath); - bs::gResources().save(physicsMesh, physicsMeshPath, true); - } - - if (!physicsMesh) return; - - bs::HMeshCollider collider = sceneObject->addComponent(); - collider->setMesh(physicsMesh); - } - - bs::Matrix4 VobImporter::convertMatrix(const ZMath::Matrix& m) - { - bs::Matrix4 bs = {m.mv[0], m.mv[1], m.mv[2], m.mv[3], m.mv[4], m.mv[5], m.mv[6], m.mv[7], - m.mv[8], m.mv[9], m.mv[10], m.mv[11], m.mv[12], m.mv[13], m.mv[14], m.mv[15]}; - - return bs.transpose(); - } - -} // namespace REGoth diff --git a/src/world/internals/VobImporter.hpp b/src/world/internals/VobImporter.hpp deleted file mode 100644 index 825107b3..00000000 --- a/src/world/internals/VobImporter.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/** \file - */ - -#pragma once - -#include -#include -#include - -namespace ZenLoad -{ - struct zCVobData; -} - -namespace REGoth -{ - class GameWorld; - using HGameWorld = bs::GameObjectHandle; - - class VobImporter - { - public: - VobImporter() = default; - ~VobImporter() = default; - - /** - * Imports a single vob and creates a bs:f object as similar as possible. - * - * @param vob Information from importing the zen-file. - * @param bsfParent Parent game object. - * @param gameWorld World to create the object in. - * - * @return Scene object modeled after the vob - */ - bs::HSceneObject importSingleVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - - //FIXME: Come up with a better way, possibly by reworking the importer into one, so there only need to be 2 getters instead of 3 - bs::HSceneObject getWorldStartPoint() - { - return mStartpoint; - } - - private: - bs::HSceneObject mStartpoint; - - bs::Matrix4 convertMatrix(const ZMath::Matrix& m); - bs::HSceneObject import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - bs::HSceneObject import_zCVobLight(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - bs::HSceneObject import_zCVobStartpoint(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - bs::HSceneObject import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - bs::HSceneObject import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - bs::HSceneObject import_zCVobSound(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - bs::HSceneObject import_zCVobAnimate(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - bs::HSceneObject import_oCMobInter(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - bs::HSceneObject import_oCMobContainer(const ZenLoad::zCVobData& vob, - bs::HSceneObject bsfParent, HGameWorld gameWorld); - bs::HSceneObject import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - bs::HSceneObject import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, - HGameWorld gameWorld); - void addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName); - void addCollisionTo(bs::HSceneObject sceneObject); - bs::Transform transformFromVob(const ZenLoad::zCVobData& vob); - - }; - -} // namespace REGoth diff --git a/src/world/internals/ZenImporter.cpp b/src/world/internals/ZenImporter.cpp index 8bc17d04..fb79e984 100644 --- a/src/world/internals/ZenImporter.cpp +++ b/src/world/internals/ZenImporter.cpp @@ -3,7 +3,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -12,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -20,7 +25,13 @@ namespace REGoth { - + ZenImporter::ZenImporter() : mVobImporter(new VobImporter) + {} + + ZenImporter::~ZenImporter(){ + delete mVobImporter; + } + bs::HSceneObject ZenImporter::constructFromZEN(HGameWorld gameWorld, const bs::String& zenFile) { OriginalZen zen; @@ -70,7 +81,7 @@ namespace REGoth { for (const auto& v : zenParent.childVobs) { - bs::HSceneObject so = mVobImporter.importSingleVob(v, bsfParent, gameWorld); + bs::HSceneObject so = mVobImporter->importSingleVob(*this, v, bsfParent, gameWorld); if (so) { @@ -215,3 +226,321 @@ namespace REGoth } } // namespace REGoth + +namespace REGoth +{ + + bs::HSceneObject ZenImporter::VobImporter::importSingleVob(ZenImporter& zenImporter, const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld) + { + if (vob.objectClass == "zCVob") + { + return import_zCVob(vob, bsfParent, gameWorld); + } + else if (vob.objectClass == "zCVobLight:zCVob") + { + return import_zCVobLight(vob, bsfParent, gameWorld); + } + else if (vob.objectClass == "zCVobStartpoint:zCVob") + { + return import_zCVobStartpoint(zenImporter, vob, bsfParent, gameWorld); + } + else if (vob.objectClass == "zCVobSpot:zCVob") + { + return import_zCVobSpot(vob, bsfParent, gameWorld); + } + else if (vob.objectClass == "zCVobSound:zCVob") + { + return import_zCVobSound(vob, bsfParent, gameWorld); + } + else if (vob.objectClass == "oCItem:zCVob") + { + return import_oCItem(vob, bsfParent, gameWorld); + } + else if (vob.objectClass == "zCVobAnimate:zCVob") + { + return import_zCVobAnimate(vob, bsfParent, gameWorld); + } + // else if (vob.objectClass == "oCMobInter:oCMOB:zCVob") + // { + // return import_oCMobInter(vob, bsfParent, gameWorld); + // } + // else if (vob.objectClass == "oCMobContainer:oCMobInter:oCMOB:zCVob") + // { + // return import_oCMobContainer(vob, bsfParent, gameWorld); + // } + // else if (vob.objectClass == "oCMobBed:oCMobInter:oCMOB:zCVob") + // { + // return import_oCMobBed(vob, bsfParent, gameWorld); + // } + // else if (vob.objectClass == "oCMobDoor:oCMobInter:oCMOB:zCVob") + // { + // return import_oCMobDoor(vob, bsfParent, gameWorld); + // } + else + { + REGOTH_LOG(Warning, Uncategorized, "[ImportSingleVob] Unsupported vob class: {0}", + bs::String(vob.objectClass.c_str())); + + return {}; + } + } + + bs::Transform ZenImporter::VobImporter::transformFromVob(const ZenLoad::zCVobData& vob) + { + bs::Transform result = bs::Transform::IDENTITY; + + bs::Matrix4 worldMatrix = convertMatrix(vob.worldMatrix); + bs::Quaternion rotation; + rotation.fromRotationMatrix(worldMatrix.get3x3()); + + bs::Vector3 positionCM = bs::Vector3(vob.position.x, vob.position.y, vob.position.z); + + float centimetersToMeters = 0.01f; + + result.setPosition(positionCM * centimetersToMeters); + result.setRotation(rotation); + + return result; + } + + /** + * The zCVob is the most basic object class we will encounter. It is + * the base class of most other objects, so it makes sense to handle + * position, rotation and the visual here as these are used by most vobs. + * + * @note Not all object types will call `import_zCVob`! + */ + bs::HSceneObject ZenImporter::VobImporter::import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld) + { + bs::HSceneObject so = bs::SceneObject::create(vob.vobName.c_str()); + + so->setParent(gameWorld->SO()); + + bs::Transform transform = transformFromVob(vob); + + so->setPosition(transform.pos()); + so->setRotation(transform.rot()); + + if (!vob.visual.empty()) + { + addVisualTo(so, vob.visual.c_str()); + } + + // cdDyn seems to be the general "this is supposed to collide with stuff"-flag. + if (vob.cdDyn) + { + addCollisionTo(so); + } + + return so; + } + + /** + * Lights can be pointlights or spotlights, although spotlights are not + * used within the original game as it seems. + */ + bs::HSceneObject ZenImporter::VobImporter::import_zCVobLight(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + // FIXME: Put lights back in + return so; +#if 0 + bs::HLight light = so->addComponent(); + + auto lightColor = bs::Color::fromRGBA(vob.zCVobLight.color); + + light->setType(bs::LightType::Radial); + light->setUseAutoAttenuation(false); + light->setAttenuationRadius(vob.zCVobLight.range); + light->setColor(lightColor); + + return so; +#endif + } + + /** + * The startpoint of the player in the current world. There should be only one. + */ + bs::HSceneObject ZenImporter::VobImporter::import_zCVobStartpoint(ZenImporter& zenImporter, const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + //FIXME: Rotate by 180Degrees?; Why do I spawn in the Oldmine looking the wrong way? + /* + bs::Quaternion rotate180Y = bs::Quaternion(bs::Radian(0), + bs::Radian(bs::Degree(180)), + bs::Radian(0)); + so->rotate(rotate180Y); +*/ + + // Startpoint is found by name of the scene object + REGOTH_LOG(Info, Uncategorized, "[ImportSingleVob] Found startpoint: {0}", so->getName()); + + zenImporter.mStartpoint = so; + + return so; + } + + /** + * Spots like free-points. + */ + bs::HSceneObject ZenImporter::VobImporter::import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + so->addComponent(); + + return so; + } + + bs::HSceneObject ZenImporter::VobImporter::import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld) + { + if (vob.oCItem.instanceName.empty()) + { + REGOTH_LOG(Warning, Uncategorized, "[ImportSingleVob] Item with empty script instance: {0}", + bs::String(vob.vobName.c_str())); + return {}; + } + + bs::Transform transform = transformFromVob(vob); + + // Items are interactable, they need to be registered within the GameWorld + HItem item = gameWorld->insertItem(vob.oCItem.instanceName.c_str(), transform); + + item->SO()->setParent(bsfParent); + + return item->SO(); + } + + bs::HSceneObject ZenImporter::VobImporter::import_zCVobSound(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + // TODO: Implement + + return so; + } + + bs::HSceneObject ZenImporter::VobImporter::import_zCVobAnimate(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + // TODO: Implement + + return so; + } + + bs::HSceneObject ZenImporter::VobImporter::import_oCMobInter(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + // TODO: Implement + + return so; + } + + bs::HSceneObject ZenImporter::VobImporter::import_oCMobContainer(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + // TODO: Implement + + return so; + } + + bs::HSceneObject ZenImporter::VobImporter::import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + // TODO: Implement + + return so; + } + + bs::HSceneObject ZenImporter::VobImporter::import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld) + { + bs::HSceneObject so = import_zCVob(vob, bsfParent, gameWorld); + + // TODO: Implement + + return so; + } + + /** + * Adds the given visual to the scene object. If that's not possible + * nothing will be added. + */ + void ZenImporter::VobImporter::addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName) + { + bool hasAdded = Visual::addToSceneObject(sceneObject, visualName); + + if (!hasAdded) + { + REGOTH_LOG(Warning, Uncategorized, "[ImportSingleVob] Unsupported visual: {0}", visualName); + } + } + + /** + * Adds a triangle physics mesh to the given scene object. Only works if the + * scene object has a renderable with a mesh set. The mesh must also have + * CPU-caching enabled, so we get access to the mesh data. + */ + void ZenImporter::VobImporter::addCollisionTo(bs::HSceneObject sceneObject) + { + bs::HRenderable renderable = sceneObject->getComponent(); + + if (!renderable) return; + + auto mesh = renderable->getMesh(); + + if (!mesh) return; + + auto meshData = mesh->getCachedData(); + + if (!meshData) return; + + bs::Path physicsMeshPath = BsZenLib::GothicPathToCachedStaticMesh(mesh->getName() + ".physics"); + + bs::HPhysicsMesh physicsMesh; + if (bs::FileSystem::exists(physicsMeshPath)) + { + physicsMesh = bs::gResources().load(physicsMeshPath); + } + else + { + REGOTH_LOG(Info, Uncategorized, "[ImportSingleVob] Caching physics mesh for {0}", + mesh->getName()); + + physicsMesh = bs::PhysicsMesh::create(meshData, bs::PhysicsMeshType::Triangle); + + BsZenLib::AddToResourceManifest(physicsMesh, physicsMeshPath); + bs::gResources().save(physicsMesh, physicsMeshPath, true); + } + + if (!physicsMesh) return; + + bs::HMeshCollider collider = sceneObject->addComponent(); + collider->setMesh(physicsMesh); + } + + bs::Matrix4 ZenImporter::VobImporter::convertMatrix(const ZMath::Matrix& m) + { + bs::Matrix4 bs = {m.mv[0], m.mv[1], m.mv[2], m.mv[3], m.mv[4], m.mv[5], m.mv[6], m.mv[7], + m.mv[8], m.mv[9], m.mv[10], m.mv[11], m.mv[12], m.mv[13], m.mv[14], m.mv[15]}; + + return bs.transpose(); + } + +} // namespace REGoth diff --git a/src/world/internals/ZenImporter.hpp b/src/world/internals/ZenImporter.hpp index e43fa37f..e01a2640 100644 --- a/src/world/internals/ZenImporter.hpp +++ b/src/world/internals/ZenImporter.hpp @@ -4,7 +4,8 @@ #pragma once #include -#include "VobImporter.hpp" +#include +#include namespace REGoth { @@ -14,8 +15,8 @@ namespace REGoth class ZenImporter { public: - ZenImporter() = default; - ~ZenImporter() = default; + ZenImporter(); + ~ZenImporter(); /** * This function will load the given zenFile from the virtual file system @@ -37,13 +38,15 @@ namespace REGoth */ bs::HSceneObject loadWorldMeshFromZEN(const bs::String& zenFile); - bs::HSceneObject getWorldStartPoint() + bs::HSceneObject getStartpoint() { - return mVobImporter.getWorldStartPoint(); + return mStartpoint; } private: - VobImporter mVobImporter; + bs::HSceneObject mStartpoint; + class VobImporter; + VobImporter* mVobImporter; struct OriginalZen { @@ -60,4 +63,52 @@ namespace REGoth const ZenLoad::zCVobData& zenParent); }; + class ZenImporter::VobImporter + { + public: + VobImporter() = default; + ~VobImporter() = default; + + /** + * Imports a single vob and creates a bs:f object as similar as possible. + * + * @param vob Information from importing the zen-file. + * @param bsfParent Parent game object. + * @param gameWorld World to create the object in. + * + * @return Scene object modeled after the vob + */ + bs::HSceneObject importSingleVob(ZenImporter& zenImporter, const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + + private: + bs::Matrix4 convertMatrix(const ZMath::Matrix& m); + bs::HSceneObject import_zCVob(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_zCVobLight(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_zCVobStartpoint(ZenImporter& zenImporter, const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_zCVobSpot(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_oCItem(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_zCVobSound(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_zCVobAnimate(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_oCMobInter(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_oCMobContainer(const ZenLoad::zCVobData& vob, + bs::HSceneObject bsfParent, HGameWorld gameWorld); + bs::HSceneObject import_oCMobBed(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + bs::HSceneObject import_oCMobDoor(const ZenLoad::zCVobData& vob, bs::HSceneObject bsfParent, + HGameWorld gameWorld); + void addVisualTo(bs::HSceneObject sceneObject, const bs::String& visualName); + void addCollisionTo(bs::HSceneObject sceneObject); + bs::Transform transformFromVob(const ZenLoad::zCVobData& vob); + + }; + } // namespace REGoth