lst.SetArray();
lst.Reserve(unsigned(v.size()), al);
for (size_t i = 0; i < v.size(); ++i) {
- lst.PushBack(StringRef(v[i]->id), al);
+ lst.PushBack(v[i]->index, al);
}
obj.AddMember(StringRef(fieldId), lst, al);
}
inline void Write(Value& obj, Accessor& a, AssetWriter& w)
{
- obj.AddMember("bufferView", Value(a.bufferView->id, w.mAl).Move(), w.mAl);
+ obj.AddMember("bufferView", a.bufferView->index, w.mAl);
obj.AddMember("byteOffset", a.byteOffset, w.mAl);
obj.AddMember("byteStride", a.byteStride, w.mAl);
obj.AddMember("componentType", int(a.componentType), w.mAl);
Value valChannel;
valChannel.SetObject();
{
- valChannel.AddMember("sampler", c.sampler, w.mAl);
+ Animation::AnimSampler& s = a.Samplers[c.sampler];
+ valChannel.AddMember("sampler", s.id, w.mAl);
Value valTarget;
valTarget.SetObject();
{
- valTarget.AddMember("id", StringRef(c.target.id->id), w.mAl);
+ valTarget.AddMember("id", StringRef(c.target.node->id), w.mAl);
valTarget.AddMember("path", c.target.path, w.mAl);
}
valChannel.AddMember("target", valTarget, w.mAl);
}
obj.AddMember("channels", channels, w.mAl);
- /****************** Parameters *******************/
- Value valParameters;
- valParameters.SetObject();
- {
- if (a.Parameters.TIME) {
- valParameters.AddMember("TIME", StringRef(a.Parameters.TIME->id), w.mAl);
- }
- if (a.Parameters.rotation) {
- valParameters.AddMember("rotation", StringRef(a.Parameters.rotation->id), w.mAl);
- }
- if (a.Parameters.scale) {
- valParameters.AddMember("scale", StringRef(a.Parameters.scale->id), w.mAl);
- }
- if (a.Parameters.translation) {
- valParameters.AddMember("translation", StringRef(a.Parameters.translation->id), w.mAl);
- }
- }
- obj.AddMember("parameters", valParameters, w.mAl);
-
/****************** Samplers *******************/
Value valSamplers;
- valSamplers.SetObject();
+ valSamplers.SetArray();
for (size_t i = 0; i < unsigned(a.Samplers.size()); ++i) {
Animation::AnimSampler& s = a.Samplers[i];
Value valSampler;
valSampler.SetObject();
{
- valSampler.AddMember("input", s.input, w.mAl);
+ Ref<Accessor> inputAccessor = a.GetAccessor(s.input);
+ Ref<Accessor> outputAccessor = a.GetAccessor(s.output);
+ valSampler.AddMember("input", inputAccessor->index, w.mAl);
valSampler.AddMember("interpolation", s.interpolation, w.mAl);
- valSampler.AddMember("output", s.output, w.mAl);
+ valSampler.AddMember("output", outputAccessor->index, w.mAl);
}
- valSamplers.AddMember(StringRef(s.id), valSampler, w.mAl);
+ valSamplers.PushBack(valSampler, w.mAl);
}
obj.AddMember("samplers", valSamplers, w.mAl);
}
inline void Write(Value& obj, Buffer& b, AssetWriter& w)
{
- const char* type;
- switch (b.type) {
- case Buffer::Type_text:
- type = "text"; break;
- default:
- type = "arraybuffer";
- }
-
obj.AddMember("byteLength", static_cast<uint64_t>(b.byteLength), w.mAl);
- obj.AddMember("type", StringRef(type), w.mAl);
obj.AddMember("uri", Value(b.GetURI(), w.mAl).Move(), w.mAl);
}
inline void Write(Value& obj, BufferView& bv, AssetWriter& w)
{
- obj.AddMember("buffer", Value(bv.buffer->id, w.mAl).Move(), w.mAl);
+ obj.AddMember("buffer", bv.buffer->index, w.mAl);
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
obj.AddMember("target", int(bv.target), w.mAl);
exts.SetObject();
ext.SetObject();
- ext.AddMember("bufferView", StringRef(img.bufferView->id), w.mAl);
+ ext.AddMember("bufferView", img.bufferView->index, w.mAl);
if (!img.mimeType.empty())
ext.AddMember("mimeType", StringRef(img.mimeType), w.mAl);
namespace {
inline void WriteColorOrTex(Value& obj, TexProperty& prop, const char* propName, MemoryPoolAllocator<>& al)
{
- if (prop.texture)
- obj.AddMember(StringRef(propName), Value(prop.texture->id, al).Move(), al);
- else {
+ if (prop.texture) {
+ Value tex;
+ tex.SetObject();
+ tex.AddMember("index", prop.texture->index, al);
+ obj.AddMember(StringRef(propName), tex, al);
+ } else {
Value col;
obj.AddMember(StringRef(propName), MakeValue(col, prop.color, al), al);
}
Value v;
v.SetObject();
{
- WriteColorOrTex(v, m.ambient, "ambient", w.mAl);
- WriteColorOrTex(v, m.diffuse, "diffuse", w.mAl);
- WriteColorOrTex(v, m.specular, "specular", w.mAl);
- WriteColorOrTex(v, m.emission, "emission", w.mAl);
+ WriteColorOrTex(v, m.ambient, m.ambient.texture ? "ambientTexture" : "ambientFactor", w.mAl);
+ WriteColorOrTex(v, m.diffuse, m.diffuse.texture ? "diffuseTexture" : "diffuseFactor", w.mAl);
+ WriteColorOrTex(v, m.specular, m.specular.texture ? "specularTexture" : "specularFactor", w.mAl);
+ WriteColorOrTex(v, m.emission, m.emission.texture ? "emissionTexture" : "emissionFactor", w.mAl);
if (m.transparent)
v.AddMember("transparency", m.transparency, w.mAl);
- v.AddMember("shininess", m.shininess, w.mAl);
+ v.AddMember("shininessFactor", m.shininess, w.mAl);
}
- obj.AddMember("values", v, w.mAl);
+ v.AddMember("type", "commonPhong", w.mAl);
+ Value ext;
+ ext.SetObject();
+ ext.AddMember("KHR_materials_common", v, w.mAl);
+ obj.AddMember("extensions", ext, w.mAl);
}
namespace {
{
if (lst.empty()) return;
if (lst.size() == 1 && !forceNumber) {
- attrs.AddMember(StringRef(semantic), Value(lst[0]->id, w.mAl).Move(), w.mAl);
+ attrs.AddMember(StringRef(semantic), lst[0]->index, w.mAl);
}
else {
for (size_t i = 0; i < lst.size(); ++i) {
char buffer[32];
ai_snprintf(buffer, 32, "%s_%d", semantic, int(i));
- attrs.AddMember(Value(buffer, w.mAl).Move(), Value(lst[i]->id, w.mAl).Move(), w.mAl);
+ attrs.AddMember(Value(buffer, w.mAl).Move(), lst[i]->index, w.mAl);
}
}
}
prim.AddMember("mode", Value(int(p.mode)).Move(), w.mAl);
if (p.material)
- prim.AddMember("material", p.material->id, w.mAl);
+ prim.AddMember("material", p.material->index, w.mAl);
if (p.indices)
- prim.AddMember("indices", Value(p.indices->id, w.mAl).Move(), w.mAl);
+ prim.AddMember("indices", p.indices->index, w.mAl);
Value attrs;
attrs.SetObject();
AddRefsVector(obj, "skeletons", n.skeletons, w.mAl);
if (n.skin) {
- obj.AddMember("skin", Value(n.skin->id, w.mAl).Move(), w.mAl);
+ obj.AddMember("skin", n.skin->index, w.mAl);
}
if (!n.jointName.empty()) {
vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
- vJointNames.PushBack(StringRef(b.jointNames[i]->jointName), w.mAl);
+ vJointNames.PushBack(b.jointNames[i]->index, w.mAl);
}
- obj.AddMember("jointNames", vJointNames, w.mAl);
+ obj.AddMember("joints", vJointNames, w.mAl);
if (b.bindShapeMatrix.isPresent) {
Value val;
}
if (b.inverseBindMatrices) {
- obj.AddMember("inverseBindMatrices", Value(b.inverseBindMatrices->id, w.mAl).Move(), w.mAl);
+ obj.AddMember("inverseBindMatrices", b.inverseBindMatrices->index, w.mAl);
}
}
inline void Write(Value& obj, Texture& tex, AssetWriter& w)
{
if (tex.source) {
- obj.AddMember("source", Value(tex.source->id, w.mAl).Move(), w.mAl);
+ obj.AddMember("source", tex.source->index, w.mAl);
}
if (tex.sampler) {
- obj.AddMember("sampler", Value(tex.sampler->id, w.mAl).Move(), w.mAl);
+ obj.AddMember("sampler", tex.sampler->index, w.mAl);
}
}
// Add the target scene field
if (mAsset.scene) {
- mDoc.AddMember("scene", StringRef(mAsset.scene->id), mAl);
+ mDoc.AddMember("scene", mAsset.scene->index, mAl);
}
}
GLB_Header header;
memcpy(header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic));
- header.version = 1;
+ header.version = 2;
AI_SWAP4(header.version);
header.length = uint32_t(sizeof(header) + sceneLength + bodyLength);
if (false)
exts.PushBack(StringRef("KHR_binary_glTF"), mAl);
- if (false)
- exts.PushBack(StringRef("KHR_materials_common"), mAl);
+ // This is used to export common materials with GLTF 2.
+ exts.PushBack(StringRef("KHR_materials_common"), mAl);
}
if (!exts.Empty())
}
Value* dict;
- if (!(dict = FindObject(*container, d.mDictId))) {
- container->AddMember(StringRef(d.mDictId), Value().SetObject().Move(), mDoc.GetAllocator());
- dict = FindObject(*container, d.mDictId);
+ if (!(dict = FindArray(*container, d.mDictId))) {
+ container->AddMember(StringRef(d.mDictId), Value().SetArray().Move(), mDoc.GetAllocator());
+ dict = FindArray(*container, d.mDictId);
}
for (size_t i = 0; i < d.mObjs.size(); ++i) {
Write(obj, *d.mObjs[i], *this);
- dict->AddMember(StringRef(d.mObjs[i]->id), obj, mAl);
+ dict->PushBack(obj, mAl);
}
}
// aib->mName =====> skinRef->jointNames
// Find the node with id = mName.
Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
- nodeRef->jointName = nodeRef->id;
+ nodeRef->jointName = nodeRef->name;
unsigned int jointNamesIndex;
bool addJointToJointNames = true;
skinRef->bindShapeMatrix.isPresent = true;
IdentityMatrix4(skinRef->bindShapeMatrix.value);
- // Find node that contains this mesh and add "skeletons" and "skin" attributes to that node.
+ // Find nodes that contain a mesh with bones and add "skeletons" and "skin" attributes to those nodes.
Ref<Node> rootNode = mAsset->nodes.Get(unsigned(0));
Ref<Node> meshNode;
- std::string meshID = mAsset->meshes.Get(unsigned(0))->id;
- FindMeshNode(rootNode, meshNode, meshID);
-
- Ref<Node> rootJoint = FindSkeletonRootJoint(skinRef);
- meshNode->skeletons.push_back(rootJoint);
- meshNode->skin = skinRef;
+ for (unsigned int meshIndex = 0; meshIndex < mAsset->meshes.Size(); ++meshIndex) {
+ Ref<Mesh> mesh = mAsset->meshes.Get(meshIndex);
+ bool hasBones = false;
+ for (unsigned int i = 0; i < mesh->primitives.size(); ++i) {
+ if (!mesh->primitives[i].attributes.weight.empty()) {
+ hasBones = true;
+ break;
+ }
+ }
+ if (!hasBones) {
+ continue;
+ }
+ std::string meshID = mesh->id;
+ FindMeshNode(rootNode, meshNode, meshID);
+ Ref<Node> rootJoint = FindSkeletonRootJoint(skinRef);
+ meshNode->skeletons.push_back(rootJoint);
+ meshNode->skin = skinRef;
+ }
}
}
*/
unsigned int glTF2Exporter::ExportNode(const aiNode* n, Ref<Node>& parent)
{
- Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
+ std::string name = mAsset->FindUniqueID(n->mName.C_Str(), "node");
+ Ref<Node> node = mAsset->nodes.Create(name);
node->parent = parent;
+ node->name = name;
if (!n->mTransformation.IsIdentity()) {
node->matrix.isPresent = true;
void glTF2Exporter::ExportMetadata()
{
AssetMetadata& asset = mAsset->asset;
- asset.version = 1;
+ asset.version = 2;
char buffer[256];
ai_snprintf(buffer, 256, "Open Asset Import Library (assimp v%d.%d.%d)",
Animation::AnimChannel tmpAnimChannel;
Animation::AnimSampler tmpAnimSampler;
- tmpAnimChannel.sampler = name + "_" + channelType;
+ tmpAnimChannel.sampler = animRef->Samplers.size();
tmpAnimChannel.target.path = channelType;
tmpAnimSampler.output = channelType;
tmpAnimSampler.id = name + "_" + channelType;
- tmpAnimChannel.target.id = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
+ tmpAnimChannel.target.node = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
tmpAnimSampler.input = "TIME";
tmpAnimSampler.interpolation = "LINEAR";