完成初步gltf重构
parent
909f9eb57a
commit
f42fbae8e9
|
@ -9,30 +9,34 @@ set(MAIN_FILE
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GLTF_MODEL_LOADER
|
set(GLTF_MODEL_LOADER
|
||||||
"${PLUMAGE_RENDER}/glTFModel_Marco.h"
|
"gltf/glTFModel_Marco.h"
|
||||||
"${PLUMAGE_RENDER}/glTFModel_common.h"
|
"gltf/glTFModel_common.h"
|
||||||
"${PLUMAGE_RENDER}/glTFBoundingBox.h"
|
"gltf/glTFBoundingBox.h"
|
||||||
"${PLUMAGE_RENDER}/glTFBoundingBox.cpp"
|
"gltf/glTFBoundingBox.cpp"
|
||||||
"${PLUMAGE_RENDER}/glTFTexture.h"
|
"gltf/glTFTexture.h"
|
||||||
"${PLUMAGE_RENDER}/glTFTexture.cpp"
|
"gltf/glTFTexture.cpp"
|
||||||
"${PLUMAGE_RENDER}/glTFModel.h"
|
"gltf/glTFModel.h"
|
||||||
"${PLUMAGE_RENDER}/glTFModel.cpp"
|
"gltf/glTFModel.cpp"
|
||||||
"${PLUMAGE_RENDER}/glTFMaterial.h"
|
"gltf/glTFMaterial.h"
|
||||||
"${PLUMAGE_RENDER}/glTFMaterial.cpp"
|
"gltf/glTFMaterial.cpp"
|
||||||
"render/glTFPrimitive.h"
|
"gltf/glTFPrimitive.h"
|
||||||
"${PLUMAGE_RENDER}/glTFPrimitive.cpp"
|
"gltf/glTFPrimitive.cpp"
|
||||||
"render/glTFMesh.h"
|
"gltf/glTFMesh.h"
|
||||||
"render/glTFMesh.cpp"
|
"gltf/glTFMesh.cpp"
|
||||||
"render/glTFSkin.h"
|
"gltf/glTFSkin.h"
|
||||||
"render/glTFSkin.cpp"
|
"gltf/glTFSkin.cpp"
|
||||||
"render/glTFNode.h"
|
"gltf/glTFNode.h"
|
||||||
"render/glTFNode.cpp"
|
"gltf/glTFNode.cpp"
|
||||||
"render/glTFAnimationChannel.h"
|
"gltf/glTFAnimationChannel.h"
|
||||||
"render/glTFAnimationChannel.cpp"
|
"gltf/glTFAnimationChannel.cpp"
|
||||||
"render/glTFAnimationSampler.h"
|
"gltf/glTFAnimationSampler.h"
|
||||||
"render/glTFAnimationSampler.cpp"
|
"gltf/glTFAnimationSampler.cpp"
|
||||||
|
"gltf/glTFAnimation.h"
|
||||||
|
"gltf/glTFAnimation.cpp"
|
||||||
|
"gltf/glTFMainModel.h"
|
||||||
|
"gltf/glTFMainModel.cpp"
|
||||||
|
|
||||||
"render/glTFAnimation.h" "render/glTFAnimation.cpp")
|
)
|
||||||
|
|
||||||
set(VULKAN_BASE
|
set(VULKAN_BASE
|
||||||
"${PLUMAGE_RENDER}/VulkanBase_Marco.h"
|
"${PLUMAGE_RENDER}/VulkanBase_Marco.h"
|
||||||
|
@ -41,7 +45,13 @@ set(VULKAN_BASE
|
||||||
"${PLUMAGE_RENDER}/VulkanDevice.cpp"
|
"${PLUMAGE_RENDER}/VulkanDevice.cpp"
|
||||||
"${PLUMAGE_RENDER}/VulkanTextureSampler.h"
|
"${PLUMAGE_RENDER}/VulkanTextureSampler.h"
|
||||||
"${PLUMAGE_RENDER}/VulkanTextureSampler.cpp"
|
"${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
|
# wayland requires additional source files
|
||||||
IF(USE_WAYLAND_WSI)
|
IF(USE_WAYLAND_WSI)
|
||||||
|
@ -71,6 +81,12 @@ include_directories(${3rdParty_vulkan_path})
|
||||||
include_directories(${lib_base_path})
|
include_directories(${lib_base_path})
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: 拆分动态库
|
||||||
|
include_directories(gltf)
|
||||||
|
include_directories(pbr)
|
||||||
|
include_directories(render)
|
||||||
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_executable(${RenderName} WIN32 ${SHADERS_GLSL} ${SHADERS_HLSL}
|
add_executable(${RenderName} WIN32 ${SHADERS_GLSL} ${SHADERS_HLSL}
|
||||||
${MAIN_FILE}
|
${MAIN_FILE}
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
#include "glTFAnimation.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
GLTFLOADER_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
glTFAnimation::glTFAnimation()
|
||||||
|
{
|
||||||
|
m_start = std::numeric_limits<float>::max();
|
||||||
|
m_end = std::numeric_limits<float>::min();
|
||||||
|
}
|
||||||
|
|
||||||
|
glTFAnimation::~glTFAnimation()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFAnimation::setChannels(std::vector<glTFAnimationChannel>& value)
|
||||||
|
{
|
||||||
|
m_channels = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glTFAnimationChannel> glTFAnimation::getChannels()
|
||||||
|
{
|
||||||
|
return m_channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFAnimation::pushChannelsBack(glTFAnimationChannel value)
|
||||||
|
{
|
||||||
|
m_channels.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFAnimation::setSamplers(std::vector<glTFAnimationSampler>& value)
|
||||||
|
{
|
||||||
|
m_samplers = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glTFAnimationSampler> 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
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef GLTFANIMATION_H
|
||||||
|
#define GLTFANIMATION_H
|
||||||
|
|
||||||
|
#include "glTFModel_Marco.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "glTFAnimationChannel.h"
|
||||||
|
#include "glTFAnimationSampler.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
GLTFLOADER_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class glTFAnimation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
glTFAnimation();
|
||||||
|
~glTFAnimation();
|
||||||
|
|
||||||
|
void setChannels(std::vector<glTFAnimationChannel>& value);
|
||||||
|
std::vector<glTFAnimationChannel> getChannels();
|
||||||
|
void pushChannelsBack(glTFAnimationChannel value);
|
||||||
|
|
||||||
|
void setSamplers(std::vector<glTFAnimationSampler>& value);
|
||||||
|
std::vector<glTFAnimationSampler> 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<glTFAnimationSampler> m_samplers;
|
||||||
|
std::vector<glTFAnimationChannel> m_channels;
|
||||||
|
float m_start;
|
||||||
|
float m_end;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
GLTFLOADER_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // !GLTFANIMATION
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,20 @@ public:
|
||||||
glTFAnimationChannel();
|
glTFAnimationChannel();
|
||||||
~glTFAnimationChannel();
|
~glTFAnimationChannel();
|
||||||
|
|
||||||
|
void setSamplerIndex(unsigned int samplerIndex);
|
||||||
|
unsigned int getSamplerIndex();
|
||||||
|
|
||||||
|
void setAnimationPathType(AnimationPathType pathType);
|
||||||
|
AnimationPathType getAnimationPathType();
|
||||||
|
|
||||||
|
void setNode(glTFNode* node);
|
||||||
|
glTFNode* getNode();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
AnimationPathType path;
|
AnimationPathType m_pathType;
|
||||||
glTFNode* node;
|
glTFNode* m_node;
|
||||||
uint32_t samplerIndex;
|
unsigned int m_samplerIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
#include "glTFAnimationSampler.h"
|
||||||
|
|
||||||
|
|
||||||
|
GLTFLOADER_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
glTFAnimationSampler::glTFAnimationSampler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
glTFAnimationSampler::~glTFAnimationSampler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFAnimationSampler::setOutputsVec4(std::vector<glm::vec4>& value)
|
||||||
|
{
|
||||||
|
m_outputsVec4 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glm::vec4> glTFAnimationSampler::getOutputsVec4()
|
||||||
|
{
|
||||||
|
return m_outputsVec4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFAnimationSampler::pushOutputsVec4Back(glm::vec4 value)
|
||||||
|
{
|
||||||
|
m_outputsVec4.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFAnimationSampler::setInputs(std::vector<float>& inputs)
|
||||||
|
{
|
||||||
|
m_inputs = inputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> 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
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef GLTFANIMATIONSAMPLER_H
|
||||||
|
#define GLTFANIMATIONSAMPLER_H
|
||||||
|
|
||||||
|
#include "glTFModel_Marco.h"
|
||||||
|
#include "glTFModel_common.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
GLTFLOADER_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class glTFAnimationSampler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
glTFAnimationSampler();
|
||||||
|
~glTFAnimationSampler();
|
||||||
|
|
||||||
|
void setOutputsVec4(std::vector<glm::vec4>& value);
|
||||||
|
std::vector<glm::vec4> getOutputsVec4();
|
||||||
|
void pushOutputsVec4Back(glm::vec4 value);
|
||||||
|
|
||||||
|
void setInputs(std::vector<float>& inputs);
|
||||||
|
std::vector<float> getInputs();
|
||||||
|
void pushInputBack(float value);
|
||||||
|
|
||||||
|
void setAnimationInterpolationType(AnimationInterpolationType interpolationType);
|
||||||
|
AnimationInterpolationType getAnimationInterpolationType();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AnimationInterpolationType m_interpolationType;
|
||||||
|
std::vector<float> m_inputs;
|
||||||
|
std::vector<glm::vec4> m_outputsVec4;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GLTFLOADER_NAMESPACE_END
|
||||||
|
|
||||||
|
#endif // !GLTFANIMATIONSAMPLER_H
|
|
@ -4,14 +4,14 @@ GLTFLOADER_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
|
||||||
glTFBoundingBox::glTFBoundingBox()
|
glTFBoundingBox::glTFBoundingBox()
|
||||||
: m_isValid(true)
|
: m_valid(true)
|
||||||
, m_min(glm::vec3(0,0,0))
|
, m_min(glm::vec3(0,0,0))
|
||||||
, m_max(glm::vec3(1,1,1))
|
, m_max(glm::vec3(1,1,1))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
glTFBoundingBox::glTFBoundingBox(glm::vec3 min, glm::vec3 max)
|
glTFBoundingBox::glTFBoundingBox(glm::vec3 min, glm::vec3 max)
|
||||||
: m_isValid(true)
|
: m_valid(true)
|
||||||
, m_min(min)
|
, m_min(min)
|
||||||
, m_max(max)
|
, m_max(max)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,37 @@ void glTFBoundingBox::setBoundingBox(glm::vec3 min, glm::vec3 max)
|
||||||
{
|
{
|
||||||
m_min = min;
|
m_min = min;
|
||||||
m_max = max;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,20 @@ public:
|
||||||
|
|
||||||
void setBoundingBox(glm::vec3 min, glm::vec3 max);
|
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:
|
private:
|
||||||
|
|
||||||
glm::vec3 m_min;
|
glm::vec3 m_min;
|
||||||
glm::vec3 m_max;
|
glm::vec3 m_max;
|
||||||
bool m_isValid = false;
|
bool m_valid = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,938 @@
|
||||||
|
#include "glTFMainModel.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <VulkanTools.h>
|
||||||
|
|
||||||
|
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<uint32_t>(loaderInfo.vertexPos);
|
||||||
|
uint32_t indexStart = static_cast<uint32_t>(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<const float*>(&(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<uint32_t>(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<const float*>(&(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<const float*>(&(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<const float*>(&(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<const float*>(&(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<const float*>(&(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<const uint16_t*>(bufferJoints);
|
||||||
|
vert.joint0 = glm::vec4(glm::make_vec4(&buf[v * jointByteStride]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: {
|
||||||
|
const uint8_t* buf = static_cast<const uint8_t*>(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<uint32_t>(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<const uint32_t*>(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<const uint16_t*>(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<const uint8_t*>(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<glm::mat4> 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<float>(mat.values["roughnessFactor"].Factor()));
|
||||||
|
}
|
||||||
|
if (mat.values.find("metallicFactor") != mat.values.end()) {
|
||||||
|
material.getPbrBaseTexture()->setMetallicFactor(static_cast<float>(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<float>(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<int>()]);
|
||||||
|
auto texCoordSet = ext->second.Get("specularGlossinessTexture").Get("texCoord");
|
||||||
|
material.getTextureCoordSet()->setSpecularGlossiness(texCoordSet.Get<int>());
|
||||||
|
material.getPbrWorkFlow()->setSpecularGlossiness(true);
|
||||||
|
}
|
||||||
|
if (ext->second.Has("diffuseTexture")) {
|
||||||
|
auto index = ext->second.Get("diffuseTexture").Get("index");
|
||||||
|
material.getTextureExtension()->setDiffuseTexture(&m_textures[index.Get<int>()]);
|
||||||
|
}
|
||||||
|
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<double>() : (float)val.Get<int>();
|
||||||
|
}
|
||||||
|
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<double>() : (float)val.Get<int>();
|
||||||
|
}
|
||||||
|
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<const float*>(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<const glm::vec3*>(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<const glm::vec4*>(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<uint32_t>(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<float> 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<glm::vec4> 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<glm::vec4> 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<glm::vec4> 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
|
||||||
|
|
||||||
|
|
|
@ -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 <glm/glm.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<glTFNode*> m_nodes;
|
||||||
|
std::vector<glTFNode*> m_linearNodes;
|
||||||
|
|
||||||
|
std::vector<glTFSkin*> m_skins;
|
||||||
|
|
||||||
|
std::vector<glTFTexture> m_textures;
|
||||||
|
std::vector<VulkanBase::VulkanTextureSampler> m_textureSamplers;
|
||||||
|
std::vector<glTFMaterial> m_materials;
|
||||||
|
std::vector<glTFAnimation> m_animations;
|
||||||
|
std::vector<std::string> 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
|
|
@ -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
|
|
@ -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 <glm/glm.hpp>
|
||||||
|
|
||||||
|
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
|
|
@ -38,6 +38,31 @@ void glTFMesh::setBoundingBox(glm::vec3 min, glm::vec3 max)
|
||||||
m_boundingBox.setBoundingBox(min, 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<glTFPrimitive*>& primitives)
|
||||||
|
{
|
||||||
|
m_primitives = primitives;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glTFPrimitive*> glTFMesh::getPrimitives()
|
||||||
|
{
|
||||||
|
return m_primitives;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFMesh::pushPrimitiveBack(glTFPrimitive* value)
|
||||||
|
{
|
||||||
|
m_primitives.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
VulkanBase::UniformBuffer glTFMesh::getUniformBuffer()
|
VulkanBase::UniformBuffer glTFMesh::getUniformBuffer()
|
||||||
{
|
{
|
||||||
return m_uniformBuffer;
|
return m_uniformBuffer;
|
|
@ -23,6 +23,12 @@ public:
|
||||||
~glTFMesh();
|
~glTFMesh();
|
||||||
|
|
||||||
void setBoundingBox(glm::vec3 min, glm::vec3 max);
|
void setBoundingBox(glm::vec3 min, glm::vec3 max);
|
||||||
|
void setBoundingBox(glTFBoundingBox BoundingBox);
|
||||||
|
glTFBoundingBox getBoundingBox();
|
||||||
|
|
||||||
|
void setPrimitives(std::vector<glTFPrimitive*>& primitives);
|
||||||
|
std::vector<glTFPrimitive*> getPrimitives();
|
||||||
|
void pushPrimitiveBack(glTFPrimitive* value);
|
||||||
|
|
||||||
VulkanBase::UniformBuffer getUniformBuffer();
|
VulkanBase::UniformBuffer getUniformBuffer();
|
||||||
void setUniformBlock(UniformBlock block);
|
void setUniformBlock(UniformBlock block);
|
|
@ -1,4 +1,4 @@
|
||||||
|
|
||||||
//#pragma once
|
//#pragma once
|
||||||
/*
|
/*
|
||||||
#ifndef TINYGLTF_IMPLEMENTATION
|
#ifndef TINYGLTF_IMPLEMENTATION
|
|
@ -34,6 +34,23 @@ struct UniformBlock {
|
||||||
float jointcount{ 0 };
|
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
|
GLTFLOADER_NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,11 @@ glm::mat4 glTFNode::getMatrix()
|
||||||
return localMatrix;
|
return localMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void glTFNode::setMatrix(glm::mat4 value)
|
||||||
|
{
|
||||||
|
m_matrix = value;
|
||||||
|
}
|
||||||
|
|
||||||
void glTFNode::update()
|
void glTFNode::update()
|
||||||
{
|
{
|
||||||
if (m_mesh) {
|
if (m_mesh) {
|
||||||
|
@ -76,6 +81,121 @@ glTFNode* glTFNode::getParent()
|
||||||
return m_parent;
|
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<glTFNode*>& children)
|
||||||
|
{
|
||||||
|
m_children = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glTFNode*> 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
|
GLTFLOADER_NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
#ifndef GLTFNODE_H
|
||||||
|
#define GLTFNODE_H
|
||||||
|
|
||||||
|
#include "glTFModel_Marco.h"
|
||||||
|
|
||||||
|
#include "glTFSkin.h"
|
||||||
|
#include "glTFMesh.h"
|
||||||
|
#include "glTFBoundingBox.h"
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
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<glTFNode*>& children);
|
||||||
|
std::vector<glTFNode*> 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<glTFNode*> 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
|
|
@ -22,4 +22,30 @@ void glTFPrimitive::setBoundingBox(glm::vec3 min, glm::vec3 max)
|
||||||
m_boundingBox.setBoundingBox(min, 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
|
GLTFLOADER_NAMESPACE_END
|
|
@ -19,12 +19,19 @@ public:
|
||||||
~glTFPrimitive();
|
~glTFPrimitive();
|
||||||
|
|
||||||
void setBoundingBox(glm::vec3 min, glm::vec3 max);
|
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:
|
private:
|
||||||
|
|
||||||
uint32_t m_firstIndex;
|
unsigned int m_firstIndex;
|
||||||
uint32_t m_indexCount;
|
unsigned int m_indexCount;
|
||||||
uint32_t m_vertexCount;
|
unsigned int m_vertexCount;
|
||||||
glTFMaterial& m_material;
|
glTFMaterial& m_material;
|
||||||
bool m_hasIndices;
|
bool m_hasIndices;
|
||||||
glTFBoundingBox m_boundingBox;
|
glTFBoundingBox m_boundingBox;
|
|
@ -0,0 +1,62 @@
|
||||||
|
#include "glTFSkin.h"
|
||||||
|
|
||||||
|
#include "glTFNode.h"
|
||||||
|
|
||||||
|
GLTFLOADER_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
glTFSkin::glTFSkin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
glTFSkin::~glTFSkin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glTFNode*> glTFSkin::getJoints()
|
||||||
|
{
|
||||||
|
return m_joints;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFSkin::pushJointsBack(glTFNode* value)
|
||||||
|
{
|
||||||
|
m_joints.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<glm::mat4> glTFSkin::getInverseBindMatrices()
|
||||||
|
{
|
||||||
|
return m_inverseBindMatrices;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFSkin::pushInverseBindMatrices(glm::mat4& value)
|
||||||
|
{
|
||||||
|
m_inverseBindMatrices.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTFSkin::setInverseBindMatrices(std::vector<glm::mat4>& 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
|
|
@ -19,8 +19,18 @@ public:
|
||||||
~glTFSkin();
|
~glTFSkin();
|
||||||
|
|
||||||
std::vector<glTFNode*> getJoints();
|
std::vector<glTFNode*> getJoints();
|
||||||
|
void pushJointsBack(glTFNode* value);
|
||||||
|
|
||||||
std::vector<glm::mat4> getInverseBindMatrices();
|
std::vector<glm::mat4> getInverseBindMatrices();
|
||||||
|
void pushInverseBindMatrices(glm::mat4& value);
|
||||||
|
void setInverseBindMatrices(std::vector<glm::mat4>& value);
|
||||||
|
|
||||||
|
void setName(std::string& value);
|
||||||
|
std::string getName();
|
||||||
|
|
||||||
|
glTFNode* getSkeletonRoot();
|
||||||
|
void setSkeletonRoot(glTFNode* value);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_name;
|
std::string m_name;
|
|
@ -31,9 +31,9 @@ private:
|
||||||
VkImageLayout m_imageLayout;
|
VkImageLayout m_imageLayout;
|
||||||
VkDeviceMemory m_deviceMemory;
|
VkDeviceMemory m_deviceMemory;
|
||||||
VkImageView m_view;
|
VkImageView m_view;
|
||||||
uint32_t m_width, m_height;
|
unsigned int m_width, m_height;
|
||||||
uint32_t m_mipLevels;
|
unsigned int m_mipLevels;
|
||||||
uint32_t m_layerCount;
|
unsigned int m_layerCount;
|
||||||
VkDescriptorImageInfo m_descriptor;
|
VkDescriptorImageInfo m_descriptor;
|
||||||
VkSampler m_sampler;
|
VkSampler m_sampler;
|
||||||
};
|
};
|
|
@ -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
|
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef PBRBASETEXTURE_H
|
||||||
|
#define PBRBASETEXTURE_H
|
||||||
|
|
||||||
|
/// todo: 分离为单独的PBR命名空间
|
||||||
|
#include "glTFModel_Marco.h"
|
||||||
|
|
||||||
|
#include "glTFTexture.h"
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef PBRTEXTUREEXTENSION_H
|
||||||
|
#define PBRTEXTUREEXTENSION_H
|
||||||
|
|
||||||
|
#include "glTFModel_Marco.h"
|
||||||
|
|
||||||
|
#include "glTFTexture.h"
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -1,14 +0,0 @@
|
||||||
#include "glTFAnimation.h"
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
glTFAnimation::glTFAnimation()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
glTFAnimation::~glTFAnimation()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_END
|
|
|
@ -1,33 +0,0 @@
|
||||||
#ifndef GLTFANIMATION_H
|
|
||||||
#define GLTFANIMATION_H
|
|
||||||
|
|
||||||
#include "glTFModel_Marco.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "glTFAnimationChannel.h"
|
|
||||||
#include "glTFAnimationSampler.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
class glTFAnimation
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
glTFAnimation();
|
|
||||||
~glTFAnimation();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name;
|
|
||||||
std::vector<glTFAnimationSampler> samplers;
|
|
||||||
std::vector<glTFAnimationChannel> channels;
|
|
||||||
float start = std::numeric_limits<float>::max();
|
|
||||||
float end = std::numeric_limits<float>::min();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // !GLTFANIMATION
|
|
|
@ -1,15 +0,0 @@
|
||||||
#include "glTFAnimationChannel.h"
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
glTFAnimationChannel::glTFAnimationChannel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
glTFAnimationChannel::~glTFAnimationChannel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_END
|
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
#include "glTFAnimationSampler.h"
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
glTFAnimationSampler::glTFAnimationSampler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
glTFAnimationSampler::~glTFAnimationSampler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_END
|
|
|
@ -1,28 +0,0 @@
|
||||||
#ifndef GLTFANIMATIONSAMPLER_H
|
|
||||||
#define GLTFANIMATIONSAMPLER_H
|
|
||||||
|
|
||||||
#include "glTFModel_Marco.h"
|
|
||||||
#include "glTFModel_common.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
class glTFAnimationSampler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
glTFAnimationSampler();
|
|
||||||
~glTFAnimationSampler();
|
|
||||||
|
|
||||||
private:
|
|
||||||
AnimationInterpolationType interpolation;
|
|
||||||
std::vector<float> inputs;
|
|
||||||
std::vector<glm::vec4> outputsVec4;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_END
|
|
||||||
|
|
||||||
#endif // !GLTFANIMATIONSAMPLER_H
|
|
|
@ -1,19 +0,0 @@
|
||||||
#include "glTFMaterial.h"
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
glTFMaterial::glTFMaterial()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
glTFMaterial::~glTFMaterial()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_END
|
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef GLTFMATERIAL_H
|
|
||||||
#define GLTFMATERIAL_H
|
|
||||||
|
|
||||||
#include "glTFModel_Marco.h"
|
|
||||||
|
|
||||||
#include "glTFModel_common.h"
|
|
||||||
|
|
||||||
#include "glTFTexture.h"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
|
|
||||||
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
|
|
|
@ -1,54 +0,0 @@
|
||||||
#ifndef GLTFNODE_H
|
|
||||||
#define GLTFNODE_H
|
|
||||||
|
|
||||||
#include "glTFModel_Marco.h"
|
|
||||||
|
|
||||||
#include "glTFSkin.h"
|
|
||||||
#include "glTFMesh.h"
|
|
||||||
#include "glTFBoundingBox.h"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/ext.hpp>
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
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<glTFNode*> 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
|
|
|
@ -1,27 +0,0 @@
|
||||||
#include "glTFSkin.h"
|
|
||||||
|
|
||||||
#include "glTFNode.h"
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
glTFSkin::glTFSkin()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
glTFSkin::~glTFSkin()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<glTFNode*> glTFSkin::getJoints()
|
|
||||||
{
|
|
||||||
return m_joints;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<glm::mat4> glTFSkin::getInverseBindMatrices()
|
|
||||||
{
|
|
||||||
return m_inverseBindMatrices;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLTFLOADER_NAMESPACE_END
|
|
Loading…
Reference in New Issue