From f42fbae8e9cd288ab874c287f000d8976832e9d1 Mon Sep 17 00:00:00 2001 From: InkSoul Date: Sun, 20 Apr 2025 22:38:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=88=9D=E6=AD=A5gltf?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CMakeLists.txt | 64 +- src/gltf/glTFAnimation.cpp | 77 ++ src/gltf/glTFAnimation.h | 51 + src/gltf/glTFAnimationChannel.cpp | 47 + src/{render => gltf}/glTFAnimationChannel.h | 15 +- src/gltf/glTFAnimationSampler.cpp | 55 + src/gltf/glTFAnimationSampler.h | 39 + src/{render => gltf}/glTFBoundingBox.cpp | 36 +- src/{render => gltf}/glTFBoundingBox.h | 11 +- src/gltf/glTFMainModel.cpp | 938 ++++++++++++++++++ src/gltf/glTFMainModel.h | 84 ++ src/gltf/glTFMaterial.cpp | 84 ++ src/gltf/glTFMaterial.h | 66 ++ src/{render => gltf}/glTFMesh.cpp | 25 + src/{render => gltf}/glTFMesh.h | 6 + src/{render => gltf}/glTFModel.cpp | 2 +- src/{render => gltf}/glTFModel.h | 0 src/{render => gltf}/glTFModel_Marco.h | 0 .../glTFModel_common.h} | 17 + src/{render => gltf}/glTFNode.cpp | 120 +++ src/gltf/glTFNode.h | 89 ++ src/{render => gltf}/glTFPrimitive.cpp | 26 + src/{render => gltf}/glTFPrimitive.h | 13 +- src/gltf/glTFSkin.cpp | 62 ++ src/{render => gltf}/glTFSkin.h | 10 + src/{render => gltf}/glTFTexture.cpp | 0 src/{render => gltf}/glTFTexture.h | 6 +- src/pbr/PbrBaseTexture.cpp | 104 ++ src/pbr/PbrBaseTexture.h | 69 ++ src/pbr/PbrTextureCoordSet.cpp | 74 ++ src/pbr/PbrTextureCoordSet.h | 47 + src/pbr/PbrTextureExtension.cpp | 55 + src/pbr/PbrTextureExtension.h | 51 + src/pbr/PbrWorkFlow.cpp | 35 + src/pbr/PbrWorkFlow.h | 33 + src/render/glTFAnimation.cpp | 14 - src/render/glTFAnimation.h | 33 - src/render/glTFAnimationChannel.cpp | 15 - src/render/glTFAnimationSampler.cpp | 15 - src/render/glTFAnimationSampler.h | 28 - src/render/glTFMaterial.cpp | 19 - src/render/glTFMaterial.h | 62 -- src/render/glTFNode.h | 54 - src/render/glTFSkin.cpp | 27 - 44 files changed, 2373 insertions(+), 305 deletions(-) create mode 100644 src/gltf/glTFAnimation.cpp create mode 100644 src/gltf/glTFAnimation.h create mode 100644 src/gltf/glTFAnimationChannel.cpp rename src/{render => gltf}/glTFAnimationChannel.h (51%) create mode 100644 src/gltf/glTFAnimationSampler.cpp create mode 100644 src/gltf/glTFAnimationSampler.h rename src/{render => gltf}/glTFBoundingBox.cpp (69%) rename src/{render => gltf}/glTFBoundingBox.h (73%) create mode 100644 src/gltf/glTFMainModel.cpp create mode 100644 src/gltf/glTFMainModel.h create mode 100644 src/gltf/glTFMaterial.cpp create mode 100644 src/gltf/glTFMaterial.h rename src/{render => gltf}/glTFMesh.cpp (73%) rename src/{render => gltf}/glTFMesh.h (77%) rename src/{render => gltf}/glTFModel.cpp (99%) rename src/{render => gltf}/glTFModel.h (100%) rename src/{render => gltf}/glTFModel_Marco.h (100%) rename src/{render/glTFModel_Common.h => gltf/glTFModel_common.h} (65%) rename src/{render => gltf}/glTFNode.cpp (53%) create mode 100644 src/gltf/glTFNode.h rename src/{render => gltf}/glTFPrimitive.cpp (52%) rename src/{render => gltf}/glTFPrimitive.h (67%) create mode 100644 src/gltf/glTFSkin.cpp rename src/{render => gltf}/glTFSkin.h (65%) rename src/{render => gltf}/glTFTexture.cpp (100%) rename src/{render => gltf}/glTFTexture.h (89%) create mode 100644 src/pbr/PbrBaseTexture.cpp create mode 100644 src/pbr/PbrBaseTexture.h create mode 100644 src/pbr/PbrTextureCoordSet.cpp create mode 100644 src/pbr/PbrTextureCoordSet.h create mode 100644 src/pbr/PbrTextureExtension.cpp create mode 100644 src/pbr/PbrTextureExtension.h create mode 100644 src/pbr/PbrWorkFlow.cpp create mode 100644 src/pbr/PbrWorkFlow.h delete mode 100644 src/render/glTFAnimation.cpp delete mode 100644 src/render/glTFAnimation.h delete mode 100644 src/render/glTFAnimationChannel.cpp delete mode 100644 src/render/glTFAnimationSampler.cpp delete mode 100644 src/render/glTFAnimationSampler.h delete mode 100644 src/render/glTFMaterial.cpp delete mode 100644 src/render/glTFMaterial.h delete mode 100644 src/render/glTFNode.h delete mode 100644 src/render/glTFSkin.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa93b74..69144c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,30 +9,34 @@ set(MAIN_FILE ) set(GLTF_MODEL_LOADER - "${PLUMAGE_RENDER}/glTFModel_Marco.h" - "${PLUMAGE_RENDER}/glTFModel_common.h" - "${PLUMAGE_RENDER}/glTFBoundingBox.h" - "${PLUMAGE_RENDER}/glTFBoundingBox.cpp" - "${PLUMAGE_RENDER}/glTFTexture.h" - "${PLUMAGE_RENDER}/glTFTexture.cpp" - "${PLUMAGE_RENDER}/glTFModel.h" - "${PLUMAGE_RENDER}/glTFModel.cpp" - "${PLUMAGE_RENDER}/glTFMaterial.h" - "${PLUMAGE_RENDER}/glTFMaterial.cpp" - "render/glTFPrimitive.h" - "${PLUMAGE_RENDER}/glTFPrimitive.cpp" - "render/glTFMesh.h" - "render/glTFMesh.cpp" - "render/glTFSkin.h" - "render/glTFSkin.cpp" - "render/glTFNode.h" - "render/glTFNode.cpp" - "render/glTFAnimationChannel.h" - "render/glTFAnimationChannel.cpp" - "render/glTFAnimationSampler.h" - "render/glTFAnimationSampler.cpp" + "gltf/glTFModel_Marco.h" + "gltf/glTFModel_common.h" + "gltf/glTFBoundingBox.h" + "gltf/glTFBoundingBox.cpp" + "gltf/glTFTexture.h" + "gltf/glTFTexture.cpp" + "gltf/glTFModel.h" + "gltf/glTFModel.cpp" + "gltf/glTFMaterial.h" + "gltf/glTFMaterial.cpp" + "gltf/glTFPrimitive.h" + "gltf/glTFPrimitive.cpp" + "gltf/glTFMesh.h" + "gltf/glTFMesh.cpp" + "gltf/glTFSkin.h" + "gltf/glTFSkin.cpp" + "gltf/glTFNode.h" + "gltf/glTFNode.cpp" + "gltf/glTFAnimationChannel.h" + "gltf/glTFAnimationChannel.cpp" + "gltf/glTFAnimationSampler.h" + "gltf/glTFAnimationSampler.cpp" + "gltf/glTFAnimation.h" + "gltf/glTFAnimation.cpp" + "gltf/glTFMainModel.h" + "gltf/glTFMainModel.cpp" - "render/glTFAnimation.h" "render/glTFAnimation.cpp") +) set(VULKAN_BASE "${PLUMAGE_RENDER}/VulkanBase_Marco.h" @@ -41,7 +45,13 @@ set(VULKAN_BASE "${PLUMAGE_RENDER}/VulkanDevice.cpp" "${PLUMAGE_RENDER}/VulkanTextureSampler.h" "${PLUMAGE_RENDER}/VulkanTextureSampler.cpp" -) + "pbr/PbrTextureExtension.h" + "pbr/PbrTextureExtension.cpp" + "pbr/PbrBaseTexture.h" + "pbr/PbrBaseTexture.cpp" + "pbr/PbrTextureCoordSet.h" + "pbr/PbrTextureCoordSet.cpp" + "pbr/PbrWorkFlow.h" "pbr/PbrWorkFlow.cpp") # wayland requires additional source files IF(USE_WAYLAND_WSI) @@ -71,6 +81,12 @@ include_directories(${3rdParty_vulkan_path}) include_directories(${lib_base_path}) +# TODO: 拆分动态库 +include_directories(gltf) +include_directories(pbr) +include_directories(render) + + if(WIN32) add_executable(${RenderName} WIN32 ${SHADERS_GLSL} ${SHADERS_HLSL} ${MAIN_FILE} diff --git a/src/gltf/glTFAnimation.cpp b/src/gltf/glTFAnimation.cpp new file mode 100644 index 0000000..4af26ac --- /dev/null +++ b/src/gltf/glTFAnimation.cpp @@ -0,0 +1,77 @@ +#include "glTFAnimation.h" + +#include + +GLTFLOADER_NAMESPACE_BEGIN + +glTFAnimation::glTFAnimation() +{ + m_start = std::numeric_limits::max(); + m_end = std::numeric_limits::min(); +} + +glTFAnimation::~glTFAnimation() +{ +} + +void glTFAnimation::setChannels(std::vector& value) +{ + m_channels = value; +} + +std::vector glTFAnimation::getChannels() +{ + return m_channels; +} + +void glTFAnimation::pushChannelsBack(glTFAnimationChannel value) +{ + m_channels.push_back(value); +} + +void glTFAnimation::setSamplers(std::vector& value) +{ + m_samplers = value; +} + +std::vector glTFAnimation::getSampler() +{ + return m_samplers; +} + +void glTFAnimation::pushSamplersBack(glTFAnimationSampler value) +{ + m_samplers.push_back(value); +} + +void glTFAnimation::setName(std::string name) +{ + m_name = name; +} + +std::string glTFAnimation::getName() +{ + return m_name; +} + +void glTFAnimation::setStart(float start) +{ + m_start = start; +} + +float glTFAnimation::getStart() +{ + return m_start; +} + +void glTFAnimation::setEnd(float end) +{ + m_end = end; +} + +float glTFAnimation::getEnd() +{ + return m_end; +} + +GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/gltf/glTFAnimation.h b/src/gltf/glTFAnimation.h new file mode 100644 index 0000000..c83dd66 --- /dev/null +++ b/src/gltf/glTFAnimation.h @@ -0,0 +1,51 @@ +#ifndef GLTFANIMATION_H +#define GLTFANIMATION_H + +#include "glTFModel_Marco.h" + + +#include "glTFAnimationChannel.h" +#include "glTFAnimationSampler.h" + +#include +#include + + +GLTFLOADER_NAMESPACE_BEGIN + +class glTFAnimation +{ +public: + glTFAnimation(); + ~glTFAnimation(); + + void setChannels(std::vector& value); + std::vector getChannels(); + void pushChannelsBack(glTFAnimationChannel value); + + void setSamplers(std::vector& value); + std::vector getSampler(); + void pushSamplersBack(glTFAnimationSampler value); + + + void setName(std::string name); + std::string getName(); + + void setStart(float start); + float getStart(); + + void setEnd(float end); + float getEnd(); + +private: + std::string m_name; + std::vector m_samplers; + std::vector m_channels; + float m_start; + float m_end; +}; + + +GLTFLOADER_NAMESPACE_END + +#endif // !GLTFANIMATION diff --git a/src/gltf/glTFAnimationChannel.cpp b/src/gltf/glTFAnimationChannel.cpp new file mode 100644 index 0000000..2e02b17 --- /dev/null +++ b/src/gltf/glTFAnimationChannel.cpp @@ -0,0 +1,47 @@ +#include "glTFAnimationChannel.h" + +GLTFLOADER_NAMESPACE_BEGIN + +glTFAnimationChannel::glTFAnimationChannel() +{ +} + +glTFAnimationChannel::~glTFAnimationChannel() +{ +} + +void glTFAnimationChannel::setSamplerIndex(unsigned int samplerIndex) +{ + m_samplerIndex = samplerIndex; +} + +unsigned int glTFAnimationChannel::getSamplerIndex() +{ + return m_samplerIndex; +} + +void glTFAnimationChannel::setAnimationPathType(AnimationPathType pathType) +{ + m_pathType = pathType; +} + +AnimationPathType glTFAnimationChannel::getAnimationPathType() +{ + return m_pathType; +} + +void glTFAnimationChannel::setNode(glTFNode* node) +{ + m_node = node; +} + +glTFNode* glTFAnimationChannel::getNode() +{ + return m_node; +} + + + +GLTFLOADER_NAMESPACE_END + + diff --git a/src/render/glTFAnimationChannel.h b/src/gltf/glTFAnimationChannel.h similarity index 51% rename from src/render/glTFAnimationChannel.h rename to src/gltf/glTFAnimationChannel.h index 6e31b7f..7726ef3 100644 --- a/src/render/glTFAnimationChannel.h +++ b/src/gltf/glTFAnimationChannel.h @@ -14,11 +14,20 @@ public: glTFAnimationChannel(); ~glTFAnimationChannel(); + void setSamplerIndex(unsigned int samplerIndex); + unsigned int getSamplerIndex(); + + void setAnimationPathType(AnimationPathType pathType); + AnimationPathType getAnimationPathType(); + + void setNode(glTFNode* node); + glTFNode* getNode(); + private: - AnimationPathType path; - glTFNode* node; - uint32_t samplerIndex; + AnimationPathType m_pathType; + glTFNode* m_node; + unsigned int m_samplerIndex; }; diff --git a/src/gltf/glTFAnimationSampler.cpp b/src/gltf/glTFAnimationSampler.cpp new file mode 100644 index 0000000..1568019 --- /dev/null +++ b/src/gltf/glTFAnimationSampler.cpp @@ -0,0 +1,55 @@ +#include "glTFAnimationSampler.h" + + +GLTFLOADER_NAMESPACE_BEGIN + +glTFAnimationSampler::glTFAnimationSampler() +{ +} + +glTFAnimationSampler::~glTFAnimationSampler() +{ +} + +void glTFAnimationSampler::setOutputsVec4(std::vector& value) +{ + m_outputsVec4 = value; +} + +std::vector glTFAnimationSampler::getOutputsVec4() +{ + return m_outputsVec4; +} + +void glTFAnimationSampler::pushOutputsVec4Back(glm::vec4 value) +{ + m_outputsVec4.push_back(value); +} + +void glTFAnimationSampler::setInputs(std::vector& inputs) +{ + m_inputs = inputs; +} + +std::vector glTFAnimationSampler::getInputs() +{ + return m_inputs; +} + +void glTFAnimationSampler::pushInputBack(float value) +{ + m_inputs.push_back(value); +} + +void glTFAnimationSampler::setAnimationInterpolationType(AnimationInterpolationType interpolationType) +{ + m_interpolationType = interpolationType; +} + +AnimationInterpolationType glTFAnimationSampler::getAnimationInterpolationType() +{ + return m_interpolationType; +} + + +GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/gltf/glTFAnimationSampler.h b/src/gltf/glTFAnimationSampler.h new file mode 100644 index 0000000..57c7653 --- /dev/null +++ b/src/gltf/glTFAnimationSampler.h @@ -0,0 +1,39 @@ +#ifndef GLTFANIMATIONSAMPLER_H +#define GLTFANIMATIONSAMPLER_H + +#include "glTFModel_Marco.h" +#include "glTFModel_common.h" + + +#include + +GLTFLOADER_NAMESPACE_BEGIN + +class glTFAnimationSampler +{ +public: + glTFAnimationSampler(); + ~glTFAnimationSampler(); + + void setOutputsVec4(std::vector& value); + std::vector getOutputsVec4(); + void pushOutputsVec4Back(glm::vec4 value); + + void setInputs(std::vector& inputs); + std::vector getInputs(); + void pushInputBack(float value); + + void setAnimationInterpolationType(AnimationInterpolationType interpolationType); + AnimationInterpolationType getAnimationInterpolationType(); + +private: + AnimationInterpolationType m_interpolationType; + std::vector m_inputs; + std::vector m_outputsVec4; +}; + + + +GLTFLOADER_NAMESPACE_END + +#endif // !GLTFANIMATIONSAMPLER_H diff --git a/src/render/glTFBoundingBox.cpp b/src/gltf/glTFBoundingBox.cpp similarity index 69% rename from src/render/glTFBoundingBox.cpp rename to src/gltf/glTFBoundingBox.cpp index d6b157a..b339736 100644 --- a/src/render/glTFBoundingBox.cpp +++ b/src/gltf/glTFBoundingBox.cpp @@ -4,14 +4,14 @@ GLTFLOADER_NAMESPACE_BEGIN glTFBoundingBox::glTFBoundingBox() - : m_isValid(true) + : m_valid(true) , m_min(glm::vec3(0,0,0)) , m_max(glm::vec3(1,1,1)) { } glTFBoundingBox::glTFBoundingBox(glm::vec3 min, glm::vec3 max) - : m_isValid(true) + : m_valid(true) , m_min(min) , m_max(max) { @@ -52,7 +52,37 @@ void glTFBoundingBox::setBoundingBox(glm::vec3 min, glm::vec3 max) { m_min = min; m_max = max; - m_isValid = true; + m_valid = true; +} + +glm::vec3 glTFBoundingBox::getMin() +{ + return m_min; +} + +void glTFBoundingBox::setMin(glm::vec3 min) +{ + m_min = min; +} + +glm::vec3 glTFBoundingBox::getMax() +{ + return m_max; +} + +void glTFBoundingBox::setMax(glm::vec3 max) +{ + m_max = max; +} + +bool glTFBoundingBox::isValid() +{ + return m_valid; +} + +void glTFBoundingBox::setValid(bool valid) +{ + m_valid = valid; } diff --git a/src/render/glTFBoundingBox.h b/src/gltf/glTFBoundingBox.h similarity index 73% rename from src/render/glTFBoundingBox.h rename to src/gltf/glTFBoundingBox.h index a00b66b..b9248e0 100644 --- a/src/render/glTFBoundingBox.h +++ b/src/gltf/glTFBoundingBox.h @@ -17,11 +17,20 @@ public: void setBoundingBox(glm::vec3 min, glm::vec3 max); + glm::vec3 getMin(); + void setMin(glm::vec3 min); + + glm::vec3 getMax(); + void setMax(glm::vec3 max); + + bool isValid(); + void setValid(bool valid); + private: glm::vec3 m_min; glm::vec3 m_max; - bool m_isValid = false; + bool m_valid = false; }; diff --git a/src/gltf/glTFMainModel.cpp b/src/gltf/glTFMainModel.cpp new file mode 100644 index 0000000..ac63b09 --- /dev/null +++ b/src/gltf/glTFMainModel.cpp @@ -0,0 +1,938 @@ +#include "glTFMainModel.h" +#include +#include + +GLTFLOADER_NAMESPACE_BEGIN + +glTFMainModel::glTFMainModel() +{ +} + +glTFMainModel::~glTFMainModel() +{ +} + +void glTFMainModel::destroy(VkDevice device) +{ + if (m_vertices.buffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_vertices.buffer, nullptr); + vkFreeMemory(device, m_vertices.memory, nullptr); + m_vertices.buffer = VK_NULL_HANDLE; + } + if (m_indices.buffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_indices.buffer, nullptr); + vkFreeMemory(device, m_indices.memory, nullptr); + m_indices.buffer = VK_NULL_HANDLE; + } + for (glTFTexture texture : m_textures) { + texture.destroy(); + } + m_textures.resize(0); + + for (glTFNode* node : m_nodes) { + delete node; + } + m_nodes.resize(0); + + m_textureSamplers.resize(0); + m_materials.resize(0); + m_animations.resize(0); + m_linearNodes.resize(0); + m_extensions.resize(0); + + for (glTFSkin* skin : m_skins) { + delete skin; + } + + m_skins.resize(0); +} + + +void glTFMainModel::getNodeProperty(const tinygltf::Node& node, const tinygltf::Model& model, size_t& vertexCount, size_t& indexCount) +{ + if (node.children.size() > 0) { + for (size_t i = 0; i < node.children.size(); i++) { + getNodeProperty(model.nodes[node.children[i]], model, vertexCount, indexCount); + } + } + if (node.mesh > -1) { + const tinygltf::Mesh mesh = model.meshes[node.mesh]; + for (size_t i = 0; i < mesh.primitives.size(); i++) { + auto primitive = mesh.primitives[i]; + vertexCount += model.accessors[primitive.attributes.find("POSITION")->second].count; + if (primitive.indices > -1) { + indexCount += model.accessors[primitive.indices].count; + } + } + } +} + +void glTFMainModel::getSceneDimensions() +{ + // Calculate binary volume hierarchy for all nodes in the scene + for (glTFNode* node : m_linearNodes) { + calculateBoundingBox(node, nullptr); + } + + m_dimensions.min = glm::vec3(FLT_MAX); + m_dimensions.max = glm::vec3(-FLT_MAX); + + for (auto node : m_linearNodes) { + glTFBoundingBox bvh = node->getBvh(); + if (bvh.isValid()) { + m_dimensions.min = glm::min(m_dimensions.min, bvh.getMin()); + m_dimensions.max = glm::max(m_dimensions.max, bvh.getMax()); + } + } + + // Calculate scene aabb + m_aabb = glm::scale(glm::mat4(1.0f), glm::vec3(m_dimensions.max[0] - m_dimensions.min[0], m_dimensions.max[1] - m_dimensions.min[1], m_dimensions.max[2] - m_dimensions.min[2])); + m_aabb[3][0] = m_dimensions.min[0]; + m_aabb[3][1] = m_dimensions.min[1]; + m_aabb[3][2] = m_dimensions.min[2]; +} + +VkSamplerAddressMode glTFMainModel::getVkWrapMode(int32_t wrapMode) +{ + switch (wrapMode) { + case -1: + case 10497: + return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case 33071: + return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case 33648: + return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + } + + std::cerr << "Unknown wrap mode for getVkWrapMode: " << wrapMode << std::endl; + return VK_SAMPLER_ADDRESS_MODE_REPEAT; +} + +VkFilter glTFMainModel::getVkFilterMode(int32_t filterMode) +{ + switch (filterMode) { + case -1: + case 9728: + return VK_FILTER_NEAREST; + case 9729: + return VK_FILTER_LINEAR; + case 9984: + return VK_FILTER_NEAREST; + case 9985: + return VK_FILTER_NEAREST; + case 9986: + return VK_FILTER_LINEAR; + case 9987: + return VK_FILTER_LINEAR; + } + + std::cerr << "Unknown filter mode for getVkFilterMode: " << filterMode << std::endl; + return VK_FILTER_NEAREST; +} + +void glTFMainModel::loadNode(glTFNode* parent, const tinygltf::Node& node, uint32_t nodeIndex, const tinygltf::Model& model, LoaderInfo& loaderInfo, float globalscale) +{ + glTFNode* newNode = new glTFNode{}; + newNode->setIndex(nodeIndex); + newNode->setParent(parent); + newNode->setName(node.name); + newNode->setSkinIndex(node.skin); + newNode->setMatrix(glm::mat4(1.0f)); + + // Generate local node matrix + glm::vec3 translation = glm::vec3(0.0f); + if (node.translation.size() == 3) { + translation = glm::make_vec3(node.translation.data()); + newNode->setTranslation(translation); + } + glm::mat4 rotation = glm::mat4(1.0f); + if (node.rotation.size() == 4) { + glm::quat q = glm::make_quat(node.rotation.data()); + newNode->setRotation(glm::mat4(q)); + } + glm::vec3 scale = glm::vec3(1.0f); + if (node.scale.size() == 3) { + scale = glm::make_vec3(node.scale.data()); + newNode->setScale(scale); + } + if (node.matrix.size() == 16) { + newNode->setMatrix(glm::make_mat4x4(node.matrix.data())); + }; + + // Node with children + if (node.children.size() > 0) { + for (size_t i = 0; i < node.children.size(); i++) { + loadNode(newNode, model.nodes[node.children[i]], node.children[i], model, loaderInfo, globalscale); + } + } + + // Node contains mesh data + if (node.mesh > -1) { + const tinygltf::Mesh mesh = model.meshes[node.mesh]; + glTFMesh* newMesh = new glTFMesh(m_device, newNode->getMatrix()); + for (size_t j = 0; j < mesh.primitives.size(); j++) { + const tinygltf::Primitive& primitive = mesh.primitives[j]; + uint32_t vertexStart = static_cast(loaderInfo.vertexPos); + uint32_t indexStart = static_cast(loaderInfo.indexPos); + uint32_t indexCount = 0; + uint32_t vertexCount = 0; + glm::vec3 posMin{}; + glm::vec3 posMax{}; + bool hasSkin = false; + bool hasIndices = primitive.indices > -1; + // Vertices + { + const float* bufferPos = nullptr; + const float* bufferNormals = nullptr; + const float* bufferTexCoordSet0 = nullptr; + const float* bufferTexCoordSet1 = nullptr; + const float* bufferColorSet0 = nullptr; + const void* bufferJoints = nullptr; + const float* bufferWeights = nullptr; + + int posByteStride; + int normByteStride; + int uv0ByteStride; + int uv1ByteStride; + int color0ByteStride; + int jointByteStride; + int weightByteStride; + + int jointComponentType; + + // Position attribute is required + assert(primitive.attributes.find("POSITION") != primitive.attributes.end()); + + const tinygltf::Accessor& posAccessor = model.accessors[primitive.attributes.find("POSITION")->second]; + const tinygltf::BufferView& posView = model.bufferViews[posAccessor.bufferView]; + bufferPos = reinterpret_cast(&(model.buffers[posView.buffer].data[posAccessor.byteOffset + posView.byteOffset])); + posMin = glm::vec3(posAccessor.minValues[0], posAccessor.minValues[1], posAccessor.minValues[2]); + posMax = glm::vec3(posAccessor.maxValues[0], posAccessor.maxValues[1], posAccessor.maxValues[2]); + vertexCount = static_cast(posAccessor.count); + posByteStride = posAccessor.ByteStride(posView) ? (posAccessor.ByteStride(posView) / sizeof(float)) : tinygltf::GetNumComponentsInType(TINYGLTF_TYPE_VEC3); + + if (primitive.attributes.find("NORMAL") != primitive.attributes.end()) { + const tinygltf::Accessor& normAccessor = model.accessors[primitive.attributes.find("NORMAL")->second]; + const tinygltf::BufferView& normView = model.bufferViews[normAccessor.bufferView]; + bufferNormals = reinterpret_cast(&(model.buffers[normView.buffer].data[normAccessor.byteOffset + normView.byteOffset])); + normByteStride = normAccessor.ByteStride(normView) ? (normAccessor.ByteStride(normView) / sizeof(float)) : tinygltf::GetNumComponentsInType(TINYGLTF_TYPE_VEC3); + } + + // UVs + if (primitive.attributes.find("TEXCOORD_0") != primitive.attributes.end()) { + const tinygltf::Accessor& uvAccessor = model.accessors[primitive.attributes.find("TEXCOORD_0")->second]; + const tinygltf::BufferView& uvView = model.bufferViews[uvAccessor.bufferView]; + bufferTexCoordSet0 = reinterpret_cast(&(model.buffers[uvView.buffer].data[uvAccessor.byteOffset + uvView.byteOffset])); + uv0ByteStride = uvAccessor.ByteStride(uvView) ? (uvAccessor.ByteStride(uvView) / sizeof(float)) : tinygltf::GetNumComponentsInType(TINYGLTF_TYPE_VEC2); + } + if (primitive.attributes.find("TEXCOORD_1") != primitive.attributes.end()) { + const tinygltf::Accessor& uvAccessor = model.accessors[primitive.attributes.find("TEXCOORD_1")->second]; + const tinygltf::BufferView& uvView = model.bufferViews[uvAccessor.bufferView]; + bufferTexCoordSet1 = reinterpret_cast(&(model.buffers[uvView.buffer].data[uvAccessor.byteOffset + uvView.byteOffset])); + uv1ByteStride = uvAccessor.ByteStride(uvView) ? (uvAccessor.ByteStride(uvView) / sizeof(float)) : tinygltf::GetNumComponentsInType(TINYGLTF_TYPE_VEC2); + } + + // Vertex colors + if (primitive.attributes.find("COLOR_0") != primitive.attributes.end()) { + const tinygltf::Accessor& accessor = model.accessors[primitive.attributes.find("COLOR_0")->second]; + const tinygltf::BufferView& view = model.bufferViews[accessor.bufferView]; + bufferColorSet0 = reinterpret_cast(&(model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset])); + color0ByteStride = accessor.ByteStride(view) ? (accessor.ByteStride(view) / sizeof(float)) : tinygltf::GetNumComponentsInType(TINYGLTF_TYPE_VEC3); + } + + // Skinning + // Joints + if (primitive.attributes.find("JOINTS_0") != primitive.attributes.end()) { + const tinygltf::Accessor& jointAccessor = model.accessors[primitive.attributes.find("JOINTS_0")->second]; + const tinygltf::BufferView& jointView = model.bufferViews[jointAccessor.bufferView]; + bufferJoints = &(model.buffers[jointView.buffer].data[jointAccessor.byteOffset + jointView.byteOffset]); + jointComponentType = jointAccessor.componentType; + jointByteStride = jointAccessor.ByteStride(jointView) ? (jointAccessor.ByteStride(jointView) / tinygltf::GetComponentSizeInBytes(jointComponentType)) : tinygltf::GetNumComponentsInType(TINYGLTF_TYPE_VEC4); + } + + if (primitive.attributes.find("WEIGHTS_0") != primitive.attributes.end()) { + const tinygltf::Accessor& weightAccessor = model.accessors[primitive.attributes.find("WEIGHTS_0")->second]; + const tinygltf::BufferView& weightView = model.bufferViews[weightAccessor.bufferView]; + bufferWeights = reinterpret_cast(&(model.buffers[weightView.buffer].data[weightAccessor.byteOffset + weightView.byteOffset])); + weightByteStride = weightAccessor.ByteStride(weightView) ? (weightAccessor.ByteStride(weightView) / sizeof(float)) : tinygltf::GetNumComponentsInType(TINYGLTF_TYPE_VEC4); + } + + hasSkin = (bufferJoints && bufferWeights); + + for (size_t v = 0; v < posAccessor.count; v++) { + Vertex& vert = loaderInfo.vertexBuffer[loaderInfo.vertexPos]; + vert.pos = glm::vec4(glm::make_vec3(&bufferPos[v * posByteStride]), 1.0f); + vert.normal = glm::normalize(glm::vec3(bufferNormals ? glm::make_vec3(&bufferNormals[v * normByteStride]) : glm::vec3(0.0f))); + vert.uv0 = bufferTexCoordSet0 ? glm::make_vec2(&bufferTexCoordSet0[v * uv0ByteStride]) : glm::vec3(0.0f); + vert.uv1 = bufferTexCoordSet1 ? glm::make_vec2(&bufferTexCoordSet1[v * uv1ByteStride]) : glm::vec3(0.0f); + vert.color = bufferColorSet0 ? glm::make_vec4(&bufferColorSet0[v * color0ByteStride]) : glm::vec4(1.0f); + + if (hasSkin) + { + switch (jointComponentType) { + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: { + const uint16_t* buf = static_cast(bufferJoints); + vert.joint0 = glm::vec4(glm::make_vec4(&buf[v * jointByteStride])); + break; + } + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: { + const uint8_t* buf = static_cast(bufferJoints); + vert.joint0 = glm::vec4(glm::make_vec4(&buf[v * jointByteStride])); + break; + } + default: + // Not supported by spec + std::cerr << "Joint component type " << jointComponentType << " not supported!" << std::endl; + break; + } + } + else { + vert.joint0 = glm::vec4(0.0f); + } + vert.weight0 = hasSkin ? glm::make_vec4(&bufferWeights[v * weightByteStride]) : glm::vec4(0.0f); + // Fix for all zero weights + if (glm::length(vert.weight0) == 0.0f) { + vert.weight0 = glm::vec4(1.0f, 0.0f, 0.0f, 0.0f); + } + loaderInfo.vertexPos++; + } + } + // Indices + if (hasIndices) + { + const tinygltf::Accessor& accessor = model.accessors[primitive.indices > -1 ? primitive.indices : 0]; + const tinygltf::BufferView& bufferView = model.bufferViews[accessor.bufferView]; + const tinygltf::Buffer& buffer = model.buffers[bufferView.buffer]; + + indexCount = static_cast(accessor.count); + const void* dataPtr = &(buffer.data[accessor.byteOffset + bufferView.byteOffset]); + + switch (accessor.componentType) { + case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT: { + const uint32_t* buf = static_cast(dataPtr); + for (size_t index = 0; index < accessor.count; index++) { + loaderInfo.indexBuffer[loaderInfo.indexPos] = buf[index] + vertexStart; + loaderInfo.indexPos++; + } + break; + } + case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT: { + const uint16_t* buf = static_cast(dataPtr); + for (size_t index = 0; index < accessor.count; index++) { + loaderInfo.indexBuffer[loaderInfo.indexPos] = buf[index] + vertexStart; + loaderInfo.indexPos++; + } + break; + } + case TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE: { + const uint8_t* buf = static_cast(dataPtr); + for (size_t index = 0; index < accessor.count; index++) { + loaderInfo.indexBuffer[loaderInfo.indexPos] = buf[index] + vertexStart; + loaderInfo.indexPos++; + } + break; + } + default: + std::cerr << "Index component type " << accessor.componentType << " not supported!" << std::endl; + return; + } + } + glTFPrimitive* newPrimitive = new glTFPrimitive(indexStart, indexCount, vertexCount, primitive.material > -1 ? m_materials[primitive.material] : m_materials.back()); + newPrimitive->setBoundingBox(posMin, posMax); + newMesh->pushPrimitiveBack(newPrimitive); + } + // Mesh BB from BBs of primitives + for (auto p : newMesh->getPrimitives()) { + if (p->getBoundingBox().isValid() && !newMesh->getBoundingBox().isValid()) { + newMesh->setBoundingBox(p->getBoundingBox()); + newMesh->getBoundingBox().setValid(true); + } + newMesh->getBoundingBox().setMin(glm::min(newMesh->getBoundingBox().getMin(), p->getBoundingBox().getMin())); + newMesh->getBoundingBox().setMax(glm::max(newMesh->getBoundingBox().getMax(), p->getBoundingBox().getMax())) ; + } + newNode->setMesh(newMesh); + } + if (parent) { + parent->pushChildrenBack(newNode); + } + else { + m_nodes.push_back(newNode); + } + m_linearNodes.push_back(newNode); +} + +void glTFMainModel::loadSkins(tinygltf::Model& gltfModel) +{ + for (tinygltf::Skin& source : gltfModel.skins) { + glTFSkin* newSkin = new glTFSkin{}; + newSkin->setName(source.name); + + // Find skeleton root node + if (source.skeleton > -1) { + newSkin->setSkeletonRoot(nodeFromIndex(source.skeleton)); + } + + // Find joint nodes + for (int jointIndex : source.joints) { + glTFNode* node = nodeFromIndex(jointIndex); + if (node) { + newSkin->pushJointsBack(nodeFromIndex(jointIndex)); + } + } + + // Get inverse bind matrices from buffer + if (source.inverseBindMatrices > -1) { + const tinygltf::Accessor& accessor = gltfModel.accessors[source.inverseBindMatrices]; + const tinygltf::BufferView& bufferView = gltfModel.bufferViews[accessor.bufferView]; + const tinygltf::Buffer& buffer = gltfModel.buffers[bufferView.buffer]; + std::vector inverseMatrices = newSkin->getInverseBindMatrices(); + inverseMatrices.resize(accessor.count); + + newSkin->setInverseBindMatrices(inverseMatrices); + memcpy(newSkin->getInverseBindMatrices().data(), &buffer.data[accessor.byteOffset + bufferView.byteOffset], accessor.count * sizeof(glm::mat4)); + } + + m_skins.push_back(newSkin); + } +} + +void glTFMainModel::loadTextures(tinygltf::Model& gltfModel, VulkanBase::VulkanDevice* device, VkQueue transferQueue) +{ + for (tinygltf::Texture& tex : gltfModel.textures) { + tinygltf::Image image = gltfModel.images[tex.source]; + VulkanBase::VulkanTextureSampler textureSampler; + if (tex.sampler == -1) { + // No sampler specified, use a default one + textureSampler.setMaxFilter(VK_FILTER_LINEAR); + textureSampler.setMinFilter(VK_FILTER_LINEAR); + textureSampler.setAddressModeU(VK_SAMPLER_ADDRESS_MODE_REPEAT); + textureSampler.setAddressModeV(VK_SAMPLER_ADDRESS_MODE_REPEAT); + textureSampler.setAddressModeW(VK_SAMPLER_ADDRESS_MODE_REPEAT); + } + else { + textureSampler = m_textureSamplers[tex.sampler]; + } + glTFTexture texture; + texture.fromglTfImage(image, textureSampler, device, transferQueue); + m_textures.push_back(texture); + } +} + +void glTFMainModel::loadTextureSamplers(tinygltf::Model& gltfModel) +{ + for (tinygltf::Sampler smpl : gltfModel.samplers) { + VulkanBase::VulkanTextureSampler sampler{}; + sampler.setMinFilter(getVkFilterMode(smpl.minFilter)); + sampler.setMaxFilter(getVkFilterMode(smpl.magFilter)); + sampler.setAddressModeU(getVkWrapMode(smpl.wrapS)); + sampler.setAddressModeV(getVkWrapMode(smpl.wrapT)); + sampler.setAddressModeW(sampler.getAddressModeV()); + m_textureSamplers.push_back(sampler); + } +} + +void glTFMainModel::loadMaterials(tinygltf::Model& gltfModel) +{ + for (tinygltf::Material& mat : gltfModel.materials) { + glTFMaterial material{}; + material.setDoublesided(mat.doubleSided); + if (mat.values.find("baseColorTexture") != mat.values.end()) { + material.getPbrBaseTexture()->setBaseColorTexture(&m_textures[mat.values["baseColorTexture"].TextureIndex()]); + material.getTextureCoordSet()->setBaseColor(mat.values["baseColorTexture"].TextureTexCoord()); + } + if (mat.values.find("metallicRoughnessTexture") != mat.values.end()) { + material.getPbrBaseTexture()->setMetallicRoughnessTexture(&m_textures[mat.values["metallicRoughnessTexture"].TextureIndex()]); + material.getTextureCoordSet()->setMetallicRoughness(mat.values["metallicRoughnessTexture"].TextureTexCoord()); + } + if (mat.values.find("roughnessFactor") != mat.values.end()) { + material.getPbrBaseTexture()->setRoughnessFactor(static_cast(mat.values["roughnessFactor"].Factor())); + } + if (mat.values.find("metallicFactor") != mat.values.end()) { + material.getPbrBaseTexture()->setMetallicFactor(static_cast(mat.values["metallicFactor"].Factor())); + } + if (mat.values.find("baseColorFactor") != mat.values.end()) { + material.getPbrBaseTexture()->setBaseColorFactor(glm::make_vec4(mat.values["baseColorFactor"].ColorFactor().data())); + } + if (mat.additionalValues.find("normalTexture") != mat.additionalValues.end()) { + material.getPbrBaseTexture()->setNormalTexture(&m_textures[mat.additionalValues["normalTexture"].TextureIndex()]); + material.getTextureCoordSet()->setNormal(mat.additionalValues["normalTexture"].TextureTexCoord()); + } + if (mat.additionalValues.find("emissiveTexture") != mat.additionalValues.end()) { + material.getPbrBaseTexture()->setEmissiveTexture(&m_textures[mat.additionalValues["emissiveTexture"].TextureIndex()]); + material.getTextureCoordSet()->setEmissive(mat.additionalValues["emissiveTexture"].TextureTexCoord()); + } + if (mat.additionalValues.find("occlusionTexture") != mat.additionalValues.end()) { + material.getPbrBaseTexture()->setOcclusionTexture(&m_textures[mat.additionalValues["occlusionTexture"].TextureIndex()]); + material.getTextureCoordSet()->setOcclusion(mat.additionalValues["occlusionTexture"].TextureTexCoord()); + } + if (mat.additionalValues.find("alphaMode") != mat.additionalValues.end()) { + tinygltf::Parameter param = mat.additionalValues["alphaMode"]; + if (param.string_value == "BLEND") { + material.setAlphaMode(AlphaMode::ALPHAMODE_BLEND); + } + if (param.string_value == "MASK") { + material.setAlphaCutOff(0.5f); + material.setAlphaMode(AlphaMode::ALPHAMODE_MASK); + } + } + if (mat.additionalValues.find("alphaCutoff") != mat.additionalValues.end()) { + material.setAlphaCutOff(static_cast(mat.additionalValues["alphaCutoff"].Factor())); + } + if (mat.additionalValues.find("emissiveFactor") != mat.additionalValues.end()) { + material.getPbrBaseTexture()->setEmissiveFactor(glm::vec4(glm::make_vec3(mat.additionalValues["emissiveFactor"].ColorFactor().data()), 1.0)); + } + + // Extensions + + if (mat.extensions.find("KHR_materials_pbrSpecularGlossiness") != mat.extensions.end()) { + auto ext = mat.extensions.find("KHR_materials_pbrSpecularGlossiness"); + if (ext->second.Has("specularGlossinessTexture")) { + auto index = ext->second.Get("specularGlossinessTexture").Get("index"); + material.getTextureExtension()->setSpecularGlossinessTexture(&m_textures[index.Get()]); + auto texCoordSet = ext->second.Get("specularGlossinessTexture").Get("texCoord"); + material.getTextureCoordSet()->setSpecularGlossiness(texCoordSet.Get()); + material.getPbrWorkFlow()->setSpecularGlossiness(true); + } + if (ext->second.Has("diffuseTexture")) { + auto index = ext->second.Get("diffuseTexture").Get("index"); + material.getTextureExtension()->setDiffuseTexture(&m_textures[index.Get()]); + } + if (ext->second.Has("diffuseFactor")) { + auto factor = ext->second.Get("diffuseFactor"); + glm::vec4 diffuseFactor(0.0); + for (uint32_t i = 0; i < factor.ArrayLen(); i++) { + auto val = factor.Get(i); + diffuseFactor[i] = val.IsNumber() ? (float)val.Get() : (float)val.Get(); + } + material.getTextureExtension()->setDiffuseFactor(diffuseFactor); + } + if (ext->second.Has("specularFactor")) { + auto factor = ext->second.Get("specularFactor"); + glm::vec3 specularFactor(0.0); + for (uint32_t i = 0; i < factor.ArrayLen(); i++) { + auto val = factor.Get(i); + specularFactor[i] = val.IsNumber() ? (float)val.Get() : (float)val.Get(); + } + material.getTextureExtension()->setSpecularFactor(specularFactor); + } + } + + m_materials.push_back(material); + } + // Push a default material at the end of the list for meshes with no material assigned + m_materials.push_back(glTFMaterial()); +} + +void glTFMainModel::loadAnimations(tinygltf::Model& gltfModel) +{ + for (tinygltf::Animation& anim : gltfModel.animations) { + glTFAnimation animation{}; + animation.setName(anim.name); + if (anim.name.empty()) { + animation.setName(std::to_string(m_animations.size())); + } + + // Samplers + for (auto& samp : anim.samplers) { + glTFAnimationSampler sampler{}; + + if (samp.interpolation == "LINEAR") { + sampler.setAnimationInterpolationType(AnimationInterpolationType::LINEAR); + } + if (samp.interpolation == "STEP") { + sampler.setAnimationInterpolationType(AnimationInterpolationType::STEP); + } + if (samp.interpolation == "CUBICSPLINE") { + sampler.setAnimationInterpolationType(AnimationInterpolationType::CUBICSPLINE); + } + + // Read sampler input time values + { + const tinygltf::Accessor& accessor = gltfModel.accessors[samp.input]; + const tinygltf::BufferView& bufferView = gltfModel.bufferViews[accessor.bufferView]; + const tinygltf::Buffer& buffer = gltfModel.buffers[bufferView.buffer]; + + assert(accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT); + + const void* dataPtr = &buffer.data[accessor.byteOffset + bufferView.byteOffset]; + const float* buf = static_cast(dataPtr); + for (size_t index = 0; index < accessor.count; index++) { + + sampler.pushInputBack(buf[index]); + + } + + for (auto input : sampler.getInputs()) { + if (input < animation.getStart()) { + animation.setStart(input); + }; + if (input > animation.getEnd()) { + animation.setEnd(input); + } + } + } + + // Read sampler output T/R/S values + { + const tinygltf::Accessor& accessor = gltfModel.accessors[samp.output]; + const tinygltf::BufferView& bufferView = gltfModel.bufferViews[accessor.bufferView]; + const tinygltf::Buffer& buffer = gltfModel.buffers[bufferView.buffer]; + + assert(accessor.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT); + + const void* dataPtr = &buffer.data[accessor.byteOffset + bufferView.byteOffset]; + + switch (accessor.type) { + case TINYGLTF_TYPE_VEC3: { + const glm::vec3* buf = static_cast(dataPtr); + for (size_t index = 0; index < accessor.count; index++) { + + sampler.pushOutputsVec4Back(glm::vec4(buf[index], 0.0f)); + + } + break; + } + case TINYGLTF_TYPE_VEC4: { + const glm::vec4* buf = static_cast(dataPtr); + for (size_t index = 0; index < accessor.count; index++) { + + sampler.pushOutputsVec4Back(buf[index]); + + } + break; + } + default: { + std::cout << "unknown type" << std::endl; + break; + } + } + } + + animation.pushSamplersBack(sampler); + + } + + // Channels + for (auto& source : anim.channels) { + glTFAnimationChannel channel{}; + + if (source.target_path == "rotation") { + channel.setAnimationPathType(AnimationPathType::ROTATION); + } + if (source.target_path == "translation") { + channel.setAnimationPathType(AnimationPathType::TRANSLATION); + } + if (source.target_path == "scale") { + channel.setAnimationPathType(AnimationPathType::SCALE); + } + if (source.target_path == "weights") { + std::cout << "weights not yet supported, skipping channel" << std::endl; + continue; + } + channel.setSamplerIndex(source.sampler); + channel.setNode(nodeFromIndex(source.target_node)); + if (!channel.getNode()) { + continue; + } + + animation.pushChannelsBack(channel); + } + + m_animations.push_back(animation); + } +} + +void glTFMainModel::loadFromFile(std::string filename, VulkanBase::VulkanDevice* device, VkQueue transferQueue, float scale) +{ + tinygltf::Model gltfModel; + tinygltf::TinyGLTF gltfContext; + + std::string error; + std::string warning; + + m_device = device; + + bool binary = false; + size_t extpos = filename.rfind('.', filename.length()); + if (extpos != std::string::npos) { + binary = (filename.substr(extpos + 1, filename.length() - extpos) == "glb"); + } + + bool fileLoaded = binary ? gltfContext.LoadBinaryFromFile(&gltfModel, &error, &warning, filename.c_str()) : gltfContext.LoadASCIIFromFile(&gltfModel, &error, &warning, filename.c_str()); + + LoaderInfo loaderInfo{}; + size_t vertexCount = 0; + size_t indexCount = 0; + + if (fileLoaded) { + loadTextureSamplers(gltfModel); + loadTextures(gltfModel, device, transferQueue); + loadMaterials(gltfModel); + + const tinygltf::Scene& scene = gltfModel.scenes[gltfModel.defaultScene > -1 ? gltfModel.defaultScene : 0]; + + // Get vertex and index buffer sizes up-front + for (size_t i = 0; i < scene.nodes.size(); i++) { + getNodeProperty(gltfModel.nodes[scene.nodes[i]], gltfModel, vertexCount, indexCount); + } + loaderInfo.vertexBuffer = new Vertex[vertexCount]; + loaderInfo.indexBuffer = new uint32_t[indexCount]; + + // TODO: scene handling with no default scene + for (size_t i = 0; i < scene.nodes.size(); i++) { + const tinygltf::Node node = gltfModel.nodes[scene.nodes[i]]; + loadNode(nullptr, node, scene.nodes[i], gltfModel, loaderInfo, scale); + } + if (gltfModel.animations.size() > 0) { + loadAnimations(gltfModel); + } + loadSkins(gltfModel); + + for (auto node : m_linearNodes) { + // Assign skins + if (node->getSkinIndex() > -1) { + node->setSkin(m_skins[node->getSkinIndex()]); + } + // Initial pose + if (node->getMesh()) { + node->update(); + } + } + } + else { + // TODO: throw + std::cerr << "Could not load gltf file: " << error << std::endl; + return; + } + + m_extensions = gltfModel.extensionsUsed; + + size_t vertexBufferSize = vertexCount * sizeof(Vertex); + size_t indexBufferSize = indexCount * sizeof(uint32_t); + + assert(vertexBufferSize > 0); + + struct StagingBuffer { + VkBuffer buffer; + VkDeviceMemory memory; + } vertexStaging, indexStaging; + + // Create staging buffers + // Vertex data + VK_CHECK_RESULT(device->createBuffer( + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + vertexBufferSize, + &vertexStaging.buffer, + &vertexStaging.memory, + loaderInfo.vertexBuffer)); + // Index data + if (indexBufferSize > 0) { + VK_CHECK_RESULT(device->createBuffer( + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + indexBufferSize, + &indexStaging.buffer, + &indexStaging.memory, + loaderInfo.indexBuffer)); + } + + // Create device local buffers + // Vertex buffer + VK_CHECK_RESULT(device->createBuffer( + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + vertexBufferSize, + &m_vertices.buffer, + &m_vertices.memory)); + // Index buffer + if (indexBufferSize > 0) { + VK_CHECK_RESULT(device->createBuffer( + VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + indexBufferSize, + &m_indices.buffer, + &m_indices.memory)); + } + + // Copy from staging buffers + VkCommandBuffer copyCmd = device->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); + + VkBufferCopy copyRegion = {}; + + copyRegion.size = vertexBufferSize; + vkCmdCopyBuffer(copyCmd, vertexStaging.buffer, m_vertices.buffer, 1, ©Region); + + if (indexBufferSize > 0) { + copyRegion.size = indexBufferSize; + vkCmdCopyBuffer(copyCmd, indexStaging.buffer, m_indices.buffer, 1, ©Region); + } + + device->flushCommandBuffer(copyCmd, transferQueue, true); + + vkDestroyBuffer(device->getLogicalDevice(), vertexStaging.buffer, nullptr); + vkFreeMemory(device->getLogicalDevice(), vertexStaging.memory, nullptr); + if (indexBufferSize > 0) { + vkDestroyBuffer(device->getLogicalDevice(), indexStaging.buffer, nullptr); + vkFreeMemory(device->getLogicalDevice(), indexStaging.memory, nullptr); + } + + delete[] loaderInfo.vertexBuffer; + delete[] loaderInfo.indexBuffer; + + getSceneDimensions(); +} + +void glTFMainModel::drawNode(glTFNode* node, VkCommandBuffer commandBuffer) +{ + if (node->getMesh()) { + for (glTFPrimitive* primitive : node->getMesh()->getPrimitives()) { + vkCmdDrawIndexed(commandBuffer, primitive->getIndexCount(), 1, primitive->getFirstIndex(), 0, 0); + } + } + for (auto& child : node->getChildren()) { + drawNode(child, commandBuffer); + } +} + +void glTFMainModel::draw(VkCommandBuffer commandBuffer) +{ + const VkDeviceSize offsets[1] = { 0 }; + vkCmdBindVertexBuffers(commandBuffer, 0, 1, &m_vertices.buffer, offsets); + vkCmdBindIndexBuffer(commandBuffer, m_indices.buffer, 0, VK_INDEX_TYPE_UINT32); + for (auto& node : m_nodes) { + drawNode(node, commandBuffer); + } +} + +void glTFMainModel::calculateBoundingBox(glTFNode* node, glTFNode* parent) +{ + glTFBoundingBox parentBvh = parent ? parent->getBvh() : glTFBoundingBox(m_dimensions.min, m_dimensions.max); + + glTFMesh* nodeMesh = node->getMesh(); + + if (nodeMesh) { + if (nodeMesh->getBoundingBox().isValid()) { + node->setAxisAlignedBoundingBox(nodeMesh->getBoundingBox().getAABB(node->getMatrix())); + + if (node->getChildren().size() == 0) { + glTFBoundingBox nodeAABB = node->getAxisAlignedBoundingBox(); + nodeAABB.setValid(true); + node->setBvh(nodeAABB); + } + } + } + + parentBvh.setMin(glm::min(parentBvh.getMin(), node->getBvh().getMin())); + parentBvh.setMax(glm::min(parentBvh.getMax(), node->getBvh().getMax())); + + for (auto& child : node->getChildren()) { + calculateBoundingBox(child, node); + } +} + +void glTFMainModel::updateAnimation(uint32_t index, float time) +{ + if (m_animations.empty()) { + std::cout << ".glTF does not contain animation." << std::endl; + return; + } + if (index > static_cast(m_animations.size()) - 1) { + std::cout << "No animation with index " << index << std::endl; + return; + } + glTFAnimation& animation = m_animations[index]; + + bool updated = false; + for (auto& channel : animation.getChannels()) { + glTFAnimationSampler& sampler = animation.getSampler()[channel.getSamplerIndex()]; + if (sampler.getInputs().size() > sampler.getOutputsVec4().size()) { + continue; + } + std::vector samplerInputs = sampler.getInputs(); + for (size_t i = 0; i < sampler.getInputs().size() - 1; i++) { + if ((time >= samplerInputs[i]) && (time <= samplerInputs[i + 1])) { + float u = std::max(0.0f, time - samplerInputs[i]) / (samplerInputs[i + 1] - samplerInputs[i]); + if (u <= 1.0f) + { + switch (channel.getAnimationPathType()) { + case glTFLoader::AnimationPathType::TRANSLATION: + { + std::vector samplerOutPutVec4 = sampler.getOutputsVec4(); + glm::vec4 translate = glm::mix(samplerOutPutVec4[i], samplerOutPutVec4[i + 1], u); + glTFNode* channelNode = channel.getNode(); + channelNode->setTranslation(translate); + channel.setNode(channelNode); + break; + } + case glTFLoader::AnimationPathType::SCALE: + { + std::vector samplerOutPutVec4 = sampler.getOutputsVec4(); + glm::vec4 scaler = glm::mix(samplerOutPutVec4[i], samplerOutPutVec4[i + 1], u); + glTFNode* channelNode = channel.getNode(); + channelNode->setScale(scaler); + channel.setNode(channelNode); + break; + } + case glTFLoader::AnimationPathType::ROTATION: + { + std::vector samplerOutPutVec4 = sampler.getOutputsVec4(); + glm::quat q1; + q1.x = samplerOutPutVec4[i].x; + q1.y = samplerOutPutVec4[i].y; + q1.z = samplerOutPutVec4[i].z; + q1.w = samplerOutPutVec4[i].w; + glm::quat q2; + q2.x = samplerOutPutVec4[i + 1].x; + q2.y = samplerOutPutVec4[i + 1].y; + q2.z = samplerOutPutVec4[i + 1].z; + q2.w = samplerOutPutVec4[i + 1].w; + + glTFNode* channelNode = channel.getNode(); + channelNode->setRotation(glm::normalize(glm::slerp(q1, q2, u))); + channel.setNode(channelNode); + break; + } + } + updated = true; + } + } + } + } + if (updated) { + for (auto& node : m_nodes) { + node->update(); + } + } +} + +glTFNode* glTFMainModel::findNode(glTFNode* parent, uint32_t index) +{ + glTFNode* nodeFound = nullptr; + if (parent->getIndex() == index) { + return parent; + } + for (auto& child : parent->getChildren()) { + nodeFound = findNode(child, index); + if (nodeFound) { + break; + } + } + return nodeFound; +} + +glTFNode* glTFMainModel::nodeFromIndex(uint32_t index) +{ + glTFNode* nodeFound = nullptr; + for (auto& node : m_nodes) { + nodeFound = findNode(node, index); + if (nodeFound) { + break; + } + } + return nodeFound; +} + +GLTFLOADER_NAMESPACE_END + + diff --git a/src/gltf/glTFMainModel.h b/src/gltf/glTFMainModel.h new file mode 100644 index 0000000..f888e3e --- /dev/null +++ b/src/gltf/glTFMainModel.h @@ -0,0 +1,84 @@ +#ifndef GLTFMAINMODEL_H +#define GLTFMAINMODEL_H + +#include "glTFModel_Marco.h" +#include "glTFModel_common.h" + +#include "VulkanDevice.h" + +#include "glTFNode.h" +#include "glTFSkin.h" +#include "glTFTexture.h" +#include "glTFAnimation.h" + +#include +#include +#include + +GLTFLOADER_NAMESPACE_BEGIN + +class glTFMainModel +{ +public: + glTFMainModel(); + ~glTFMainModel(); + + VkSamplerAddressMode getVkWrapMode(int32_t wrapMode); + VkFilter getVkFilterMode(int32_t filterMode); + void getNodeProperty(const tinygltf::Node& node, const tinygltf::Model& model, size_t& vertexCount, size_t& indexCount); + void getSceneDimensions(); + void destroy(VkDevice device); + + void loadNode(glTFNode* parent, const tinygltf::Node& node, uint32_t nodeIndex, const tinygltf::Model& model, LoaderInfo& loaderInfo, float globalscale); + void loadSkins(tinygltf::Model& gltfModel); + void loadTextures(tinygltf::Model& gltfModel, VulkanBase::VulkanDevice* device, VkQueue transferQueue); + void loadTextureSamplers(tinygltf::Model& gltfModel); + void loadMaterials(tinygltf::Model& gltfModel); + void loadAnimations(tinygltf::Model& gltfModel); + void loadFromFile(std::string filename, VulkanBase::VulkanDevice* device, VkQueue transferQueue, float scale = 1.0f); + + void drawNode(glTFNode* node, VkCommandBuffer commandBuffer); + void draw(VkCommandBuffer commandBuffer); + + void calculateBoundingBox(glTFNode* node, glTFNode* parent); + void updateAnimation(uint32_t index, float time); + glTFNode* findNode(glTFNode* parent, uint32_t index); + glTFNode* nodeFromIndex(uint32_t index); + +private: + + VulkanBase::VulkanDevice* m_device; + + struct Vertices { + VkBuffer buffer = VK_NULL_HANDLE; + VkDeviceMemory memory; + } m_vertices; + struct Indices { + VkBuffer buffer = VK_NULL_HANDLE; + VkDeviceMemory memory; + } m_indices; + + glm::mat4 m_aabb; + + std::vector m_nodes; + std::vector m_linearNodes; + + std::vector m_skins; + + std::vector m_textures; + std::vector m_textureSamplers; + std::vector m_materials; + std::vector m_animations; + std::vector m_extensions; + + struct Dimensions { + glm::vec3 min = glm::vec3(FLT_MAX); + glm::vec3 max = glm::vec3(-FLT_MAX); + } m_dimensions; + +}; + + +GLTFLOADER_NAMESPACE_END + +#endif // !GLTFMAINMODEL_h diff --git a/src/gltf/glTFMaterial.cpp b/src/gltf/glTFMaterial.cpp new file mode 100644 index 0000000..ebde6b8 --- /dev/null +++ b/src/gltf/glTFMaterial.cpp @@ -0,0 +1,84 @@ +#include "glTFMaterial.h" + + +GLTFLOADER_NAMESPACE_BEGIN + +glTFMaterial::glTFMaterial() +{ +} + +glTFMaterial::~glTFMaterial() +{ +} + +void glTFMaterial::setDoublesided(bool value) +{ + m_doubleSided = value; +} + +bool glTFMaterial::getDoublesided() +{ + return m_doubleSided; +} + +void glTFMaterial::setAlphaMode(AlphaMode value) +{ + m_alphaMode = value; +} + +AlphaMode glTFMaterial::getAlphaMode() +{ + return m_alphaMode; +} + +void glTFMaterial::setAlphaCutOff(float value) +{ + m_alphaCutoff = value; +} + +float glTFMaterial::getAlphaCutOff() +{ + return m_alphaCutoff; +} + +TextureCoordSet* glTFMaterial::getTextureCoordSet() +{ + return m_texCoordSets; +} + +void glTFMaterial::setTextureCoordSet(TextureCoordSet* value) +{ + m_texCoordSets = value; +} + +PbrTextureExtension* glTFMaterial::getTextureExtension() +{ + return m_textureExtension; +} + +void glTFMaterial::setPbrTextureExtension(PbrTextureExtension* value) +{ + m_textureExtension = value; +} + +PbrBaseTexture* glTFMaterial::getPbrBaseTexture() +{ + return m_pbrBaseTexture; +} + +void glTFMaterial::setPbrBaseTexture(PbrBaseTexture* value) +{ + m_pbrBaseTexture = value; +} + +PbrWorkFlow* glTFMaterial::getPbrWorkFlow() +{ + return m_pbrWorkFlow; +} + +void glTFMaterial::setPbrWorkFlow() +{ + m_pbrWorkFlow; +} + +GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/gltf/glTFMaterial.h b/src/gltf/glTFMaterial.h new file mode 100644 index 0000000..1d02de0 --- /dev/null +++ b/src/gltf/glTFMaterial.h @@ -0,0 +1,66 @@ +#ifndef GLTFMATERIAL_H +#define GLTFMATERIAL_H + +#include "glTFModel_Marco.h" +#include "glTFModel_common.h" + +#include "glTFTexture.h" +#include "PbrTextureCoordSet.h" +#include "PbrTextureExtension.h" +#include "PbrBaseTexture.h" +#include "PbrWorkFlow.h" + +#include + +GLTFLOADER_NAMESPACE_BEGIN + +class glTFMaterial +{ +public: + glTFMaterial(); + ~glTFMaterial(); + + void setDoublesided(bool value); + bool getDoublesided(); + + void setAlphaMode(AlphaMode value); + AlphaMode getAlphaMode(); + + void setAlphaCutOff(float value); + float getAlphaCutOff(); + + + TextureCoordSet* getTextureCoordSet(); + void setTextureCoordSet(TextureCoordSet* value); + + PbrTextureExtension* getTextureExtension(); + void setPbrTextureExtension(PbrTextureExtension* value); + + PbrBaseTexture* getPbrBaseTexture(); + void setPbrBaseTexture(PbrBaseTexture* value); + + PbrWorkFlow* getPbrWorkFlow(); + void setPbrWorkFlow(); + +private: + + AlphaMode m_alphaMode = ALPHAMODE_OPAQUE; + float m_alphaCutoff = 1.0f; + + PbrBaseTexture* m_pbrBaseTexture; + bool m_doubleSided = false; + TextureCoordSet* m_texCoordSets; + PbrTextureExtension* m_textureExtension; + PbrWorkFlow* m_pbrWorkFlow; + + VkDescriptorSet m_descriptorSet = VK_NULL_HANDLE; + +}; + + + + + +GLTFLOADER_NAMESPACE_END + +#endif // !GLTFMATERIAL_H diff --git a/src/render/glTFMesh.cpp b/src/gltf/glTFMesh.cpp similarity index 73% rename from src/render/glTFMesh.cpp rename to src/gltf/glTFMesh.cpp index 8032e29..294aeef 100644 --- a/src/render/glTFMesh.cpp +++ b/src/gltf/glTFMesh.cpp @@ -38,6 +38,31 @@ void glTFMesh::setBoundingBox(glm::vec3 min, glm::vec3 max) m_boundingBox.setBoundingBox(min, max); } +void glTFMesh::setBoundingBox(glTFBoundingBox BoundingBox) +{ + m_boundingBox = BoundingBox; +} + +glTFBoundingBox glTFMesh::getBoundingBox() +{ + return m_boundingBox; +} + +void glTFMesh::setPrimitives(std::vector& primitives) +{ + m_primitives = primitives; +} + +std::vector glTFMesh::getPrimitives() +{ + return m_primitives; +} + +void glTFMesh::pushPrimitiveBack(glTFPrimitive* value) +{ + m_primitives.push_back(value); +} + VulkanBase::UniformBuffer glTFMesh::getUniformBuffer() { return m_uniformBuffer; diff --git a/src/render/glTFMesh.h b/src/gltf/glTFMesh.h similarity index 77% rename from src/render/glTFMesh.h rename to src/gltf/glTFMesh.h index 96e7ba2..a759183 100644 --- a/src/render/glTFMesh.h +++ b/src/gltf/glTFMesh.h @@ -23,6 +23,12 @@ public: ~glTFMesh(); void setBoundingBox(glm::vec3 min, glm::vec3 max); + void setBoundingBox(glTFBoundingBox BoundingBox); + glTFBoundingBox getBoundingBox(); + + void setPrimitives(std::vector& primitives); + std::vector getPrimitives(); + void pushPrimitiveBack(glTFPrimitive* value); VulkanBase::UniformBuffer getUniformBuffer(); void setUniformBlock(UniformBlock block); diff --git a/src/render/glTFModel.cpp b/src/gltf/glTFModel.cpp similarity index 99% rename from src/render/glTFModel.cpp rename to src/gltf/glTFModel.cpp index 5ff37d8..22b151e 100644 --- a/src/render/glTFModel.cpp +++ b/src/gltf/glTFModel.cpp @@ -1,4 +1,4 @@ - + //#pragma once /* #ifndef TINYGLTF_IMPLEMENTATION diff --git a/src/render/glTFModel.h b/src/gltf/glTFModel.h similarity index 100% rename from src/render/glTFModel.h rename to src/gltf/glTFModel.h diff --git a/src/render/glTFModel_Marco.h b/src/gltf/glTFModel_Marco.h similarity index 100% rename from src/render/glTFModel_Marco.h rename to src/gltf/glTFModel_Marco.h diff --git a/src/render/glTFModel_Common.h b/src/gltf/glTFModel_common.h similarity index 65% rename from src/render/glTFModel_Common.h rename to src/gltf/glTFModel_common.h index 816422f..4d86a88 100644 --- a/src/render/glTFModel_Common.h +++ b/src/gltf/glTFModel_common.h @@ -34,6 +34,23 @@ struct UniformBlock { float jointcount{ 0 }; }; +struct Vertex { + glm::vec3 pos; + glm::vec3 normal; + glm::vec2 uv0; + glm::vec2 uv1; + glm::vec4 joint0; + glm::vec4 weight0; + glm::vec4 color; +}; + +struct LoaderInfo { + uint32_t* indexBuffer; + Vertex* vertexBuffer; + size_t indexPos = 0; + size_t vertexPos = 0; +}; + GLTFLOADER_NAMESPACE_END diff --git a/src/render/glTFNode.cpp b/src/gltf/glTFNode.cpp similarity index 53% rename from src/render/glTFNode.cpp rename to src/gltf/glTFNode.cpp index 6c1ef36..a31df7e 100644 --- a/src/render/glTFNode.cpp +++ b/src/gltf/glTFNode.cpp @@ -33,6 +33,11 @@ glm::mat4 glTFNode::getMatrix() return localMatrix; } +void glTFNode::setMatrix(glm::mat4 value) +{ + m_matrix = value; +} + void glTFNode::update() { if (m_mesh) { @@ -76,6 +81,121 @@ glTFNode* glTFNode::getParent() return m_parent; } +void glTFNode::setBvh(glTFBoundingBox bvh) +{ + m_bvh = bvh; +} + +glTFBoundingBox glTFNode::getBvh() +{ + return m_bvh; +} + +void glTFNode::setMesh(glTFMesh* mesh) +{ + m_mesh = mesh; +} + +glTFMesh* glTFNode::getMesh() +{ + return m_mesh; +} + +void glTFNode::setAxisAlignedBoundingBox(glTFBoundingBox aabb) +{ + m_aabb = aabb; +} + +glTFBoundingBox glTFNode::getAxisAlignedBoundingBox() +{ + return m_aabb; +} + +void glTFNode::setChildren(std::vector& children) +{ + m_children = children; +} + +std::vector glTFNode::getChildren() +{ + return m_children; +} + +void glTFNode::pushChildrenBack(glTFNode* value) +{ + m_children.push_back(value); +} + +void glTFNode::setIndex(unsigned int index) +{ + m_index = index; +} + +unsigned int glTFNode::getIndex() +{ + return m_index; +} + +void glTFNode::setTranslation(glm::vec3 translation) +{ + m_translation = translation; +} + +glm::vec3 glTFNode::getTranslation() +{ + return m_translation; +} + +void glTFNode::setScale(glm::vec3 scaler) +{ + m_scale = scaler; +} + +glm::vec3 glTFNode::getScale() +{ + return m_scale; +} + +void glTFNode::setRotation(glm::quat rotation) +{ + m_rotation = rotation; +} + +glm::quat glTFNode::getRotation() +{ + return m_rotation; +} + +void glTFNode::setSkinIndex(unsigned int skinIndex) +{ + m_skinIndex = skinIndex; +} + +unsigned int glTFNode::getSkinIndex() +{ + return m_skinIndex; +} + +void glTFNode::setSkin(glTFSkin* skin) +{ + m_skin = skin; +} + +glTFSkin* glTFNode::getSkin() +{ + return m_skin; +} + +void glTFNode::setName(std::string value) +{ + m_name = value; +} + +std::string glTFNode::getName() +{ + return m_name; +} + GLTFLOADER_NAMESPACE_END diff --git a/src/gltf/glTFNode.h b/src/gltf/glTFNode.h new file mode 100644 index 0000000..dbccb3a --- /dev/null +++ b/src/gltf/glTFNode.h @@ -0,0 +1,89 @@ +#ifndef GLTFNODE_H +#define GLTFNODE_H + +#include "glTFModel_Marco.h" + +#include "glTFSkin.h" +#include "glTFMesh.h" +#include "glTFBoundingBox.h" + +#include +#include + +#include +#include + + +GLTFLOADER_NAMESPACE_BEGIN + +class glTFNode +{ +public: + glTFNode(); + ~glTFNode(); + + glm::mat4 getLocalMatrix(); + glm::mat4 getMatrix(); + void setMatrix(glm::mat4 value); + void update(); + + void setParent(glTFNode* parent); + glTFNode* getParent(); + + void setBvh(glTFBoundingBox bvh); + glTFBoundingBox getBvh(); + + void setMesh(glTFMesh* mesh); + glTFMesh* getMesh(); + + void setAxisAlignedBoundingBox(glTFBoundingBox aabb); + glTFBoundingBox getAxisAlignedBoundingBox(); + + void setChildren(std::vector& children); + std::vector getChildren(); + void pushChildrenBack(glTFNode* value); + + void setIndex(unsigned int index); + unsigned int getIndex(); + + void setTranslation(glm::vec3 translation); + glm::vec3 getTranslation(); + + void setScale(glm::vec3 scaler); + glm::vec3 getScale(); + + void setRotation(glm::quat rotation); + glm::quat getRotation(); + + void setSkinIndex(unsigned int skinIndex); + unsigned int getSkinIndex(); + + void setSkin(glTFSkin* skin); + glTFSkin* getSkin(); + + void setName(std::string value); + std::string getName(); + +private: + + glTFNode* m_parent; + unsigned int m_index; + std::vector m_children; + glm::mat4 m_matrix; + std::string m_name; + glTFMesh* m_mesh; + glTFSkin* m_skin; + unsigned int m_skinIndex = -1; + glm::vec3 m_translation; + glm::vec3 m_scale{ 1.0f }; + glm::quat m_rotation{}; + glTFBoundingBox m_bvh; + glTFBoundingBox m_aabb; + + +}; + + +GLTFLOADER_NAMESPACE_END + +#endif // !1 \ No newline at end of file diff --git a/src/render/glTFPrimitive.cpp b/src/gltf/glTFPrimitive.cpp similarity index 52% rename from src/render/glTFPrimitive.cpp rename to src/gltf/glTFPrimitive.cpp index c1e3571..ac58316 100644 --- a/src/render/glTFPrimitive.cpp +++ b/src/gltf/glTFPrimitive.cpp @@ -22,4 +22,30 @@ void glTFPrimitive::setBoundingBox(glm::vec3 min, glm::vec3 max) m_boundingBox.setBoundingBox(min, max); } +glTFBoundingBox glTFPrimitive::getBoundingBox() +{ + return m_boundingBox; +} + +void glTFPrimitive::setIndexCount(unsigned int indexCount) +{ + m_indexCount = indexCount; +} + +unsigned int glTFPrimitive::getIndexCount() +{ + return m_indexCount; +} + +void glTFPrimitive::setFirstIndex(unsigned int firstIndex) +{ + m_firstIndex = firstIndex; +} + +unsigned int glTFPrimitive::getFirstIndex() +{ + return m_firstIndex; +} + + GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/render/glTFPrimitive.h b/src/gltf/glTFPrimitive.h similarity index 67% rename from src/render/glTFPrimitive.h rename to src/gltf/glTFPrimitive.h index bdf17c5..c9e5de0 100644 --- a/src/render/glTFPrimitive.h +++ b/src/gltf/glTFPrimitive.h @@ -19,12 +19,19 @@ public: ~glTFPrimitive(); void setBoundingBox(glm::vec3 min, glm::vec3 max); + glTFBoundingBox getBoundingBox(); + + void setIndexCount(unsigned int indexCount); + unsigned int getIndexCount(); + + void setFirstIndex(unsigned int firstIndex); + unsigned int getFirstIndex(); private: - uint32_t m_firstIndex; - uint32_t m_indexCount; - uint32_t m_vertexCount; + unsigned int m_firstIndex; + unsigned int m_indexCount; + unsigned int m_vertexCount; glTFMaterial& m_material; bool m_hasIndices; glTFBoundingBox m_boundingBox; diff --git a/src/gltf/glTFSkin.cpp b/src/gltf/glTFSkin.cpp new file mode 100644 index 0000000..432688e --- /dev/null +++ b/src/gltf/glTFSkin.cpp @@ -0,0 +1,62 @@ +#include "glTFSkin.h" + +#include "glTFNode.h" + +GLTFLOADER_NAMESPACE_BEGIN + +glTFSkin::glTFSkin() +{ +} + +glTFSkin::~glTFSkin() +{ +} + +std::vector glTFSkin::getJoints() +{ + return m_joints; +} + +void glTFSkin::pushJointsBack(glTFNode* value) +{ + m_joints.push_back(value); +} + +std::vector glTFSkin::getInverseBindMatrices() +{ + return m_inverseBindMatrices; +} + +void glTFSkin::pushInverseBindMatrices(glm::mat4& value) +{ + m_inverseBindMatrices.push_back(value); +} + +void glTFSkin::setInverseBindMatrices(std::vector& value) +{ + m_inverseBindMatrices = value; +} + +void glTFSkin::setName(std::string& value) +{ + m_name = value; +} + +std::string glTFSkin::getName() +{ + return m_name; +} + +glTFNode* glTFSkin::getSkeletonRoot() +{ + return m_skeletonRoot; +} + +void glTFSkin::setSkeletonRoot(glTFNode* value) +{ + m_skeletonRoot = value; +} + + + +GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/render/glTFSkin.h b/src/gltf/glTFSkin.h similarity index 65% rename from src/render/glTFSkin.h rename to src/gltf/glTFSkin.h index 0e23dc7..620c29f 100644 --- a/src/render/glTFSkin.h +++ b/src/gltf/glTFSkin.h @@ -19,8 +19,18 @@ public: ~glTFSkin(); std::vector getJoints(); + void pushJointsBack(glTFNode* value); std::vector getInverseBindMatrices(); + void pushInverseBindMatrices(glm::mat4& value); + void setInverseBindMatrices(std::vector& value); + + void setName(std::string& value); + std::string getName(); + + glTFNode* getSkeletonRoot(); + void setSkeletonRoot(glTFNode* value); + private: std::string m_name; diff --git a/src/render/glTFTexture.cpp b/src/gltf/glTFTexture.cpp similarity index 100% rename from src/render/glTFTexture.cpp rename to src/gltf/glTFTexture.cpp diff --git a/src/render/glTFTexture.h b/src/gltf/glTFTexture.h similarity index 89% rename from src/render/glTFTexture.h rename to src/gltf/glTFTexture.h index 19680ec..29aa06c 100644 --- a/src/render/glTFTexture.h +++ b/src/gltf/glTFTexture.h @@ -31,9 +31,9 @@ private: VkImageLayout m_imageLayout; VkDeviceMemory m_deviceMemory; VkImageView m_view; - uint32_t m_width, m_height; - uint32_t m_mipLevels; - uint32_t m_layerCount; + unsigned int m_width, m_height; + unsigned int m_mipLevels; + unsigned int m_layerCount; VkDescriptorImageInfo m_descriptor; VkSampler m_sampler; }; diff --git a/src/pbr/PbrBaseTexture.cpp b/src/pbr/PbrBaseTexture.cpp new file mode 100644 index 0000000..0ecc393 --- /dev/null +++ b/src/pbr/PbrBaseTexture.cpp @@ -0,0 +1,104 @@ +#include "PbrBaseTexture.h" + +GLTFLOADER_NAMESPACE_BEGIN + +PbrBaseTexture::PbrBaseTexture() +{ +} + +PbrBaseTexture::~PbrBaseTexture() +{ +} + +void PbrBaseTexture::setBaseColorTexture(glTFTexture* value) +{ + m_baseColorTexture = value; +} + +glTFTexture* PbrBaseTexture::getBaseColorTexture() +{ + return m_baseColorTexture; +} + +void PbrBaseTexture::setBaseColorFactor(glm::vec4 value) +{ + m_baseColorFactor = value; +} + +glm::vec4 PbrBaseTexture::getBaseColorFactor() +{ + return m_baseColorFactor; +} + +void PbrBaseTexture::setNormalTexture(glTFTexture* value) +{ + m_normalTexture = value; +} + +glTFTexture* PbrBaseTexture::getNormalTexture() +{ + return m_normalTexture; +} + +void PbrBaseTexture::setMetallicRoughnessTexture(glTFTexture* value) +{ + m_metallicRoughnessTexture = value; +} + +glTFTexture* PbrBaseTexture::getMetalicRoughnessTexture() +{ + return m_metallicRoughnessTexture; +} + +void PbrBaseTexture::setMetallicFactor(float value) +{ + m_metallicFactor = value; +} + +float PbrBaseTexture::getMetallicFactor() +{ + return m_metallicFactor; +} + +void PbrBaseTexture::setRoughnessFactor(float value) +{ + m_roughnessFactor = value; +} + +float PbrBaseTexture::getRoughnessFactor() +{ + return m_roughnessFactor; +} + +void PbrBaseTexture::setEmissiveTexture(glTFTexture* value) +{ + m_emissiveTexture = value; +} + +glTFTexture* PbrBaseTexture::getEmissiveTexture() +{ + return m_emissiveTexture; +} + + +void PbrBaseTexture::setEmissiveFactor(glm::vec4 value) +{ + m_emissiveFactor = value; +} + +glm::vec4 PbrBaseTexture::getEmissiveFactor() +{ + return m_emissiveFactor; +} + +void PbrBaseTexture::setOcclusionTexture(glTFTexture* value) +{ + m_occlusionTexture = value; +} + +glTFTexture* PbrBaseTexture::getOcclusionTexture() +{ + return m_occlusionTexture; +} + +GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/pbr/PbrBaseTexture.h b/src/pbr/PbrBaseTexture.h new file mode 100644 index 0000000..b6e8b9d --- /dev/null +++ b/src/pbr/PbrBaseTexture.h @@ -0,0 +1,69 @@ +#ifndef PBRBASETEXTURE_H +#define PBRBASETEXTURE_H + +/// todo: 分离为单独的PBR命名空间 +#include "glTFModel_Marco.h" + +#include "glTFTexture.h" + +#include + +GLTFLOADER_NAMESPACE_BEGIN + +/// @brief todo:拆分texture基类摆脱gltf限制 +class PbrBaseTexture +{ +public: + PbrBaseTexture(); + ~PbrBaseTexture(); + + void setBaseColorTexture(glTFTexture* value); + glTFTexture* getBaseColorTexture(); + + void setBaseColorFactor(glm::vec4 value); + glm::vec4 getBaseColorFactor(); + + void setNormalTexture(glTFTexture* value); + glTFTexture* getNormalTexture(); + + void setMetallicRoughnessTexture(glTFTexture* value); + glTFTexture* getMetalicRoughnessTexture(); + + void setMetallicFactor(float value); + float getMetallicFactor(); + + void setRoughnessFactor(float value); + float getRoughnessFactor(); + + void setEmissiveTexture(glTFTexture* value); + glTFTexture* getEmissiveTexture(); + + void setEmissiveFactor(glm::vec4 value); + glm::vec4 getEmissiveFactor(); + + void setOcclusionTexture(glTFTexture* value); + glTFTexture* getOcclusionTexture(); + +private: + + glTFTexture* m_baseColorTexture = nullptr; + glm::vec4 m_baseColorFactor = glm::vec4(1.0f); + + glTFTexture* m_normalTexture = nullptr; + + glTFTexture* m_metallicRoughnessTexture = nullptr; + float m_metallicFactor = 1.0f; + float m_roughnessFactor = 1.0f; + + glTFTexture* m_emissiveTexture = nullptr; + glm::vec4 m_emissiveFactor = glm::vec4(1.0f); + + glTFTexture* m_occlusionTexture = nullptr; + +}; + + + +GLTFLOADER_NAMESPACE_END + +#endif // !PBRBASETEXTURE_H diff --git a/src/pbr/PbrTextureCoordSet.cpp b/src/pbr/PbrTextureCoordSet.cpp new file mode 100644 index 0000000..a60d30c --- /dev/null +++ b/src/pbr/PbrTextureCoordSet.cpp @@ -0,0 +1,74 @@ +#include "TextureCoordSet.h" + + +VULKANBASE_NAMESPACE_BEGIN + +TextureCoordSet::TextureCoordSet() +{ +} + +TextureCoordSet::~TextureCoordSet() +{ +} + +void TextureCoordSet::setBaseColor(unsigned char value) +{ + m_baseColor = value; +} + +unsigned char TextureCoordSet::getBaseColor() +{ + return m_baseColor; +} + +void TextureCoordSet::setMetallicRoughness(unsigned char value) +{ + m_metallicRoughness = value; +} + +unsigned char TextureCoordSet::getMetallicRoughness() +{ + return m_metallicRoughness; +} + +void TextureCoordSet::setSpecularGlossiness(unsigned char value) +{ + m_specularGlossiness = value; +} + +unsigned char TextureCoordSet::getSpecularGlossiness() +{ + return m_specularGlossiness; +} + +void TextureCoordSet::setNormal(unsigned char value) +{ + m_normal = value; +} + +unsigned char TextureCoordSet::getNormal() +{ + return m_normal; +} + +void TextureCoordSet::setOcclusion(unsigned char value) +{ + m_occlusion = value; +} + +unsigned char TextureCoordSet::getOcclusion() +{ + return m_occlusion; +} + +void TextureCoordSet::setEmissive(unsigned char value) +{ + m_emissive = value; +} + +unsigned char TextureCoordSet::getEmissive() +{ + return m_emissive; +} + +VULKANBASE_NAMESPACE_END \ No newline at end of file diff --git a/src/pbr/PbrTextureCoordSet.h b/src/pbr/PbrTextureCoordSet.h new file mode 100644 index 0000000..fc9ff36 --- /dev/null +++ b/src/pbr/PbrTextureCoordSet.h @@ -0,0 +1,47 @@ +#ifndef TESTURECOORDSET_H +#define TESTURECOORDSET_H + +#include "glTFModel_Marco.h" + +GLTFLOADER_NAMESPACE_BEGIN + +/// @brief 材质信息集合 +class TextureCoordSet +{ +public: + TextureCoordSet(); + ~TextureCoordSet(); + + void setBaseColor(unsigned char value); + unsigned char getBaseColor(); + + void setMetallicRoughness(unsigned char value); + unsigned char getMetallicRoughness(); + + void setSpecularGlossiness(unsigned char value); + unsigned char getSpecularGlossiness(); + + void setNormal(unsigned char value); + unsigned char getNormal(); + + void setOcclusion(unsigned char value); + unsigned char getOcclusion(); + + void setEmissive(unsigned char value); + unsigned char getEmissive(); + +private: + + unsigned char m_baseColor = 0; + unsigned char m_metallicRoughness = 0; + unsigned char m_specularGlossiness = 0; + unsigned char m_normal = 0; + unsigned char m_occlusion = 0; + unsigned char m_emissive = 0; + +}; + +GLTFLOADER_NAMESPACE_END + + +#endif // !TestureCoordSet_h \ No newline at end of file diff --git a/src/pbr/PbrTextureExtension.cpp b/src/pbr/PbrTextureExtension.cpp new file mode 100644 index 0000000..bdadd25 --- /dev/null +++ b/src/pbr/PbrTextureExtension.cpp @@ -0,0 +1,55 @@ +#include "PbrTextureExtension.h" + +GLTFLOADER_NAMESPACE_BEGIN + +PbrTextureExtension::PbrTextureExtension() +{ +} + +PbrTextureExtension::~PbrTextureExtension() +{ +} + +void PbrTextureExtension::setSpecularGlossinessTexture(glTFTexture* _texture) +{ + m_specularGlossinessTexture = _texture; +} + +glTFTexture* PbrTextureExtension::getSpecularGlossinessTexture() +{ + return m_specularGlossinessTexture; +} + +void PbrTextureExtension::setDiffuseTexture(glTFTexture* _texture) +{ + m_diffuseTexture = _texture; +} + +glTFTexture* PbrTextureExtension::getDiffuseTexture() +{ + return m_diffuseTexture; +} + +void PbrTextureExtension::setDiffuseFactor(glm::vec4 value) +{ + m_diffuseFactor = value; +} + +glm::vec4 PbrTextureExtension::getDiffuseFactor() +{ + return m_diffuseFactor; +} + +void PbrTextureExtension::setSpecularFactor(glm::vec3 value) +{ + m_specularFactor = value; +} + +glm::vec3 PbrTextureExtension::getSpecularFactor() +{ + return m_specularFactor; +} + + + +GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/pbr/PbrTextureExtension.h b/src/pbr/PbrTextureExtension.h new file mode 100644 index 0000000..05eaf5c --- /dev/null +++ b/src/pbr/PbrTextureExtension.h @@ -0,0 +1,51 @@ +#ifndef PBRTEXTUREEXTENSION_H +#define PBRTEXTUREEXTENSION_H + +#include "glTFModel_Marco.h" + +#include "glTFTexture.h" + +#include + + +GLTFLOADER_NAMESPACE_BEGIN + +class PbrTextureExtension +{ +public: + PbrTextureExtension(); + ~PbrTextureExtension(); + + void setSpecularGlossinessTexture(glTFTexture* _texture); + glTFTexture* getSpecularGlossinessTexture(); + + void setDiffuseTexture(glTFTexture* _texture); + glTFTexture* getDiffuseTexture(); + + void setDiffuseFactor(glm::vec4 value); + glm::vec4 getDiffuseFactor(); + + void setSpecularFactor(glm::vec3 value); + glm::vec3 getSpecularFactor(); + + +private: + + glTFTexture* m_specularGlossinessTexture = nullptr; + glTFTexture* m_diffuseTexture = nullptr; + glm::vec4 m_diffuseFactor = glm::vec4(1.0f); + glm::vec3 m_specularFactor = glm::vec3(0.0f); + +}; + + + + + +GLTFLOADER_NAMESPACE_END + + + + +#endif // !PbrTextureExtension_h + diff --git a/src/pbr/PbrWorkFlow.cpp b/src/pbr/PbrWorkFlow.cpp new file mode 100644 index 0000000..2852124 --- /dev/null +++ b/src/pbr/PbrWorkFlow.cpp @@ -0,0 +1,35 @@ +#include "PbrWorkFlow.h" + +GLTFLOADER_NAMESPACE_BEGIN + +PbrWorkFlow::PbrWorkFlow() +{ +} + +PbrWorkFlow::~PbrWorkFlow() +{ +} + +void PbrWorkFlow::setMetallicRoughness(bool value) +{ + m_metallicRoughness = value; +} + +bool PbrWorkFlow::getMetallicRoughness() +{ + return m_metallicRoughness; +} + +void PbrWorkFlow::setSpecularGlossiness(bool value) +{ + m_specularGlossiness = value; +} + +bool PbrWorkFlow::getSpecularGlossiness() +{ + return m_specularGlossiness; +} + + + +GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/pbr/PbrWorkFlow.h b/src/pbr/PbrWorkFlow.h new file mode 100644 index 0000000..8594466 --- /dev/null +++ b/src/pbr/PbrWorkFlow.h @@ -0,0 +1,33 @@ +#ifndef PBRWORKFLOW_H +#define PBRWORKFLOW_H + +#include "glTFModel_Marco.h" + +GLTFLOADER_NAMESPACE_BEGIN + +class PbrWorkFlow +{ +public: + PbrWorkFlow(); + ~PbrWorkFlow(); + + void setMetallicRoughness(bool value); + bool getMetallicRoughness(); + + void setSpecularGlossiness(bool value); + bool getSpecularGlossiness(); + +private: + + bool m_metallicRoughness = true; + bool m_specularGlossiness = false; + +}; + + + + +GLTFLOADER_NAMESPACE_END + + +#endif // !PBRWORKFLOW_H diff --git a/src/render/glTFAnimation.cpp b/src/render/glTFAnimation.cpp deleted file mode 100644 index 4fd780f..0000000 --- a/src/render/glTFAnimation.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "glTFAnimation.h" - - -GLTFLOADER_NAMESPACE_BEGIN - -glTFAnimation::glTFAnimation() -{ -} - -glTFAnimation::~glTFAnimation() -{ -} - -GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/render/glTFAnimation.h b/src/render/glTFAnimation.h deleted file mode 100644 index 95419ca..0000000 --- a/src/render/glTFAnimation.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef GLTFANIMATION_H -#define GLTFANIMATION_H - -#include "glTFModel_Marco.h" - - -#include "glTFAnimationChannel.h" -#include "glTFAnimationSampler.h" - -#include -#include -#include - -GLTFLOADER_NAMESPACE_BEGIN - -class glTFAnimation -{ -public: - glTFAnimation(); - ~glTFAnimation(); - -private: - std::string name; - std::vector samplers; - std::vector channels; - float start = std::numeric_limits::max(); - float end = std::numeric_limits::min(); -}; - - -GLTFLOADER_NAMESPACE_END - -#endif // !GLTFANIMATION diff --git a/src/render/glTFAnimationChannel.cpp b/src/render/glTFAnimationChannel.cpp deleted file mode 100644 index 0bbf027..0000000 --- a/src/render/glTFAnimationChannel.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "glTFAnimationChannel.h" - -GLTFLOADER_NAMESPACE_BEGIN - -glTFAnimationChannel::glTFAnimationChannel() -{ -} - -glTFAnimationChannel::~glTFAnimationChannel() -{ -} - -GLTFLOADER_NAMESPACE_END - - diff --git a/src/render/glTFAnimationSampler.cpp b/src/render/glTFAnimationSampler.cpp deleted file mode 100644 index 2cc8b31..0000000 --- a/src/render/glTFAnimationSampler.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "glTFAnimationSampler.h" - - -GLTFLOADER_NAMESPACE_BEGIN - -glTFAnimationSampler::glTFAnimationSampler() -{ -} - -glTFAnimationSampler::~glTFAnimationSampler() -{ -} - - -GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/render/glTFAnimationSampler.h b/src/render/glTFAnimationSampler.h deleted file mode 100644 index 858a996..0000000 --- a/src/render/glTFAnimationSampler.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef GLTFANIMATIONSAMPLER_H -#define GLTFANIMATIONSAMPLER_H - -#include "glTFModel_Marco.h" -#include "glTFModel_common.h" - - -#include - -GLTFLOADER_NAMESPACE_BEGIN - -class glTFAnimationSampler -{ -public: - glTFAnimationSampler(); - ~glTFAnimationSampler(); - -private: - AnimationInterpolationType interpolation; - std::vector inputs; - std::vector outputsVec4; -}; - - - -GLTFLOADER_NAMESPACE_END - -#endif // !GLTFANIMATIONSAMPLER_H diff --git a/src/render/glTFMaterial.cpp b/src/render/glTFMaterial.cpp deleted file mode 100644 index 34d5053..0000000 --- a/src/render/glTFMaterial.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "glTFMaterial.h" - - -GLTFLOADER_NAMESPACE_BEGIN - -glTFMaterial::glTFMaterial() -{ -} - -glTFMaterial::~glTFMaterial() -{ -} - - - - - - -GLTFLOADER_NAMESPACE_END \ No newline at end of file diff --git a/src/render/glTFMaterial.h b/src/render/glTFMaterial.h deleted file mode 100644 index a8f7214..0000000 --- a/src/render/glTFMaterial.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef GLTFMATERIAL_H -#define GLTFMATERIAL_H - -#include "glTFModel_Marco.h" - -#include "glTFModel_common.h" - -#include "glTFTexture.h" - -#include - -GLTFLOADER_NAMESPACE_BEGIN - -class glTFMaterial -{ -public: - glTFMaterial(); - ~glTFMaterial(); - -private: - - AlphaMode m_alphaMode = ALPHAMODE_OPAQUE; - float m_alphaCutoff = 1.0f; - float m_metallicFactor = 1.0f; - float m_roughnessFactor = 1.0f; - glm::vec4 m_baseColorFactor = glm::vec4(1.0f); - glm::vec4 m_emissiveFactor = glm::vec4(1.0f); - glTFTexture* m_baseColorTexture = nullptr; - glTFTexture* m_metallicRoughnessTexture = nullptr; - glTFTexture* m_normalTexture = nullptr; - glTFTexture* m_occlusionTexture = nullptr; - glTFTexture* m_emissiveTexture = nullptr; - bool m_doubleSided = false; - struct TexCoordSets { - uint8_t baseColor = 0; - uint8_t metallicRoughness = 0; - uint8_t specularGlossiness = 0; - uint8_t normal = 0; - uint8_t occlusion = 0; - uint8_t emissive = 0; - } m_texCoordSets; - struct Extension { - glTFTexture* specularGlossinessTexture = nullptr; - glTFTexture* diffuseTexture = nullptr; - glm::vec4 diffuseFactor = glm::vec4(1.0f); - glm::vec3 specularFactor = glm::vec3(0.0f); - } m_extension; - struct PbrWorkflows { - bool metallicRoughness = true; - bool specularGlossiness = false; - } m_pbrWorkflows; - VkDescriptorSet m_descriptorSet = VK_NULL_HANDLE; - -}; - - - - - -GLTFLOADER_NAMESPACE_END - -#endif // !GLTFMATERIAL_H diff --git a/src/render/glTFNode.h b/src/render/glTFNode.h deleted file mode 100644 index ff61a37..0000000 --- a/src/render/glTFNode.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef GLTFNODE_H -#define GLTFNODE_H - -#include "glTFModel_Marco.h" - -#include "glTFSkin.h" -#include "glTFMesh.h" -#include "glTFBoundingBox.h" - -#include -#include - -#include -#include - - -GLTFLOADER_NAMESPACE_BEGIN - -class glTFNode -{ -public: - glTFNode(); - ~glTFNode(); - - glm::mat4 getLocalMatrix(); - glm::mat4 getMatrix(); - void update(); - - void setParent(glTFNode* parent); - glTFNode* getParent(); - -private: - - glTFNode* m_parent; - uint32_t m_index; - std::vector m_children; - glm::mat4 m_matrix; - std::string m_name; - glTFMesh* m_mesh; - glTFSkin* m_skin; - int32_t m_skinIndex = -1; - glm::vec3 m_translation; - glm::vec3 m_scale{ 1.0f }; - glm::quat m_rotation{}; - glTFBoundingBox m_bvh; - glTFBoundingBox m_aabb; - - -}; - - -GLTFLOADER_NAMESPACE_END - -#endif // !1 \ No newline at end of file diff --git a/src/render/glTFSkin.cpp b/src/render/glTFSkin.cpp deleted file mode 100644 index f1bb83e..0000000 --- a/src/render/glTFSkin.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "glTFSkin.h" - -#include "glTFNode.h" - -GLTFLOADER_NAMESPACE_BEGIN - -glTFSkin::glTFSkin() -{ -} - -glTFSkin::~glTFSkin() -{ -} - -std::vector glTFSkin::getJoints() -{ - return m_joints; -} - -std::vector glTFSkin::getInverseBindMatrices() -{ - return m_inverseBindMatrices; -} - - - -GLTFLOADER_NAMESPACE_END \ No newline at end of file