diff --git a/src/ObjCommon/XModel/Gltf/JsonGltf.h b/src/ObjCommon/XModel/Gltf/JsonGltf.h index dccbc794..f7b18b12 100644 --- a/src/ObjCommon/XModel/Gltf/JsonGltf.h +++ b/src/ObjCommon/XModel/Gltf/JsonGltf.h @@ -194,13 +194,40 @@ namespace gltf NLOHMANN_DEFINE_TYPE_EXTENSION(JsonAnimation, channels, samplers, name); + class JsonTextureInfo + { + public: + unsigned index; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTextureInfo, index); + + class JsonPbrMetallicRoughness + { + public: + std::optional baseColorTexture; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonPbrMetallicRoughness, baseColorTexture); + + class JsonNormalTextureInfo + { + public: + unsigned index; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonNormalTextureInfo, index); + class JsonMaterial { public: std::optional name; + std::optional pbrMetallicRoughness; + std::optional normalTexture; + std::optional doubleSided; }; - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial, name); + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonMaterial, name, pbrMetallicRoughness, normalTexture, doubleSided); enum class JsonMeshPrimitivesMode { @@ -276,6 +303,22 @@ namespace gltf NLOHMANN_DEFINE_TYPE_EXTENSION(JsonScene, nodes, name); + class JsonTexture + { + public: + unsigned source; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonTexture, source); + + class JsonImage + { + public: + std::optional uri; + }; + + NLOHMANN_DEFINE_TYPE_EXTENSION(JsonImage, uri); + class JsonRoot { public: @@ -284,13 +327,16 @@ namespace gltf JsonAsset asset; std::optional> buffers; std::optional> bufferViews; + std::optional> images; std::optional> materials; std::optional> meshes; std::optional> nodes; std::optional> skins; std::optional scene; std::optional> scenes; + std::optional> textures; }; - NLOHMANN_DEFINE_TYPE_EXTENSION(JsonRoot, accessors, animations, asset, buffers, bufferViews, materials, meshes, nodes, skins, scene, scenes); + NLOHMANN_DEFINE_TYPE_EXTENSION( + JsonRoot, accessors, animations, asset, buffers, bufferViews, images, materials, meshes, nodes, skins, scene, scenes, textures); } // namespace gltf diff --git a/src/ObjWriting/XModel/Gltf/GltfWriter.cpp b/src/ObjWriting/XModel/Gltf/GltfWriter.cpp index 3db6698b..ed640ba9 100644 --- a/src/ObjWriting/XModel/Gltf/GltfWriter.cpp +++ b/src/ObjWriting/XModel/Gltf/GltfWriter.cpp @@ -4,6 +4,8 @@ #include "XModel/Gltf/GltfConstants.h" #include "XModel/Gltf/JsonGltf.h" +#include + using namespace gltf; using namespace nlohmann; @@ -124,10 +126,50 @@ namespace material.name = modelMaterial.name; + if (!modelMaterial.colorMapName.empty()) + material.pbrMetallicRoughness.emplace().baseColorTexture.emplace().index = CreateTexture(gltf, modelMaterial.colorMapName); + + if (!modelMaterial.normalMapName.empty()) + material.normalTexture.emplace().index = CreateTexture(gltf, modelMaterial.colorMapName); + + material.doubleSided = true; gltf.materials->emplace_back(material); } } + static unsigned CreateTexture(JsonRoot& gltf, const std::string& textureName) + { + if (!gltf.textures.has_value()) + gltf.textures.emplace(); + if (!gltf.images.has_value()) + gltf.images.emplace(); + + auto uri = std::format("../images/{}.dds", textureName); + + auto existingTexIndex = 0u; + for (const auto& existingTex : gltf.textures.value()) + { + const auto& existingImage = gltf.images.value()[existingTex.source]; + + if (existingImage.uri == uri) + return existingTexIndex; + + existingTexIndex++; + } + + JsonImage image; + image.uri = std::move(uri); + const auto imageIndex = gltf.images->size(); + gltf.images->emplace_back(std::move(image)); + + JsonTexture texture; + texture.source = imageIndex; + const auto textureIndex = gltf.textures->size(); + gltf.textures->emplace_back(texture); + + return textureIndex; + } + static void CreateSkeletonNodes(JsonRoot& gltf, const XModelCommon& xmodel) { if (xmodel.m_bones.empty())