mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-06 08:42:35 +00:00
feat: heirarchical transforms are now implemented
This commit is contained in:
@@ -359,14 +359,12 @@ namespace
|
|||||||
return vertexOffset;
|
return vertexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addLightNode(const gltf::JsonNode& node)
|
bool addLightNode(const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
assert(m_is_world_gfx);
|
assert(m_is_world_gfx);
|
||||||
assert(node.extensions);
|
assert(node.extensions);
|
||||||
assert(node.extensions->KHR_lights_punctual);
|
assert(node.extensions->KHR_lights_punctual);
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
|
|
||||||
int lightIndex = node.extensions->KHR_lights_punctual->light;
|
int lightIndex = node.extensions->KHR_lights_punctual->light;
|
||||||
|
|
||||||
assert(lightIndex >= 0);
|
assert(lightIndex >= 0);
|
||||||
@@ -438,13 +436,11 @@ namespace
|
|||||||
return newMaterialIndex;
|
return newMaterialIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addMeshNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
bool addMeshNode(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
assert(node.mesh);
|
assert(node.mesh);
|
||||||
assert(jRoot.meshes);
|
assert(jRoot.meshes);
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
|
|
||||||
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
||||||
for (const auto& primitive : mesh.primitives)
|
for (const auto& primitive : mesh.primitives)
|
||||||
{
|
{
|
||||||
@@ -559,12 +555,11 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addXModelNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
bool addXModelNode(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
assert(node.extras);
|
assert(node.extras);
|
||||||
assert(node.extras->contains("xmodel"));
|
assert(node.extras->contains("xmodel"));
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
BSPXModel xmodel;
|
BSPXModel xmodel;
|
||||||
|
|
||||||
xmodel.name = node.extras->at("xmodel");
|
xmodel.name = node.extras->at("xmodel");
|
||||||
@@ -607,13 +602,11 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addSpawnPointNode(const gltf::JsonNode& node)
|
bool addSpawnPointNode(const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
assert(node.extras);
|
assert(node.extras);
|
||||||
assert(node.extras->contains("spawnpoint"));
|
assert(node.extras->contains("spawnpoint"));
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
|
|
||||||
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
||||||
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
@@ -650,12 +643,11 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t addScriptBrushModel(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
size_t addScriptBrushModel(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
if (!node.mesh || !jRoot.meshes)
|
if (!node.mesh || !jRoot.meshes)
|
||||||
throw new GltfLoadException("Script model created with no mesh data");
|
throw new GltfLoadException("Script model created with no mesh data");
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
||||||
|
|
||||||
if (mesh.primitives.size() == 0)
|
if (mesh.primitives.size() == 0)
|
||||||
@@ -737,12 +729,11 @@ namespace
|
|||||||
return m_bsp->models.size(); // script model index starts at 1
|
return m_bsp->models.size(); // script model index starts at 1
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t addScriptTerrainModel(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
size_t addScriptTerrainModel(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
if (!node.mesh || !jRoot.meshes)
|
if (!node.mesh || !jRoot.meshes)
|
||||||
throw new GltfLoadException("Script model created with no mesh data");
|
throw new GltfLoadException("Script model created with no mesh data");
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
const auto& mesh = jRoot.meshes.value()[node.mesh.value()];
|
||||||
|
|
||||||
if (mesh.primitives.size() == 0)
|
if (mesh.primitives.size() == 0)
|
||||||
@@ -798,7 +789,7 @@ namespace
|
|||||||
return m_bsp->models.size(); // script model index starts at 1
|
return m_bsp->models.size(); // script model index starts at 1
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addZoneNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
bool addZoneNode(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
assert(node.extras);
|
assert(node.extras);
|
||||||
assert(node.extras->contains("zone"));
|
assert(node.extras->contains("zone"));
|
||||||
@@ -809,8 +800,6 @@ namespace
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
|
|
||||||
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
||||||
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
@@ -824,19 +813,17 @@ namespace
|
|||||||
zone.zoneName = node.extras->at("zone");
|
zone.zoneName = node.extras->at("zone");
|
||||||
zone.spawnerGroupName = node.extras->at("spawner_group");
|
zone.spawnerGroupName = node.extras->at("spawner_group");
|
||||||
zone.spawnpointGroupName = node.extras->at("spawnpoint_group");
|
zone.spawnpointGroupName = node.extras->at("spawnpoint_group");
|
||||||
zone.modelIndex = addScriptBrushModel(jRoot, node);
|
zone.modelIndex = addScriptBrushModel(jRoot, node, nodeMatrix);
|
||||||
m_bsp->zm_zones.emplace_back(zone);
|
m_bsp->zm_zones.emplace_back(zone);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addZSpawnerNode(const gltf::JsonNode& node)
|
bool addZSpawnerNode(const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
assert(node.extras);
|
assert(node.extras);
|
||||||
assert(node.extras->contains("spawner"));
|
assert(node.extras->contains("spawner"));
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
|
|
||||||
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
||||||
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
@@ -866,7 +853,7 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addClassNode(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
bool addClassNode(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
assert(node.extras);
|
assert(node.extras);
|
||||||
assert(node.extras->contains("classname"));
|
assert(node.extras->contains("classname"));
|
||||||
@@ -891,15 +878,13 @@ namespace
|
|||||||
if (node.mesh && !doesClassContainModel)
|
if (node.mesh && !doesClassContainModel)
|
||||||
{
|
{
|
||||||
if (m_is_world_gfx)
|
if (m_is_world_gfx)
|
||||||
entity.modelIndex = addScriptTerrainModel(jRoot, node);
|
entity.modelIndex = addScriptTerrainModel(jRoot, node, nodeMatrix);
|
||||||
else
|
else
|
||||||
entity.modelIndex = addScriptBrushModel(jRoot, node);
|
entity.modelIndex = addScriptBrushModel(jRoot, node, nodeMatrix);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
entity.modelIndex = 0;
|
entity.modelIndex = 0;
|
||||||
|
|
||||||
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
|
||||||
|
|
||||||
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
Eigen::Vector4f position(0, 0, 0, 1.0f);
|
||||||
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
Eigen::Vector4f transformedPosition = nodeMatrix * position;
|
||||||
entity.origin.x = transformedPosition.x();
|
entity.origin.x = transformedPosition.x();
|
||||||
@@ -920,37 +905,37 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addNodeToBSP(const JsonRoot& jRoot, const gltf::JsonNode& node)
|
bool addNodeToBSP(const JsonRoot& jRoot, const gltf::JsonNode& node, Eigen::Matrix4f& nodeMatrix)
|
||||||
{
|
{
|
||||||
if (m_is_world_gfx && node.extensions && node.extensions->KHR_lights_punctual)
|
if (m_is_world_gfx && node.extensions && node.extensions->KHR_lights_punctual)
|
||||||
return addLightNode(node);
|
return addLightNode(node, nodeMatrix);
|
||||||
|
|
||||||
if (node.extras)
|
if (node.extras)
|
||||||
{
|
{
|
||||||
if (!m_is_world_gfx)
|
if (!m_is_world_gfx)
|
||||||
{
|
{
|
||||||
if (node.extras->contains("classname"))
|
if (node.extras->contains("classname"))
|
||||||
return addClassNode(jRoot, node);
|
return addClassNode(jRoot, node, nodeMatrix);
|
||||||
|
|
||||||
if (node.extras->contains("spawnpoint"))
|
if (node.extras->contains("spawnpoint"))
|
||||||
return addSpawnPointNode(node);
|
return addSpawnPointNode(node, nodeMatrix);
|
||||||
|
|
||||||
if (m_bsp->isZombiesMap)
|
if (m_bsp->isZombiesMap)
|
||||||
{
|
{
|
||||||
if (node.extras->contains("zone"))
|
if (node.extras->contains("zone"))
|
||||||
return addZoneNode(jRoot, node);
|
return addZoneNode(jRoot, node, nodeMatrix);
|
||||||
|
|
||||||
if (node.extras->contains("spawner"))
|
if (node.extras->contains("spawner"))
|
||||||
return addZSpawnerNode(node);
|
return addZSpawnerNode(node, nodeMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.extras->contains("xmodel"))
|
if (node.extras->contains("xmodel"))
|
||||||
return addXModelNode(jRoot, node);
|
return addXModelNode(jRoot, node, nodeMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.mesh)
|
if (node.mesh)
|
||||||
return addMeshNode(jRoot, node);
|
return addMeshNode(jRoot, node, nodeMatrix);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1155,27 +1140,32 @@ namespace
|
|||||||
if (!jRoot.nodes || jRoot.nodes->empty())
|
if (!jRoot.nodes || jRoot.nodes->empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::deque<unsigned> nodeQueue;
|
struct s_nodes
|
||||||
const std::vector<unsigned> rootNodes = GetRootNodes(jRoot);
|
{
|
||||||
|
unsigned int nodeIndex;
|
||||||
|
Eigen::Matrix4f parentNodeMatrix;
|
||||||
|
};
|
||||||
|
|
||||||
for (const auto rootNode : rootNodes)
|
std::deque<s_nodes> nodeQueue;
|
||||||
nodeQueue.emplace_back(rootNode);
|
for (const auto rootNode : GetRootNodes(jRoot))
|
||||||
|
nodeQueue.emplace_back(s_nodes{rootNode, Eigen::Matrix4f::Identity()});
|
||||||
|
|
||||||
while (!nodeQueue.empty())
|
while (!nodeQueue.empty())
|
||||||
{
|
{
|
||||||
const auto& node = jRoot.nodes.value()[nodeQueue.front()];
|
const auto& node = jRoot.nodes.value()[nodeQueue.front().nodeIndex];
|
||||||
|
Eigen::Matrix4f parentNodeMatrix = nodeQueue.front().parentNodeMatrix;
|
||||||
nodeQueue.pop_front();
|
nodeQueue.pop_front();
|
||||||
|
|
||||||
|
Eigen::Matrix4f nodeMatrix = createNodeMatrix(node);
|
||||||
|
Eigen::Matrix4f transformedNodeMatrix = parentNodeMatrix * nodeMatrix;
|
||||||
|
|
||||||
if (node.children)
|
if (node.children)
|
||||||
{
|
{
|
||||||
for (const auto childIndex : *node.children)
|
for (const auto childIndex : *node.children)
|
||||||
nodeQueue.emplace_back(childIndex);
|
nodeQueue.emplace_back(s_nodes{childIndex, transformedNodeMatrix});
|
||||||
|
|
||||||
if (node.matrix || node.translation || node.rotation || node.scale)
|
|
||||||
con::warn("Parent node has position data that won't be used");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!addNodeToBSP(jRoot, node))
|
if (!addNodeToBSP(jRoot, node, transformedNodeMatrix))
|
||||||
con::warn("({}) Ignoring node: {}", getWorldTypeName(), node.name.value_or("unnamed node"));
|
con::warn("({}) Ignoring node: {}", getWorldTypeName(), node.name.value_or("unnamed node"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user