iimachines / Maya2glTF

Maya to glTF 2.0 exporter
MIT License
323 stars 49 forks source link

implement mesh instancing #10

Open ziriax opened 6 years ago

ziriax commented 6 years ago

Currently each instanced maya shape is exported as a new mesh. Most code should be in place to deal with instances.

BigRoy commented 3 years ago

@Ziriax any pointers on where to start to make this work?

Like where in code could I potentially point them to the same mesh data using some sort of lookup table.

ziriax commented 3 years ago

I'm not even sure this is still the case... I would have to investigate myself, this plugin is rather "stable" so I haven't worked on it myself for a long time 😉

BigRoy commented 3 years ago

I see - I was unable to export instances so I didn't feel like it was implemented. Any details would be helpful! :)

ziriax commented 3 years ago

I have some test scenes for instancing in this repository

I will first test these again to check if these still work.

ziriax commented 3 years ago

Indeed, mesh instancing doesn't seem to work. But it should work, so this is a bug.

ziriax commented 3 years ago

Ah, no, this is not yet implemented, the comment says why

    // TODO: Support instancing, for now we create a new mesh for each node.
    // To properly support instance, we need to decide what to do with shapes
    // that are both with and without a skeleton Do we generate two meshes, with
    // and without skinning vertex attributes?
    ExportableMesh(ExportableScene &scene, ExportableNode &node,
                   const MDagPath &shapeDagPath);
ziriax commented 3 years ago

Bummer, I forgot about this...

This is a very important feature, and should be implemented.

That being said, do you think this plugin is still relevant? The BabylonJS team is much larger and has made their own plugin...

ziriax commented 3 years ago

Maybe the easiest approach is hashing the vertex element buffers, and what buffers a mesh uses. If all buffers are the same, then instance it. This solves the issue with weights etc... The mesh name could also be considered to avoid different Maya meshes to become instances.

As a first step, the element buffers should always be shared if possible, since these are read-only by definition I guess, so it doesn't make sense to store these twice...

BigRoy commented 3 years ago

Maybe the easiest approach is hashing the vertex element buffers, and what buffers a mesh uses. If all buffers are the same, then instance it. This solves the issue with weights etc... The mesh name could also be considered to avoid different Maya meshes to become instances.

As a first step, the element buffers should always be shared if possible, since these are read-only by definition I guess, so it doesn't make sense to store these twice...

Actually no. The problem is much more trivial. You can just query Maya if the shape is instanced and if it is you can also find the other instances (and e.g. the master instance - which Maya doesn't really have; instancing is just the same mesh shape parented under multiple transforms).

Thus, with instancing in Maya you can't have one mesh being skinned and the other not being skinned if they were supposed to actual instances - because any case where the shape node differs is basically not an instance.

Regarding BabylonJS. I haven't used the exporter yet but only read through the docs. Because it first goes through the Babylon engine for conversion it felt bloated and limited to what the engine supports at best. Could be decent enough for most use cases however. Hard to tell whether it's worth dropping this particular plugin. If this one isn't being maintained I can see how the other could outrun it.

I was thinking of maybe rewriting this full exporter with the Maya python API just because I feel Maya users are more familiar in that area and it being Python it might get more development support. (But I just don't use it enough for work to warrant spending so much time getting that involved.)

ziriax commented 3 years ago

That could work, but Maya also supports transform instances, not just shapes, something GLTF doesn't support. So basically any transform can have any number of parents in Maya, that's how they do instances. So extra logic will be needed I guess. But possible

The problem is that it is possible in Maya (as far as I remember) to have a mesh that is skinned, and other instance that isn't, and in GLTF, that can't be the same mesh, so instancing can't work in that case. But the accessors can be the same, and hence on the GPU, the same buffers could be re-used.

No this plugin isn't really maintained, but I try to help out people with requests, and like to work on it in my free time. But it is not actively used by the original company/sponsor anymore (they switched to Unity3D and FBX). Personally I'm unfortunately not doing any 3D coding anymore.

Rewriting in Python might be a good idea, but I won't be able to help with that, I just hate Python, any untyped language for that matter 😉