mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-23 18:43:15 +08:00
Implement some skinnig stuff.
This commit is contained in:
parent
134d660722
commit
1b85cb8c59
@ -65,10 +65,23 @@ typedef struct {
|
|||||||
size_t count; // byte count
|
size_t count; // byte count
|
||||||
} GLCurvesState;
|
} GLCurvesState;
|
||||||
|
|
||||||
|
|
||||||
|
// Stores vertex position transformed by skinning
|
||||||
|
typedef struct {
|
||||||
|
std::vector<float> positions; // float4
|
||||||
|
} SkinnedMesh;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
std::vector<example::mat4> inverseBindMatrices; // mat44
|
||||||
|
} SkinningMatrices;
|
||||||
|
|
||||||
|
|
||||||
std::map<int, GLBufferState> gBufferState;
|
std::map<int, GLBufferState> gBufferState;
|
||||||
std::map<std::string, GLMeshState> gMeshState;
|
std::map<std::string, GLMeshState> gMeshState;
|
||||||
std::map<int, GLCurvesState> gCurvesMesh;
|
std::map<int, GLCurvesState> gCurvesMesh;
|
||||||
GLProgramState gGLProgramState;
|
GLProgramState gGLProgramState;
|
||||||
|
std::vector<SkinnedMesh> gSkinnedMesh;
|
||||||
|
std::map<int, SkinningMatrices> gSkiningMatrices;
|
||||||
|
|
||||||
void CheckErrors(std::string desc) {
|
void CheckErrors(std::string desc) {
|
||||||
GLenum e = glGetError();
|
GLenum e = glGetError();
|
||||||
@ -729,30 +742,89 @@ static void PrintNodes(const tinygltf::Scene &scene) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetupSkinningState(const tinygltf::Model &model)
|
static void ConstructNodeMatrix(const tinygltf::Node &node, example::mat4 *xform) {
|
||||||
{
|
|
||||||
for (auto &s : model.skins) {
|
|
||||||
if (s.inverseBindMatrices > -1) {
|
|
||||||
|
|
||||||
if (s.joints.size() > 0) {
|
if (node.matrix.size() == 16) {
|
||||||
for (auto const &j : s.joints) {
|
for (size_t j = 0; j < 4; j++) {
|
||||||
std::cout << j << std::endl;
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
xform->m[j][i] = node.matrix[j * 4 + i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<example::mat4> inverse_bind_matrices(s.joints.size());
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const tinygltf::Accessor &accessor = model.accessors[s.inverseBindMatrices];
|
float translation[3] = {0.0f, 0.0f, 0.0f};
|
||||||
|
float rotation[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
float scale[3] = {1.0f, 1.0f, 1.0f};
|
||||||
|
|
||||||
|
if (node.rotation.size() == 4) {
|
||||||
|
std::cout << "rotation " << node.rotation[3] << std::endl;
|
||||||
|
rotation[0] = node.rotation[0];
|
||||||
|
rotation[1] = node.rotation[1];
|
||||||
|
rotation[2] = node.rotation[2];
|
||||||
|
rotation[3] = node.rotation[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.translation.size() == 3) {
|
||||||
|
translation[0] = node.translation[0];
|
||||||
|
translation[1] = node.translation[1];
|
||||||
|
translation[2] = node.translation[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.scale.size() == 3) {
|
||||||
|
scale[0] = node.scale[0];
|
||||||
|
scale[1] = node.scale[1];
|
||||||
|
scale[2] = node.scale[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
example::BuildTransofrmMatrix(translation, rotation, scale, xform);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Hierarchically evalute skining matrix
|
||||||
|
//
|
||||||
|
static void ApplySkinningToMesh(const tinygltf::model &model, const tinygltf::Node &node, example::mat4 &parent_xform, std::vector<SkinnedMesh> *skinned_meshes) {
|
||||||
|
example::mat4 xform = parent_xform;
|
||||||
|
|
||||||
|
if (node.mesh) {
|
||||||
|
if (node.skin) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &child : node.children) {
|
||||||
|
ApplySkinningToMesh(model.nodes[child], xform, skinned_meshes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Read inverseBindMatricies for each skin
|
||||||
|
//
|
||||||
|
static void SetupSkinningMatrices(const tinygltf::Model &model, std::map<int, SkinningMatrices> &skinning_matrices)
|
||||||
|
{
|
||||||
|
for (size_t s = 0; s < model.skins.size(); s++) {
|
||||||
|
const tinygltf::Skin &skin = model.skins[s];
|
||||||
|
|
||||||
|
if (skin.inverseBindMatrices > -1) {
|
||||||
|
|
||||||
|
if (skin.joints.size() > 0) {
|
||||||
|
|
||||||
|
const tinygltf::Accessor &accessor = model.accessors[skin.inverseBindMatrices];
|
||||||
assert(accessor.type == TINYGLTF_TYPE_MAT4);
|
assert(accessor.type == TINYGLTF_TYPE_MAT4);
|
||||||
|
|
||||||
const tinygltf::BufferView &bufferView = model.bufferViews[accessor.bufferView];
|
const tinygltf::BufferView &bufferView = model.bufferViews[accessor.bufferView];
|
||||||
|
|
||||||
const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer];
|
const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer];
|
||||||
|
|
||||||
const float *ptr = reinterpret_cast<const float *>(buffer.data.data() + bufferView.byteOffset);
|
const float *ptr = reinterpret_cast<const float *>(buffer.data.data() + accessor.byteOffset + bufferView.byteOffset);
|
||||||
|
std::cout << "count = " << accessor.count << std::endl;
|
||||||
|
|
||||||
for (size_t j = 0; j < s.joints.size(); j++) {
|
std::vector<example::mat4> inverse_bind_matrices(accessor.count);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < skin.joints.size(); j++) {
|
||||||
example::mat4 m;
|
example::mat4 m;
|
||||||
memcpy(m.m, ptr + j * 16 * sizeof(float), 16 * sizeof(float));
|
memcpy(m.m, ptr + j * 16, 16 * sizeof(float));
|
||||||
|
|
||||||
inverse_bind_matrices[j] = m;
|
inverse_bind_matrices[j] = m;
|
||||||
|
|
||||||
@ -761,6 +833,8 @@ static void SetupSkinningState(const tinygltf::Model &model)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skinning_matrices[s].inverseBindMatrices = inverse_bind_matrices;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,7 +902,9 @@ int main(int argc, char **argv) {
|
|||||||
// DBG
|
// DBG
|
||||||
PrintNodes(model.scenes[scene_idx]);
|
PrintNodes(model.scenes[scene_idx]);
|
||||||
|
|
||||||
SetupSkinningState(model);
|
gSkinnedMesh.resize(model.meshes.size());
|
||||||
|
|
||||||
|
SetupSkinningMatrices(model, gSkiningMatrices);
|
||||||
|
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
std::cerr << "Failed to initialize GLFW." << std::endl;
|
std::cerr << "Failed to initialize GLFW." << std::endl;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define EXAMPLE_SKINNING_H_
|
#define EXAMPLE_SKINNING_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
namespace example {
|
namespace example {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user