mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-14 03:25:56 +08:00
Supports glTF skinning (glTF 2.0)
This commit is contained in:
parent
5cb4346a32
commit
8cb98950ff
@ -312,6 +312,18 @@ typedef struct {
|
|||||||
Value extras;
|
Value extras;
|
||||||
} Animation;
|
} Animation;
|
||||||
|
|
||||||
|
struct Skin {
|
||||||
|
std::string name;
|
||||||
|
int inverseBindMatrices; // required here but not in the spec
|
||||||
|
int skeleton; // The index of the node used as a skeleton root
|
||||||
|
std::vector<int> joints; // Indices of skeleton nodes
|
||||||
|
|
||||||
|
Skin()
|
||||||
|
{
|
||||||
|
inverseBindMatrices = -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Sampler {
|
struct Sampler {
|
||||||
std::string name;
|
std::string name;
|
||||||
int minFilter; // ["NEAREST", "LINEAR", "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_NEAREST", "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_LINEAR"]
|
int minFilter; // ["NEAREST", "LINEAR", "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_NEAREST", "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_LINEAR"]
|
||||||
@ -455,7 +467,8 @@ class Node {
|
|||||||
public:
|
public:
|
||||||
Node()
|
Node()
|
||||||
{
|
{
|
||||||
mesh = -1;
|
mesh = -1,
|
||||||
|
skin = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Node() {}
|
~Node() {}
|
||||||
@ -463,6 +476,7 @@ class Node {
|
|||||||
int camera; // the index of the camera referenced by this node
|
int camera; // the index of the camera referenced by this node
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
int skin;
|
||||||
int mesh;
|
int mesh;
|
||||||
std::vector<int> children;
|
std::vector<int> children;
|
||||||
std::vector<double> rotation; // length must be 0 or 4
|
std::vector<double> rotation; // length must be 0 or 4
|
||||||
@ -512,6 +526,7 @@ class Model {
|
|||||||
std::vector<Node> nodes;
|
std::vector<Node> nodes;
|
||||||
std::vector<Texture> textures;
|
std::vector<Texture> textures;
|
||||||
std::vector<Image> images;
|
std::vector<Image> images;
|
||||||
|
std::vector<Skin> skins;
|
||||||
std::vector<Sampler> samplers;
|
std::vector<Sampler> samplers;
|
||||||
std::vector<Scene> scenes;
|
std::vector<Scene> scenes;
|
||||||
|
|
||||||
@ -1759,6 +1774,10 @@ static bool ParseMesh(Mesh *mesh, std::string *err, const picojson::object &o) {
|
|||||||
static bool ParseNode(Node *node, std::string *err, const picojson::object &o) {
|
static bool ParseNode(Node *node, std::string *err, const picojson::object &o) {
|
||||||
ParseStringProperty(&node->name, err, o, "name", false);
|
ParseStringProperty(&node->name, err, o, "name", false);
|
||||||
|
|
||||||
|
double skin = -1.0;
|
||||||
|
ParseNumberProperty(&skin, err, o, "skin", false);
|
||||||
|
node->skin = static_cast<int>(skin);
|
||||||
|
|
||||||
// Matrix and T/R/S are exclusive
|
// Matrix and T/R/S are exclusive
|
||||||
if(!ParseNumberArrayProperty(&node->matrix, err, o, "matrix", false)) {
|
if(!ParseNumberArrayProperty(&node->matrix, err, o, "matrix", false)) {
|
||||||
|
|
||||||
@ -2031,6 +2050,29 @@ static bool ParseSampler(Sampler *sampler, std::string *err,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParseSkin(Skin *skin, std::string *err,
|
||||||
|
const picojson::object &o) {
|
||||||
|
|
||||||
|
ParseStringProperty(&skin->name, err, o, "name", false);
|
||||||
|
|
||||||
|
std::vector<double> joints;
|
||||||
|
if (!ParseNumberArrayProperty(&joints, err, o, "joints", false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
double skeleton;
|
||||||
|
ParseNumberProperty(&skeleton, err, o, "skeleton", false);
|
||||||
|
skin->skeleton = static_cast<int>(skeleton);
|
||||||
|
|
||||||
|
skin->joints = std::vector<int>(joints.begin(), joints.end());
|
||||||
|
|
||||||
|
double invBind = -1.0;
|
||||||
|
ParseNumberProperty(&invBind, err, o, "inverseBindMatrices", true);
|
||||||
|
skin->inverseBindMatrices = static_cast<int>(invBind);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool TinyGLTFLoader::LoadFromString(Model *model, std::string *err,
|
bool TinyGLTFLoader::LoadFromString(Model *model, std::string *err,
|
||||||
const char *str, unsigned int length,
|
const char *str, unsigned int length,
|
||||||
const std::string &base_dir,
|
const std::string &base_dir,
|
||||||
@ -2314,8 +2356,8 @@ if (v.contains("scenes") && v.get("scenes").is<picojson::array>()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 11. Parse Animation
|
// 11. Parse Animation
|
||||||
if (v.contains("animations") && v.get("animations").is<picojson::object>()) {
|
if (v.contains("animations") && v.get("animations").is<picojson::array>()) {
|
||||||
const picojson::object &root = v.get("animations").get<picojson::object>();
|
const picojson::array &root = v.get("animations").get<picojson::array>();
|
||||||
|
|
||||||
picojson::array::const_iterator it(root.begin());
|
picojson::array::const_iterator it(root.begin());
|
||||||
picojson::array::const_iterator itEnd(root.end());
|
picojson::array::const_iterator itEnd(root.end());
|
||||||
@ -2330,7 +2372,24 @@ if (v.contains("scenes") && v.get("scenes").is<picojson::array>()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 12. Parse Sampler
|
// 12. Parse Skin
|
||||||
|
if (v.contains("skins") && v.get("skins").is<picojson::array>()) {
|
||||||
|
const picojson::array &root = v.get("skins").get<picojson::array>();
|
||||||
|
|
||||||
|
picojson::array::const_iterator it(root.begin());
|
||||||
|
picojson::array::const_iterator itEnd(root.end());
|
||||||
|
for (; it != itEnd; ++it) {
|
||||||
|
Skin skin;
|
||||||
|
if (!ParseSkin(&skin, err,
|
||||||
|
it->get<picojson::object>())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
model->skins.push_back(skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 13. Parse Sampler
|
||||||
if (v.contains("samplers") && v.get("samplers").is<picojson::array>()) {
|
if (v.contains("samplers") && v.get("samplers").is<picojson::array>()) {
|
||||||
const picojson::array &root = v.get("samplers").get<picojson::array>();
|
const picojson::array &root = v.get("samplers").get<picojson::array>();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user