完成初步gltf重构

reconstruct-gltfLoader
InkSoul 2025-04-20 22:38:31 +08:00
parent 909f9eb57a
commit f42fbae8e9
44 changed files with 2373 additions and 305 deletions

View File

@ -9,30 +9,34 @@ set(MAIN_FILE
)
set(GLTF_MODEL_LOADER
"${PLUMAGE_RENDER}/glTFModel_Marco.h"
"${PLUMAGE_RENDER}/glTFModel_common.h"
"${PLUMAGE_RENDER}/glTFBoundingBox.h"
"${PLUMAGE_RENDER}/glTFBoundingBox.cpp"
"${PLUMAGE_RENDER}/glTFTexture.h"
"${PLUMAGE_RENDER}/glTFTexture.cpp"
"${PLUMAGE_RENDER}/glTFModel.h"
"${PLUMAGE_RENDER}/glTFModel.cpp"
"${PLUMAGE_RENDER}/glTFMaterial.h"
"${PLUMAGE_RENDER}/glTFMaterial.cpp"
"render/glTFPrimitive.h"
"${PLUMAGE_RENDER}/glTFPrimitive.cpp"
"render/glTFMesh.h"
"render/glTFMesh.cpp"
"render/glTFSkin.h"
"render/glTFSkin.cpp"
"render/glTFNode.h"
"render/glTFNode.cpp"
"render/glTFAnimationChannel.h"
"render/glTFAnimationChannel.cpp"
"render/glTFAnimationSampler.h"
"render/glTFAnimationSampler.cpp"
"gltf/glTFModel_Marco.h"
"gltf/glTFModel_common.h"
"gltf/glTFBoundingBox.h"
"gltf/glTFBoundingBox.cpp"
"gltf/glTFTexture.h"
"gltf/glTFTexture.cpp"
"gltf/glTFModel.h"
"gltf/glTFModel.cpp"
"gltf/glTFMaterial.h"
"gltf/glTFMaterial.cpp"
"gltf/glTFPrimitive.h"
"gltf/glTFPrimitive.cpp"
"gltf/glTFMesh.h"
"gltf/glTFMesh.cpp"
"gltf/glTFSkin.h"
"gltf/glTFSkin.cpp"
"gltf/glTFNode.h"
"gltf/glTFNode.cpp"
"gltf/glTFAnimationChannel.h"
"gltf/glTFAnimationChannel.cpp"
"gltf/glTFAnimationSampler.h"
"gltf/glTFAnimationSampler.cpp"
"gltf/glTFAnimation.h"
"gltf/glTFAnimation.cpp"
"gltf/glTFMainModel.h"
"gltf/glTFMainModel.cpp"
"render/glTFAnimation.h" "render/glTFAnimation.cpp")
)
set(VULKAN_BASE
"${PLUMAGE_RENDER}/VulkanBase_Marco.h"
@ -41,7 +45,13 @@ set(VULKAN_BASE
"${PLUMAGE_RENDER}/VulkanDevice.cpp"
"${PLUMAGE_RENDER}/VulkanTextureSampler.h"
"${PLUMAGE_RENDER}/VulkanTextureSampler.cpp"
)
"pbr/PbrTextureExtension.h"
"pbr/PbrTextureExtension.cpp"
"pbr/PbrBaseTexture.h"
"pbr/PbrBaseTexture.cpp"
"pbr/PbrTextureCoordSet.h"
"pbr/PbrTextureCoordSet.cpp"
"pbr/PbrWorkFlow.h" "pbr/PbrWorkFlow.cpp")
# wayland requires additional source files
IF(USE_WAYLAND_WSI)
@ -71,6 +81,12 @@ include_directories(${3rdParty_vulkan_path})
include_directories(${lib_base_path})
# TODO:
include_directories(gltf)
include_directories(pbr)
include_directories(render)
if(WIN32)
add_executable(${RenderName} WIN32 ${SHADERS_GLSL} ${SHADERS_HLSL}
${MAIN_FILE}

View 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

View File

@ -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

View File

@ -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

View File

@ -14,11 +14,20 @@ public:
glTFAnimationChannel();
~glTFAnimationChannel();
void setSamplerIndex(unsigned int samplerIndex);
unsigned int getSamplerIndex();
void setAnimationPathType(AnimationPathType pathType);
AnimationPathType getAnimationPathType();
void setNode(glTFNode* node);
glTFNode* getNode();
private:
AnimationPathType path;
glTFNode* node;
uint32_t samplerIndex;
AnimationPathType m_pathType;
glTFNode* m_node;
unsigned int m_samplerIndex;
};

View File

@ -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

View File

@ -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

View File

@ -4,14 +4,14 @@ GLTFLOADER_NAMESPACE_BEGIN
glTFBoundingBox::glTFBoundingBox()
: m_isValid(true)
: m_valid(true)
, m_min(glm::vec3(0,0,0))
, m_max(glm::vec3(1,1,1))
{
}
glTFBoundingBox::glTFBoundingBox(glm::vec3 min, glm::vec3 max)
: m_isValid(true)
: m_valid(true)
, m_min(min)
, m_max(max)
{
@ -52,7 +52,37 @@ void glTFBoundingBox::setBoundingBox(glm::vec3 min, glm::vec3 max)
{
m_min = min;
m_max = max;
m_isValid = true;
m_valid = true;
}
glm::vec3 glTFBoundingBox::getMin()
{
return m_min;
}
void glTFBoundingBox::setMin(glm::vec3 min)
{
m_min = min;
}
glm::vec3 glTFBoundingBox::getMax()
{
return m_max;
}
void glTFBoundingBox::setMax(glm::vec3 max)
{
m_max = max;
}
bool glTFBoundingBox::isValid()
{
return m_valid;
}
void glTFBoundingBox::setValid(bool valid)
{
m_valid = valid;
}

View File

@ -17,11 +17,20 @@ public:
void setBoundingBox(glm::vec3 min, glm::vec3 max);
glm::vec3 getMin();
void setMin(glm::vec3 min);
glm::vec3 getMax();
void setMax(glm::vec3 max);
bool isValid();
void setValid(bool valid);
private:
glm::vec3 m_min;
glm::vec3 m_max;
bool m_isValid = false;
bool m_valid = false;
};

View File

@ -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, &copyRegion);
if (indexBufferSize > 0) {
copyRegion.size = indexBufferSize;
vkCmdCopyBuffer(copyCmd, indexStaging.buffer, m_indices.buffer, 1, &copyRegion);
}
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -38,6 +38,31 @@ void glTFMesh::setBoundingBox(glm::vec3 min, glm::vec3 max)
m_boundingBox.setBoundingBox(min, max);
}
void glTFMesh::setBoundingBox(glTFBoundingBox BoundingBox)
{
m_boundingBox = BoundingBox;
}
glTFBoundingBox glTFMesh::getBoundingBox()
{
return m_boundingBox;
}
void glTFMesh::setPrimitives(std::vector<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()
{
return m_uniformBuffer;

View File

@ -23,6 +23,12 @@ public:
~glTFMesh();
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();
void setUniformBlock(UniformBlock block);

View File

@ -1,4 +1,4 @@

//#pragma once
/*
#ifndef TINYGLTF_IMPLEMENTATION

View File

@ -34,6 +34,23 @@ struct UniformBlock {
float jointcount{ 0 };
};
struct Vertex {
glm::vec3 pos;
glm::vec3 normal;
glm::vec2 uv0;
glm::vec2 uv1;
glm::vec4 joint0;
glm::vec4 weight0;
glm::vec4 color;
};
struct LoaderInfo {
uint32_t* indexBuffer;
Vertex* vertexBuffer;
size_t indexPos = 0;
size_t vertexPos = 0;
};
GLTFLOADER_NAMESPACE_END

View File

@ -33,6 +33,11 @@ glm::mat4 glTFNode::getMatrix()
return localMatrix;
}
void glTFNode::setMatrix(glm::mat4 value)
{
m_matrix = value;
}
void glTFNode::update()
{
if (m_mesh) {
@ -76,6 +81,121 @@ glTFNode* glTFNode::getParent()
return m_parent;
}
void glTFNode::setBvh(glTFBoundingBox bvh)
{
m_bvh = bvh;
}
glTFBoundingBox glTFNode::getBvh()
{
return m_bvh;
}
void glTFNode::setMesh(glTFMesh* mesh)
{
m_mesh = mesh;
}
glTFMesh* glTFNode::getMesh()
{
return m_mesh;
}
void glTFNode::setAxisAlignedBoundingBox(glTFBoundingBox aabb)
{
m_aabb = aabb;
}
glTFBoundingBox glTFNode::getAxisAlignedBoundingBox()
{
return m_aabb;
}
void glTFNode::setChildren(std::vector<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

View File

@ -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

View File

@ -22,4 +22,30 @@ void glTFPrimitive::setBoundingBox(glm::vec3 min, glm::vec3 max)
m_boundingBox.setBoundingBox(min, max);
}
glTFBoundingBox glTFPrimitive::getBoundingBox()
{
return m_boundingBox;
}
void glTFPrimitive::setIndexCount(unsigned int indexCount)
{
m_indexCount = indexCount;
}
unsigned int glTFPrimitive::getIndexCount()
{
return m_indexCount;
}
void glTFPrimitive::setFirstIndex(unsigned int firstIndex)
{
m_firstIndex = firstIndex;
}
unsigned int glTFPrimitive::getFirstIndex()
{
return m_firstIndex;
}
GLTFLOADER_NAMESPACE_END

View File

@ -19,12 +19,19 @@ public:
~glTFPrimitive();
void setBoundingBox(glm::vec3 min, glm::vec3 max);
glTFBoundingBox getBoundingBox();
void setIndexCount(unsigned int indexCount);
unsigned int getIndexCount();
void setFirstIndex(unsigned int firstIndex);
unsigned int getFirstIndex();
private:
uint32_t m_firstIndex;
uint32_t m_indexCount;
uint32_t m_vertexCount;
unsigned int m_firstIndex;
unsigned int m_indexCount;
unsigned int m_vertexCount;
glTFMaterial& m_material;
bool m_hasIndices;
glTFBoundingBox m_boundingBox;

View File

@ -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

View File

@ -19,8 +19,18 @@ public:
~glTFSkin();
std::vector<glTFNode*> getJoints();
void pushJointsBack(glTFNode* value);
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:
std::string m_name;

View File

@ -31,9 +31,9 @@ private:
VkImageLayout m_imageLayout;
VkDeviceMemory m_deviceMemory;
VkImageView m_view;
uint32_t m_width, m_height;
uint32_t m_mipLevels;
uint32_t m_layerCount;
unsigned int m_width, m_height;
unsigned int m_mipLevels;
unsigned int m_layerCount;
VkDescriptorImageInfo m_descriptor;
VkSampler m_sampler;
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,14 +0,0 @@
#include "glTFAnimation.h"
GLTFLOADER_NAMESPACE_BEGIN
glTFAnimation::glTFAnimation()
{
}
glTFAnimation::~glTFAnimation()
{
}
GLTFLOADER_NAMESPACE_END

View File

@ -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

View File

@ -1,15 +0,0 @@
#include "glTFAnimationChannel.h"
GLTFLOADER_NAMESPACE_BEGIN
glTFAnimationChannel::glTFAnimationChannel()
{
}
glTFAnimationChannel::~glTFAnimationChannel()
{
}
GLTFLOADER_NAMESPACE_END

View File

@ -1,15 +0,0 @@
#include "glTFAnimationSampler.h"
GLTFLOADER_NAMESPACE_BEGIN
glTFAnimationSampler::glTFAnimationSampler()
{
}
glTFAnimationSampler::~glTFAnimationSampler()
{
}
GLTFLOADER_NAMESPACE_END

View File

@ -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

View File

@ -1,19 +0,0 @@
#include "glTFMaterial.h"
GLTFLOADER_NAMESPACE_BEGIN
glTFMaterial::glTFMaterial()
{
}
glTFMaterial::~glTFMaterial()
{
}
GLTFLOADER_NAMESPACE_END

View File

@ -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

View File

@ -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

View File

@ -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