mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-09-13 07:23:15 +08:00
Start to add node hierarchy support(W.I.P.)
This commit is contained in:
parent
3890ae276a
commit
29d4dc5247
@ -43,7 +43,27 @@
|
|||||||
class Node
|
class Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Node() {}
|
Node() {
|
||||||
|
xform[0] = 1.0;
|
||||||
|
xform[1] = 0.0;
|
||||||
|
xform[2] = 0.0;
|
||||||
|
xform[3] = 0.0;
|
||||||
|
|
||||||
|
xform[4] = 0.0;
|
||||||
|
xform[5] = 1.0;
|
||||||
|
xform[6] = 0.0;
|
||||||
|
xform[7] = 0.0;
|
||||||
|
|
||||||
|
xform[8] = 0.0;
|
||||||
|
xform[9] = 0.0;
|
||||||
|
xform[10] = 1.0;
|
||||||
|
xform[11] = 0.0;
|
||||||
|
|
||||||
|
xform[12] = 0.0;
|
||||||
|
xform[13] = 0.0;
|
||||||
|
xform[14] = 0.0;
|
||||||
|
xform[15] = 1.0;
|
||||||
|
}
|
||||||
virtual ~Node();
|
virtual ~Node();
|
||||||
|
|
||||||
Node(const Node& rhs) {
|
Node(const Node& rhs) {
|
||||||
@ -51,6 +71,8 @@ class Node
|
|||||||
for (size_t i = 0; i < 16; i++) {
|
for (size_t i = 0; i < 16; i++) {
|
||||||
xform[i] = rhs.xform[i];
|
xform[i] = rhs.xform[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
children = rhs.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node &operator=(const Node& rhs) {
|
Node &operator=(const Node& rhs) {
|
||||||
@ -59,11 +81,15 @@ class Node
|
|||||||
xform[i] = rhs.xform[i];
|
xform[i] = rhs.xform[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
children = rhs.children;
|
||||||
|
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
double xform[16];
|
double xform[16];
|
||||||
|
|
||||||
|
std::vector<Node *> children;
|
||||||
};
|
};
|
||||||
|
|
||||||
Node::~Node()
|
Node::~Node()
|
||||||
@ -159,11 +185,11 @@ Points::~Points()
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
std::map<std::string, Mesh> mesh_map;
|
std::map<std::string, Mesh*> mesh_map;
|
||||||
std::map<std::string, Curves> curves_map;
|
std::map<std::string, Curves*> curves_map;
|
||||||
//std::map<std::string, Points> points_map;
|
//std::map<std::string, Points> points_map;
|
||||||
|
|
||||||
std::map<std::string, Node> node_map;
|
std::map<std::string, Node*> node_map;
|
||||||
|
|
||||||
} Scene;
|
} Scene;
|
||||||
|
|
||||||
@ -490,7 +516,7 @@ static void readPolyUVs(
|
|||||||
|
|
||||||
|
|
||||||
// Traverse Alembic object tree and extract scene data.
|
// Traverse Alembic object tree and extract scene data.
|
||||||
static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, const Alembic::AbcGeom::IObject& obj, const std::string& indent) {
|
static void VisitObjectAndExtractScene(Node* node_out, std::stringstream& ss, const Alembic::AbcGeom::IObject& obj, const std::string& indent) {
|
||||||
|
|
||||||
std::string path = obj.getFullName();
|
std::string path = obj.getFullName();
|
||||||
|
|
||||||
@ -501,6 +527,8 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
Alembic::AbcGeom::ICompoundProperty props = obj.getProperties();
|
Alembic::AbcGeom::ICompoundProperty props = obj.getProperties();
|
||||||
VisitProperties(ss, props, indent);
|
VisitProperties(ss, props, indent);
|
||||||
|
|
||||||
|
ss << "# of children = " << obj.getNumChildren() << std::endl;
|
||||||
|
|
||||||
for (size_t i = 0; i < obj.getNumChildren(); i++) {
|
for (size_t i = 0; i < obj.getNumChildren(); i++) {
|
||||||
const Alembic::AbcGeom::ObjectHeader& header = obj.getChildHeader(i);
|
const Alembic::AbcGeom::ObjectHeader& header = obj.getChildHeader(i);
|
||||||
ss << " Child: header = " << header.getName() << std::endl;
|
ss << " Child: header = " << header.getName() << std::endl;
|
||||||
@ -508,7 +536,10 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
Alembic::AbcGeom::ICompoundProperty cprops = obj.getChild(i).getProperties();
|
Alembic::AbcGeom::ICompoundProperty cprops = obj.getChild(i).getProperties();
|
||||||
VisitProperties(ss, props, indent);
|
VisitProperties(ss, props, indent);
|
||||||
|
|
||||||
|
Node *node = NULL;
|
||||||
|
|
||||||
if (Alembic::AbcGeom::IXform::matches(header)) {
|
if (Alembic::AbcGeom::IXform::matches(header)) {
|
||||||
|
ss << " IXform" << std::endl;
|
||||||
|
|
||||||
Alembic::AbcGeom::IXform xform( obj, header.getName() );
|
Alembic::AbcGeom::IXform xform( obj, header.getName() );
|
||||||
|
|
||||||
@ -517,24 +548,26 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
Alembic::AbcGeom::M44d static_matrix = xform.getSchema().getValue().getMatrix();
|
Alembic::AbcGeom::M44d static_matrix = xform.getSchema().getValue().getMatrix();
|
||||||
ss << "IXform static: " << header.getName() << ", " << static_matrix << std::endl;
|
ss << "IXform static: " << header.getName() << ", " << static_matrix << std::endl;
|
||||||
|
|
||||||
Node node;
|
Node *xform_node = new Node();
|
||||||
node.name = header.getName();
|
xform_node->name = header.getName();
|
||||||
node.xform[0] = static_matrix[0][0];
|
xform_node->xform[0] = static_matrix[0][0];
|
||||||
node.xform[1] = static_matrix[0][1];
|
xform_node->xform[1] = static_matrix[0][1];
|
||||||
node.xform[2] = static_matrix[0][2];
|
xform_node->xform[2] = static_matrix[0][2];
|
||||||
node.xform[3] = static_matrix[0][3];
|
xform_node->xform[3] = static_matrix[0][3];
|
||||||
node.xform[4] = static_matrix[1][0];
|
xform_node->xform[4] = static_matrix[1][0];
|
||||||
node.xform[5] = static_matrix[1][1];
|
xform_node->xform[5] = static_matrix[1][1];
|
||||||
node.xform[6] = static_matrix[1][2];
|
xform_node->xform[6] = static_matrix[1][2];
|
||||||
node.xform[7] = static_matrix[1][3];
|
xform_node->xform[7] = static_matrix[1][3];
|
||||||
node.xform[8] = static_matrix[2][0];
|
xform_node->xform[8] = static_matrix[2][0];
|
||||||
node.xform[9] = static_matrix[2][1];
|
xform_node->xform[9] = static_matrix[2][1];
|
||||||
node.xform[10] = static_matrix[2][2];
|
xform_node->xform[10] = static_matrix[2][2];
|
||||||
node.xform[11] = static_matrix[2][3];
|
xform_node->xform[11] = static_matrix[2][3];
|
||||||
node.xform[12] = static_matrix[3][0];
|
xform_node->xform[12] = static_matrix[3][0];
|
||||||
node.xform[13] = static_matrix[3][1];
|
xform_node->xform[13] = static_matrix[3][1];
|
||||||
node.xform[14] = static_matrix[3][2];
|
xform_node->xform[14] = static_matrix[3][2];
|
||||||
node.xform[15] = static_matrix[3][3];
|
xform_node->xform[15] = static_matrix[3][3];
|
||||||
|
|
||||||
|
node = xform_node;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -548,6 +581,8 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
|
|
||||||
ss << " Child: xform" << std::endl;
|
ss << " Child: xform" << std::endl;
|
||||||
} else if (Alembic::AbcGeom::IPolyMesh::matches(header)) {
|
} else if (Alembic::AbcGeom::IPolyMesh::matches(header)) {
|
||||||
|
ss << " IPolyMesh" << std::endl;
|
||||||
|
|
||||||
// Polygon
|
// Polygon
|
||||||
Alembic::AbcGeom::IPolyMesh pmesh(obj, header.getName());
|
Alembic::AbcGeom::IPolyMesh pmesh(obj, header.getName());
|
||||||
|
|
||||||
@ -559,7 +594,7 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
std::cout << " # of samples = " << ps.getNumSamples() << std::endl;
|
std::cout << " # of samples = " << ps.getNumSamples() << std::endl;
|
||||||
|
|
||||||
if (ps.getNumSamples() > 0) {
|
if (ps.getNumSamples() > 0) {
|
||||||
Mesh mesh;
|
Mesh *mesh = new Mesh();
|
||||||
ps.get(psample, samplesel);
|
ps.get(psample, samplesel);
|
||||||
Alembic::Abc::P3fArraySamplePtr P = psample.getPositions();
|
Alembic::Abc::P3fArraySamplePtr P = psample.getPositions();
|
||||||
std::cout << " # of positions = " << P->size() << std::endl;
|
std::cout << " # of positions = " << P->size() << std::endl;
|
||||||
@ -574,7 +609,7 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
readPolyNormals(&normals, &facevarying_normals, normals_param);
|
readPolyNormals(&normals, &facevarying_normals, normals_param);
|
||||||
std::cout << " # of normals = " << (normals.size() / 3) << std::endl;
|
std::cout << " # of normals = " << (normals.size() / 3) << std::endl;
|
||||||
std::cout << " # of facevarying normals = " << (facevarying_normals.size() / 3) << std::endl;
|
std::cout << " # of facevarying normals = " << (facevarying_normals.size() / 3) << std::endl;
|
||||||
mesh.normals = normals;
|
mesh->normals = normals;
|
||||||
|
|
||||||
|
|
||||||
// UV
|
// UV
|
||||||
@ -584,8 +619,8 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
readPolyUVs(&uvs, &facevarying_uvs, uvs_param);
|
readPolyUVs(&uvs, &facevarying_uvs, uvs_param);
|
||||||
std::cout << " # of uvs = " << (uvs.size() / 2) << std::endl;
|
std::cout << " # of uvs = " << (uvs.size() / 2) << std::endl;
|
||||||
std::cout << " # of facevarying_uvs = " << (facevarying_uvs.size() / 2) << std::endl;
|
std::cout << " # of facevarying_uvs = " << (facevarying_uvs.size() / 2) << std::endl;
|
||||||
mesh.texcoords = uvs;
|
mesh->texcoords = uvs;
|
||||||
mesh.facevarying_texcoords = facevarying_uvs;
|
mesh->facevarying_texcoords = facevarying_uvs;
|
||||||
|
|
||||||
std::vector<unsigned int> faces; // temp
|
std::vector<unsigned int> faces; // temp
|
||||||
bool ret = BuildFaceSet(faces, P, psample.getFaceIndices(), psample.getFaceCounts());
|
bool ret = BuildFaceSet(faces, P, psample.getFaceIndices(), psample.getFaceCounts());
|
||||||
@ -593,18 +628,22 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
std::cout << " No faces in polymesh" << std::endl;
|
std::cout << " No faces in polymesh" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.vertices.resize(3 * P->size());
|
mesh->vertices.resize(3 * P->size());
|
||||||
memcpy(mesh.vertices.data(), P->get(), sizeof(float) * 3 * P->size());
|
memcpy(mesh->vertices.data(), P->get(), sizeof(float) * 3 * P->size());
|
||||||
mesh.faces = faces;
|
mesh->faces = faces;
|
||||||
|
|
||||||
assert(scene->mesh_map.find(path) == scene->mesh_map.end());
|
node = mesh;
|
||||||
scene->mesh_map[path] = mesh;
|
|
||||||
return;
|
//assert(scene->mesh_map.find(path) == scene->mesh_map.end());
|
||||||
|
//scene->mesh_map[path] = mesh;
|
||||||
|
//return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Warning: # of samples = 0" << std::endl;
|
std::cout << "Warning: # of samples = 0" << std::endl;
|
||||||
}
|
}
|
||||||
} else if (Alembic::AbcGeom::ICurves::matches(header)) {
|
} else if (Alembic::AbcGeom::ICurves::matches(header)) {
|
||||||
|
ss << " ICurves" << std::endl;
|
||||||
|
|
||||||
// Curves
|
// Curves
|
||||||
Alembic::AbcGeom::ICurves curve(obj, header.getName());
|
Alembic::AbcGeom::ICurves curve(obj, header.getName());
|
||||||
|
|
||||||
@ -662,20 +701,92 @@ static void VisitObjectAndExtractScene(Scene* scene, std::stringstream& ss, cons
|
|||||||
memcpy(curves.nverts.data(), num_vertices->get(), sizeof(int) * num_vertices->size());
|
memcpy(curves.nverts.data(), num_vertices->get(), sizeof(int) * num_vertices->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(scene->curves_map.find(path) == scene->curves_map.end());
|
//assert(scene->curves_map.find(path) == scene->curves_map.end());
|
||||||
scene->curves_map[path] = curves;
|
//scene->curves_map[path] = curves;
|
||||||
return;
|
//return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Warning: # of samples = 0" << std::endl;
|
std::cout << "Warning: # of samples = 0" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (Alembic::AbcGeom::IFaceSet::matches(header)) {
|
||||||
|
ss << " IFaceSet" << std::endl;
|
||||||
|
} else {
|
||||||
|
ss << " TODO" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
VisitObjectAndExtractScene(scene, ss, Alembic::AbcGeom::IObject(obj, obj.getChildHeader(i).getName()), indent);
|
if (node) {
|
||||||
|
// Visit child.
|
||||||
|
VisitObjectAndExtractScene(node, ss, Alembic::AbcGeom::IObject(obj, obj.getChildHeader(i).getName()), indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
node_out->children.push_back(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool SaveSceneToGLTF(picojson::object *out, const Scene &scene)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::map<std::string, Node*>::const_iterator it(scene.node_map.begin());
|
||||||
|
std::map<std::string, Node*>::const_iterator it_end(scene.node_map.end());
|
||||||
|
|
||||||
|
picojson::object nodes;
|
||||||
|
|
||||||
|
for (; it != it_end; it++) {
|
||||||
|
picojson::object node;
|
||||||
|
|
||||||
|
// FIXME: Hierarchial
|
||||||
|
picojson::array meshes;
|
||||||
|
|
||||||
|
meshes.push_back(picojson::value(std::string("mesh_1")));
|
||||||
|
|
||||||
|
node["meshes"] = picojson::value(meshes);
|
||||||
|
|
||||||
|
// Xform
|
||||||
|
// TODO(syoyo): Support Translation, Scale, Rotate, etc.
|
||||||
|
{
|
||||||
|
picojson::array xform;
|
||||||
|
for (size_t i = 0; i < 16; i++) {
|
||||||
|
xform.push_back(picojson::value((it->second)->xform[i]));
|
||||||
|
}
|
||||||
|
node["matrix"] = picojson::value(xform);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes["node_1"] = picojson::value(node);
|
||||||
|
(*out)["nodes"] = picojson::value(nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
picojson::object defaultScene;
|
||||||
|
picojson::array nodes;
|
||||||
|
|
||||||
|
nodes.push_back(picojson::value(std::string("node_1")));
|
||||||
|
|
||||||
|
defaultScene["nodes"] = picojson::value(nodes);
|
||||||
|
|
||||||
|
(*out)["scene"] = picojson::value("defaultScene");
|
||||||
|
picojson::object scenes;
|
||||||
|
scenes["defaultScene"] = picojson::value(defaultScene);
|
||||||
|
(*out)["scenes"] = picojson::value(scenes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @todo {}
|
||||||
|
picojson::object shaders;
|
||||||
|
picojson::object programs;
|
||||||
|
picojson::object techniques;
|
||||||
|
picojson::object materials;
|
||||||
|
picojson::object skins;
|
||||||
|
(*out)["shaders"] = picojson::value(shaders);
|
||||||
|
(*out)["programs"] = picojson::value(programs);
|
||||||
|
(*out)["techniques"] = picojson::value(techniques);
|
||||||
|
(*out)["materials"] = picojson::value(materials);
|
||||||
|
(*out)["skins"] = picojson::value(skins);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool SaveMeshToGLTF(const std::string& output_filename,
|
static bool SaveMeshToGLTF(const std::string& output_filename,
|
||||||
const Mesh& mesh) {
|
const Mesh& mesh) {
|
||||||
picojson::object root;
|
picojson::object root;
|
||||||
@ -804,46 +915,6 @@ static bool SaveMeshToGLTF(const std::string& output_filename,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
picojson::object nodes;
|
|
||||||
picojson::object node;
|
|
||||||
picojson::array meshes;
|
|
||||||
|
|
||||||
meshes.push_back(picojson::value(std::string("mesh_1")));
|
|
||||||
|
|
||||||
node["meshes"] = picojson::value(meshes);
|
|
||||||
|
|
||||||
nodes["node_1"] = picojson::value(node);
|
|
||||||
root["nodes"] = picojson::value(nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
picojson::object defaultScene;
|
|
||||||
picojson::array nodes;
|
|
||||||
|
|
||||||
nodes.push_back(picojson::value(std::string("node_1")));
|
|
||||||
|
|
||||||
defaultScene["nodes"] = picojson::value(nodes);
|
|
||||||
|
|
||||||
root["scene"] = picojson::value("defaultScene");
|
|
||||||
picojson::object scenes;
|
|
||||||
scenes["defaultScene"] = picojson::value(defaultScene);
|
|
||||||
root["scenes"] = picojson::value(scenes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// @todo {}
|
|
||||||
picojson::object shaders;
|
|
||||||
picojson::object programs;
|
|
||||||
picojson::object techniques;
|
|
||||||
picojson::object materials;
|
|
||||||
picojson::object skins;
|
|
||||||
root["shaders"] = picojson::value(shaders);
|
|
||||||
root["programs"] = picojson::value(programs);
|
|
||||||
root["techniques"] = picojson::value(techniques);
|
|
||||||
root["materials"] = picojson::value(materials);
|
|
||||||
root["skins"] = picojson::value(skins);
|
|
||||||
|
|
||||||
std::ofstream ifs(output_filename.c_str());
|
std::ofstream ifs(output_filename.c_str());
|
||||||
if (ifs.bad()) {
|
if (ifs.bad()) {
|
||||||
std::cerr << "Failed to open " << output_filename << std::endl;
|
std::cerr << "Failed to open " << output_filename << std::endl;
|
||||||
@ -1062,13 +1133,14 @@ static bool SaveCurvesToGLTF(const std::string& output_filename,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
// Flatten multiple Curves object to one Curves.
|
// Flatten multiple Curves object to one Curves.
|
||||||
static void FlattenCurves(Curves *flatten_curves, const Scene &scene)
|
static void FlattenCurves(Curves *flatten_curves, const Scene &scene)
|
||||||
{
|
{
|
||||||
flatten_curves->name = "flatten_curves";
|
flatten_curves->name = "flatten_curves";
|
||||||
|
|
||||||
std::map<std::string, Curves>::const_iterator it(scene.curves_map.begin());
|
std::map<std::string, Curves*>::const_iterator it(scene.curves_map.begin());
|
||||||
std::map<std::string, Curves>::const_iterator itEnd(scene.curves_map.end());
|
std::map<std::string, Curves*>::const_iterator itEnd(scene.curves_map.end());
|
||||||
|
|
||||||
for (; it != itEnd; it++) {
|
for (; it != itEnd; it++) {
|
||||||
const Curves &curves = it->second;
|
const Curves &curves = it->second;
|
||||||
@ -1076,6 +1148,7 @@ static void FlattenCurves(Curves *flatten_curves, const Scene &scene)
|
|||||||
std::copy(curves.nverts.begin(), curves.nverts.end(), std::back_inserter(flatten_curves->nverts));
|
std::copy(curves.nverts.begin(), curves.nverts.end(), std::back_inserter(flatten_curves->nverts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
std::string abc_filename;
|
std::string abc_filename;
|
||||||
@ -1098,7 +1171,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
Scene scene;
|
Scene scene;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
VisitObjectAndExtractScene(&scene, ss, root, /* indent */" ");
|
Node node;
|
||||||
|
VisitObjectAndExtractScene(&node, ss, root, /* indent */" ");
|
||||||
|
|
||||||
std::cout << ss.str() << std::endl;
|
std::cout << ss.str() << std::endl;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user