mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-21 00:25:44 +00:00
chore: export gltf basic attributes
This commit is contained in:
parent
8a0c93d3d8
commit
0d96213f21
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Json/JsonExtension.h"
|
#include "Json/JsonExtension.h"
|
||||||
|
#include <array>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -20,14 +21,16 @@ namespace gltf
|
|||||||
class JsonNode
|
class JsonNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::optional<std::string> name;
|
||||||
std::vector<float> translation;
|
std::optional<std::array<float, 3>> translation;
|
||||||
std::vector<float> rotation;
|
std::optional<std::array<float, 4>> rotation;
|
||||||
std::vector<float> scale;
|
std::optional<std::array<float, 3>> scale;
|
||||||
std::vector<unsigned> children;
|
std::optional<std::vector<unsigned>> children;
|
||||||
|
std::optional<unsigned> skin;
|
||||||
|
std::optional<unsigned> mesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonNode, name, translation, rotation, scale, children);
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonNode, name, translation, rotation, scale, children, skin, mesh);
|
||||||
|
|
||||||
class JsonBuffer
|
class JsonBuffer
|
||||||
{
|
{
|
||||||
@ -166,7 +169,7 @@ namespace gltf
|
|||||||
unsigned output;
|
unsigned output;
|
||||||
};
|
};
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAnimationSampler, input);
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAnimationSampler, input, interpolation, output);
|
||||||
|
|
||||||
class JsonAnimation
|
class JsonAnimation
|
||||||
{
|
{
|
||||||
@ -238,19 +241,30 @@ namespace gltf
|
|||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSkin, inverseBindMatrices, skeleton, joints);
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonSkin, inverseBindMatrices, skeleton, joints);
|
||||||
|
|
||||||
|
class JsonScene
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::vector<unsigned> nodes;
|
||||||
|
std::optional<std::string> name;
|
||||||
|
};
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonScene, nodes, name);
|
||||||
|
|
||||||
class JsonRoot
|
class JsonRoot
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<JsonAccessor> accessors;
|
std::optional<std::vector<JsonAccessor>> accessors;
|
||||||
std::vector<JsonAnimation> animations;
|
std::optional<std::vector<JsonAnimation>> animations;
|
||||||
JsonAsset asset;
|
JsonAsset asset;
|
||||||
std::vector<JsonBuffer> buffers;
|
std::optional<std::vector<JsonBuffer>> buffers;
|
||||||
std::vector<JsonBufferView> bufferViews;
|
std::optional<std::vector<JsonBufferView>> bufferViews;
|
||||||
std::vector<JsonMaterial> materials;
|
std::optional<std::vector<JsonMaterial>> materials;
|
||||||
std::vector<JsonMesh> meshes;
|
std::optional<std::vector<JsonMesh>> meshes;
|
||||||
std::vector<JsonNode> nodes;
|
std::optional<std::vector<JsonNode>> nodes;
|
||||||
std::vector<JsonSkin> skins;
|
std::optional<std::vector<JsonSkin>> skins;
|
||||||
|
std::optional<unsigned> scene;
|
||||||
|
std::optional<std::vector<JsonScene>> scenes;
|
||||||
};
|
};
|
||||||
|
|
||||||
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonRoot, asset);
|
NLOHMANN_DEFINE_TYPE_EXTENSION(JsonRoot, accessors, animations, asset, buffers, bufferViews, materials, meshes, nodes, skins, scene, scenes);
|
||||||
} // namespace gltf
|
} // namespace gltf
|
||||||
|
@ -13,6 +13,9 @@ namespace
|
|||||||
|
|
||||||
class GltfWriterImpl final : public gltf::Writer
|
class GltfWriterImpl final : public gltf::Writer
|
||||||
{
|
{
|
||||||
|
static constexpr auto NODE_INDEX_MESH = 0u;
|
||||||
|
static constexpr auto NODE_FIRST_INDEX_BONES = 1u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GltfWriterImpl(const Output* output, std::string gameName, std::string zoneName)
|
GltfWriterImpl(const Output* output, std::string gameName, std::string zoneName)
|
||||||
: m_output(output),
|
: m_output(output),
|
||||||
@ -24,8 +27,12 @@ namespace
|
|||||||
void Write(std::ostream& stream) override
|
void Write(std::ostream& stream) override
|
||||||
{
|
{
|
||||||
JsonRoot gltf;
|
JsonRoot gltf;
|
||||||
gltf.asset.version = GLTF_VERSION_STRING;
|
CreateJsonAsset(gltf.asset);
|
||||||
gltf.asset.generator = GLTF_GENERATOR;
|
CreateMeshNode(gltf);
|
||||||
|
CreateMesh(gltf);
|
||||||
|
CreateSkeletonNodes(gltf);
|
||||||
|
CreateSkin(gltf);
|
||||||
|
CreateScene(gltf);
|
||||||
|
|
||||||
const json jRoot = gltf;
|
const json jRoot = gltf;
|
||||||
m_output->EmitJson(jRoot);
|
m_output->EmitJson(jRoot);
|
||||||
@ -33,6 +40,109 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void CreateJsonAsset(JsonAsset& asset)
|
||||||
|
{
|
||||||
|
asset.version = GLTF_VERSION_STRING;
|
||||||
|
asset.generator = GLTF_GENERATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateMeshNode(JsonRoot& gltf) const
|
||||||
|
{
|
||||||
|
JsonNode meshNode;
|
||||||
|
|
||||||
|
// We only have one mesh
|
||||||
|
meshNode.mesh = 0u;
|
||||||
|
|
||||||
|
// Only add skin if the model has bones
|
||||||
|
if (!m_bones.empty())
|
||||||
|
{
|
||||||
|
// We only have one skin
|
||||||
|
meshNode.skin = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gltf.nodes.has_value())
|
||||||
|
gltf.nodes.emplace();
|
||||||
|
|
||||||
|
gltf.nodes->emplace_back(std::move(meshNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateMesh(JsonRoot& gltf) const
|
||||||
|
{
|
||||||
|
if (!gltf.meshes.has_value())
|
||||||
|
gltf.meshes.emplace();
|
||||||
|
|
||||||
|
JsonMesh mesh;
|
||||||
|
|
||||||
|
gltf.meshes->emplace_back(std::move(mesh));
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned CreateNodeIndexFromBoneIndex(const unsigned boneIndex)
|
||||||
|
{
|
||||||
|
return boneIndex + NODE_FIRST_INDEX_BONES;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateSkeletonNodes(JsonRoot& gltf) const
|
||||||
|
{
|
||||||
|
if (m_bones.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!gltf.nodes.has_value())
|
||||||
|
gltf.nodes.emplace();
|
||||||
|
|
||||||
|
for (const auto [boneIndex, bone] : std::views::enumerate(m_bones))
|
||||||
|
{
|
||||||
|
JsonNode boneNode;
|
||||||
|
|
||||||
|
boneNode.name = bone.name;
|
||||||
|
boneNode.translation = std::to_array(bone.globalOffset);
|
||||||
|
boneNode.rotation = std::to_array({bone.globalRotation.m_x, bone.globalRotation.m_y, bone.globalRotation.m_z, bone.globalRotation.m_w});
|
||||||
|
|
||||||
|
const auto isParentOf = [this, boneIndex](const unsigned b)
|
||||||
|
{
|
||||||
|
return m_bones[b].parentIndex == boneIndex;
|
||||||
|
};
|
||||||
|
auto children = std::ranges::iota_view(0u, m_bones.size()) | std::views::filter(isParentOf)
|
||||||
|
| std::views::transform(CreateNodeIndexFromBoneIndex) | std::ranges::to<std::vector<unsigned>>();
|
||||||
|
if (!children.empty())
|
||||||
|
boneNode.children = std::move(children);
|
||||||
|
|
||||||
|
gltf.nodes->emplace_back(std::move(boneNode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateSkin(JsonRoot& gltf) const
|
||||||
|
{
|
||||||
|
if (m_bones.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
JsonSkin skin;
|
||||||
|
skin.joints =
|
||||||
|
std::ranges::iota_view(0u, m_bones.size()) | std::views::transform(CreateNodeIndexFromBoneIndex) | std::ranges::to<std::vector<unsigned>>();
|
||||||
|
|
||||||
|
if (!gltf.skins.has_value())
|
||||||
|
gltf.skins.emplace();
|
||||||
|
gltf.skins->emplace_back(std::move(skin));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateScene(JsonRoot& gltf) const
|
||||||
|
{
|
||||||
|
JsonScene scene;
|
||||||
|
|
||||||
|
// Only add skin if the model has bones
|
||||||
|
if (m_bones.empty())
|
||||||
|
scene.nodes.emplace_back(NODE_INDEX_MESH);
|
||||||
|
else
|
||||||
|
scene.nodes.emplace_back(m_skeleton_node);
|
||||||
|
|
||||||
|
if (!gltf.scenes.has_value())
|
||||||
|
gltf.scenes.emplace();
|
||||||
|
|
||||||
|
gltf.scenes->emplace_back(std::move(scene));
|
||||||
|
gltf.scene = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned m_skeleton_node = 0u;
|
||||||
|
|
||||||
const Output* m_output;
|
const Output* m_output;
|
||||||
std::string m_game_name;
|
std::string m_game_name;
|
||||||
std::string m_zone_name;
|
std::string m_zone_name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user