From f0ea5dad7d57b167c8d32192cae1c11186682563 Mon Sep 17 00:00:00 2001 From: LJW-Dev <48092720+LJW-Dev@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:22:51 +0800 Subject: [PATCH] feat: trigger_use and trigger_multiple can now be loaded through GLTF --- src/ObjCommon/XModel/Gltf/JsonGltf.h | 7 ++- src/ObjLoading/Game/T6/BSP/BSP.h | 10 ++++ src/ObjLoading/Game/T6/BSP/BSPCreator.cpp | 54 +++++++++++++++++++ .../Game/T6/BSP/Linker/MapEntsLinker.cpp | 25 +++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) diff --git a/src/ObjCommon/XModel/Gltf/JsonGltf.h b/src/ObjCommon/XModel/Gltf/JsonGltf.h index 959069a4..354d9054 100644 --- a/src/ObjCommon/XModel/Gltf/JsonGltf.h +++ b/src/ObjCommon/XModel/Gltf/JsonGltf.h @@ -103,9 +103,14 @@ namespace gltf std::optional spawnpoint_group; // value: zone zspawner group name std::optional zspawner; // value: zspawner group name + + // scripting + std::optional trigger_use; + std::optional trigger_multiple; }; - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonNodeExtras, xmodel, spawnpoint, flags, pathnode, zone, zspawner_group, spawnpoint_group, zspawner); + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonNodeExtras, xmodel, spawnpoint, flags, pathnode, zone, zspawner_group, spawnpoint_group, zspawner, trigger_use, trigger_multiple); class JsonNode { diff --git a/src/ObjLoading/Game/T6/BSP/BSP.h b/src/ObjLoading/Game/T6/BSP/BSP.h index 6c1c6612..80ef1d4c 100644 --- a/src/ObjLoading/Game/T6/BSP/BSP.h +++ b/src/ObjLoading/Game/T6/BSP/BSP.h @@ -160,6 +160,13 @@ namespace BSP size_t brushIndex; }; + struct BSPTriggerBox + { + vec3_t origin; + size_t modelIndex; + std::string triggerName; + }; + struct BSPData { std::string name; @@ -177,6 +184,9 @@ namespace BSP std::vector zSpawners; std::vector zZones; + std::vector useTriggers; + std::vector triggerMultiples; + std::vector models; }; diff --git a/src/ObjLoading/Game/T6/BSP/BSPCreator.cpp b/src/ObjLoading/Game/T6/BSP/BSPCreator.cpp index 6fe760e8..40237515 100644 --- a/src/ObjLoading/Game/T6/BSP/BSPCreator.cpp +++ b/src/ObjLoading/Game/T6/BSP/BSPCreator.cpp @@ -866,6 +866,54 @@ namespace return true; } + bool addTriggerUseNode(const JsonRoot& jRoot, const gltf::JsonNode& node) + { + assert(node.extras); + assert(node.extras->trigger_use); + + Eigen::Matrix4f nodeMatrix = createNodeMatrix(node); + + Eigen::Vector4f position(0, 0, 0, 1.0f); + Eigen::Vector4f transformedPosition = nodeMatrix * position; + vec3_t origin; + origin.x = transformedPosition.x(); + origin.y = transformedPosition.y(); + origin.z = transformedPosition.z(); + RhcToLhcCoordinates(origin.v); + + BSPTriggerBox trigger; + trigger.origin = origin; + trigger.triggerName = *node.extras->trigger_use; + trigger.modelIndex = addScriptBrushModel(jRoot, node); + m_bsp->useTriggers.emplace_back(trigger); + + return true; + } + + bool addTriggerMultipleNode(const JsonRoot& jRoot, const gltf::JsonNode& node) + { + assert(node.extras); + assert(node.extras->trigger_multiple); + + Eigen::Matrix4f nodeMatrix = createNodeMatrix(node); + + Eigen::Vector4f position(0, 0, 0, 1.0f); + Eigen::Vector4f transformedPosition = nodeMatrix * position; + vec3_t origin; + origin.x = transformedPosition.x(); + origin.y = transformedPosition.y(); + origin.z = transformedPosition.z(); + RhcToLhcCoordinates(origin.v); + + BSPTriggerBox trigger; + trigger.origin = origin; + trigger.triggerName = *node.extras->trigger_multiple; + trigger.modelIndex = addScriptBrushModel(jRoot, node); + m_bsp->triggerMultiples.emplace_back(trigger); + + return true; + } + bool addNodeToBSP(const JsonRoot& jRoot, const gltf::JsonNode& node) { if (m_is_world_gfx && node.extensions && node.extensions->KHR_lights_punctual) @@ -882,6 +930,12 @@ namespace if (!m_is_world_gfx && node.extras->pathnode) return addPathNode_Node(node); + if (!m_is_world_gfx && node.extras->trigger_use) + return addTriggerUseNode(jRoot, node); + + if (!m_is_world_gfx && node.extras->trigger_multiple) + return addTriggerMultipleNode(jRoot, node); + if (!m_is_world_gfx && m_bsp->isZombiesMap) { if (node.extras->zone) diff --git a/src/ObjLoading/Game/T6/BSP/Linker/MapEntsLinker.cpp b/src/ObjLoading/Game/T6/BSP/Linker/MapEntsLinker.cpp index 3b90c6f9..3c76e6d8 100644 --- a/src/ObjLoading/Game/T6/BSP/Linker/MapEntsLinker.cpp +++ b/src/ObjLoading/Game/T6/BSP/Linker/MapEntsLinker.cpp @@ -173,6 +173,29 @@ namespace } } + void addScriptingToEntString(BSP::BSPData* bsp, std::string& entityString) + { + for (auto& useTrigger : bsp->useTriggers) + { + entityString.append("{\n"); + entityString.append("\"classname\" \"trigger_use\"\n"); + entityString.append(std::format("\"targetname\" \"{}\"\n", useTrigger.triggerName)); + entityString.append(std::format("\"origin\" \"{}\"\n", BSP::BSPUtil::convertVec3ToString(useTrigger.origin))); + entityString.append(std::format("\"model\" \"*{}\"\n", useTrigger.modelIndex)); + entityString.append("}\n"); + } + + for (auto& useTrigger : bsp->triggerMultiples) + { + entityString.append("{\n"); + entityString.append("\"classname\" \"trigger_multiple\"\n"); + entityString.append(std::format("\"targetname\" \"{}\"\n", useTrigger.triggerName)); + entityString.append(std::format("\"origin\" \"{}\"\n", BSP::BSPUtil::convertVec3ToString(useTrigger.origin))); + entityString.append(std::format("\"model\" \"*{}\"\n", useTrigger.modelIndex)); + entityString.append("}\n"); + } + } + constexpr const char* DEFAULT_MAP_ENTS_STRING = R"({ "entities": [ { @@ -229,6 +252,8 @@ namespace BSP if (bsp->isZombiesMap) addZombiesEntitiesToEntString(bsp, entityString); + addScriptingToEntString(bsp, entityString); + MapEnts* mapEnts = m_memory.Alloc(); mapEnts->name = m_memory.Dup(bsp->bspName.c_str());