Supports glTF skinning (glTF 2.0)

This commit is contained in:
Aurélien Chatelain 2017-05-24 12:55:26 +00:00
parent 5cb4346a32
commit 8cb98950ff

View File

@ -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>();