Initial working abc2gltf converter.

This commit is contained in:
Syoyo Fujita 2016-10-14 18:50:33 +09:00
parent 0614eb8fa6
commit e08ef2fbd5
4 changed files with 153 additions and 5 deletions

View File

@ -7,7 +7,7 @@ ILMBASE_INC := -I/usr/local/include/OpenEXR
EXTRA_CXXFLAGS := -Wno-deprecated-register -Weverything EXTRA_CXXFLAGS := -Wno-deprecated-register -Weverything
all: all:
clang++ -std=c++11 -g -o abc2gltf $(ABC_INC) $(ILMBASE_INC) $(EXTRA_CXXFLAGS) main.cc $(ABC_LDFLAGS) clang++ -std=c++11 -g -o abc2gltf $(ABC_INC) $(ILMBASE_INC) $(EXTRA_CXXFLAGS) abc2gltf.cc $(ABC_LDFLAGS)
run: run:
./abc2gltf suzanne.abc suzanne.gltf ./abc2gltf suzanne.abc suzanne.gltf

View File

@ -0,0 +1,31 @@
# Simple Alembic to glTF converter example
## Features
* Polygon mesh.
## Limitations
* Alembic data with Ogawa backend only
* Simple poly mesh only
* Static mesh only(Use first time sample. no animation)
## Compile
OpenEXR(ilmbase), and Alembic 1.6 or later are equired to compile the converter.
Edit include and lib paths for Alembic OpenEXR(ilmbase) in `Makefile`, then simply:
$ make
## Alembic data
I am testing with Alembic data using Blender's Alembic exporter(feature available from Blender 2.78)
## TODO
* [ ] Support normals and texcoords
* [ ] Support mutiple meshes
* [ ] Support animation(time samples)
* [ ] Support scene graph(node hierarchy)
* [ ] Support Point, Curve and SubD?

View File

@ -31,12 +31,15 @@
#include <Alembic/AbcCoreOgawa/All.h> #include <Alembic/AbcCoreOgawa/All.h>
#include <Alembic/AbcGeom/All.h> #include <Alembic/AbcGeom/All.h>
#define PICOJSON_USE_INT64
#include "../../picojson.h" #include "../../picojson.h"
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#include "../../tiny_gltf_loader.h" // To import some TINYGLTF_*** macros.
// @todo { texcoords, normals } // @todo { texcoords, normals }
typedef struct typedef struct
{ {
@ -337,8 +340,8 @@ static bool SaveGLTF(const std::string& output_filename,
root["assets"] = picojson::value(asset); root["assets"] = picojson::value(asset);
} }
picojson::object buffers;
{ {
picojson::object buffers;
{ {
std::string vertices_b64data = base64_encode(reinterpret_cast<unsigned char const*>(mesh.vertices.data()), mesh.vertices.size() * sizeof(float)); std::string vertices_b64data = base64_encode(reinterpret_cast<unsigned char const*>(mesh.vertices.data()), mesh.vertices.size() * sizeof(float));
picojson::object buf; picojson::object buf;
@ -359,12 +362,122 @@ static bool SaveGLTF(const std::string& output_filename,
buf["uri"] = picojson::value( buf["uri"] = picojson::value(
std::string("data:application/octet-stream;base64,") + faces_b64data); std::string("data:application/octet-stream;base64,") + faces_b64data);
buf["byteLength"] = buf["byteLength"] =
picojson::value(static_cast<double>(mesh.vertices.size() * sizeof(unsigned int))); picojson::value(static_cast<double>(mesh.faces.size() * sizeof(unsigned int)));
buffers["indices"] = picojson::value(buf); buffers["indices"] = picojson::value(buf);
} }
root["buffers"] = picojson::value(buffers);
} }
root["buffers"] = picojson::value(buffers);
{
picojson::object buffer_views;
{
picojson::object buffer_view_vertices;
buffer_view_vertices["buffer"] = picojson::value(std::string("vertices"));
buffer_view_vertices["byteLength"] = picojson::value(static_cast<double>(mesh.vertices.size() * sizeof(float)));
buffer_view_vertices["byteOffset"] = picojson::value(static_cast<double>(0));
buffer_view_vertices["target"] = picojson::value(static_cast<int64_t>(TINYGLTF_TARGET_ARRAY_BUFFER));
buffer_views["bufferView_vertices"] = picojson::value(buffer_view_vertices);
}
{
picojson::object buffer_view_indices;
buffer_view_indices["buffer"] = picojson::value(std::string("indices"));
buffer_view_indices["byteLength"] = picojson::value(static_cast<double>(mesh.faces.size() * sizeof(unsigned int)));
buffer_view_indices["byteOffset"] = picojson::value(static_cast<double>(0));
buffer_view_indices["target"] = picojson::value(static_cast<int64_t>(TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER));
buffer_views["bufferView_indices"] = picojson::value(buffer_view_indices);
}
root["bufferViews"] = picojson::value(buffer_views);
}
{
picojson::object attributes;
attributes["POSITION"] = picojson::value(std::string("accessor_vertices"));
picojson::object primitive;
primitive["attributes"] = picojson::value(attributes);
primitive["indices"] = picojson::value("accessor_indices");
primitive["material"] = picojson::value("material_1");
primitive["mode"] = picojson::value(static_cast<int64_t>(TINYGLTF_MODE_TRIANGLES));
picojson::array primitive_array;
primitive_array.push_back(picojson::value(primitive));
picojson::object m;
m["primitives"] = picojson::value(primitive_array);
picojson::object meshes;
meshes["mesh_1"] = picojson::value(m);
root["meshes"] = picojson::value(meshes);
}
{
picojson::object accessors;
picojson::object accessor_vertices;
picojson::object accessor_indices;
accessor_vertices["bufferView"] = picojson::value(std::string("bufferView_vertices"));
accessor_vertices["byteOffset"] = picojson::value(static_cast<int64_t>(0));
accessor_vertices["byteStride"] = picojson::value(static_cast<double>(3 * sizeof(float)));
accessor_vertices["componentType"] = picojson::value(static_cast<int64_t>(TINYGLTF_COMPONENT_TYPE_FLOAT));
accessor_vertices["count"] = picojson::value(static_cast<int64_t>(mesh.vertices.size()));
accessor_vertices["type"] = picojson::value(std::string("VEC3"));
accessors["accessor_vertices"] = picojson::value(accessor_vertices);
accessor_indices["bufferView"] = picojson::value(std::string("bufferView_indices"));
accessor_indices["byteOffset"] = picojson::value(static_cast<int64_t>(0));
accessor_indices["componentType"] = picojson::value(static_cast<int64_t>(TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT));
accessor_indices["count"] = picojson::value(static_cast<int64_t>(mesh.faces.size()));
accessor_indices["type"] = picojson::value(std::string("SCALAR"));
accessors["accessor_indices"] = picojson::value(accessor_indices);
root["accessors"] = picojson::value(accessors);
}
{
// Use Default Material(Do not supply `material.technique`)
picojson::object default_material;
picojson::object materials;
materials["material_1"] = picojson::value(default_material);
root["materials"] = picojson::value(materials);
}
{
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 {} // @todo {}
picojson::object shaders; picojson::object shaders;
@ -422,7 +535,11 @@ int main(int argc, char** argv) {
if (foundMesh) { if (foundMesh) {
bool ret = SaveGLTF(gltf_filename, mesh); bool ret = SaveGLTF(gltf_filename, mesh);
return ret ? EXIT_SUCCESS : EXIT_FAILURE; if (ret) {
std::cout << "Wrote " << gltf_filename << std::endl;
} else {
return EXIT_FAILURE;
}
} else { } else {
std::cout << "No polygon mesh found in Alembic file" << std::endl; std::cout << "No polygon mesh found in Alembic file" << std::endl;
} }

Binary file not shown.