Closed uykusuz closed 10 years ago
Hi there.
We had this feature request a lot and to some part I agree: We definitely need an easier way instantiate assets composed of multiple meshes.
However, I still believe that instantiation of groups is not the best way to solve this issue. Some reasons:
Still, I also think that we need a better solution to instantiate larger assets.
That's why I created a proposal for a new <datalist>
and <multimesh>
element.
You find it in the wiki: https://github.com/xml3d/xml3d.js/wiki/Multidata
Even though I posted this proposal some time ago, I didn't find the time to discuss and implement it until now.
With DataLists and MultiMeshes it is possible to instantiate complex assets with a single element such as this:
<multimesh src="assets/myAsset.xml#dataListElement" ></mulitmesh>
This asset can have an arbitrary number of transformed mesh elements, connected with multiple shaders.
In addition, it is possible to instantiate assets combined with Xflow dataflows (e.g. skinned meshes with animations)
<!-- Add the multimesh -->
<multimesh src="assets/sniper.xml#meshDataList" >
<!-- Extend the "base" subdata which includes the animation -->
<subdata name="base">
<!-- Add the animation data -->
<data src="assets/sniper.xml#someAnimationData"" ></data>
<!-- Add the key for the animation -->
<float name="key">0.0</float>
</subdata>
</multimesh>
The best thing about this feature: It's implementation in xml3d.js is very feasible. In fact, I was planning to spend some time the next days and try to implement this.
Do you think this feature would help you out? If you see any limitations with this approach, please tell me.
From a user standpoint I found this confusing and not intuitive. I like the simplicity of writing
<group src="myothergroupnode" />
in the same way as I do it for meshes. With the data-way you're pushing the declaration of the hierarchy inside the data-elements, which seems like another world. I see your points, also concerning ease of implementation, but from a user point-of-view I don't like that approach.
But all that aside, having at least some way of instancing is better than none.
I kinda expected that people would explain about this concept not being intuitive.
Still for group instantiation, the whole simplicity will break as soon as you try to instantiate anything but a static group of meshes - and this is a very relevant use case.
So I rather have one new approach that works elegantly for a wide range of use cases rather than to try to extend the functionality of <group>
nodes - which will most likely be very ugly when you want to describe a way to replace the content inside a tree structure.
Hm this goes into a direction that I can basically put XML3D aside and define everything in Xflow, this sounds strange :D As I said before, I simply want to instantiate an asset. That asset is static, I don't want to modify anything in there. At least in our applications this is the only use case we need. This is just my personal opinion but I think this is the use case that is needed in most of the applications: simple asset instantiation.
Well, it's not quite like you define everything with Xflow.
The <datalist>
and <multimesh>
are basically syntactical sugar for assembling Xflow graphs connected to meshes.
I understand and agree that simple asset instantiation is important, but it is not the only relevant use cases.
For instance, if you want to create a virtual world with animated avatars and need to instantiate a large number of them, you will be glad if you can do this with 4 elements per avatar instead of about 20-40.
I don't see how forfeiting the inner workings of a group referenced in the proposed <group src="somewhere.xml" />
way is a problem. It's perfectly equivalent to <img src="something.svg"/>
, where you forfeit the possibility to manipulate the svg (e.g. for animation).
I agree that the "avatar" scenario you propose is valid. If I understood it correctly though, and I think that is what @uykusuz was getting at with it "sounding strange", XML3D should work without resorting to Xflow. Unfortunately the SVG analogy breaks down to some extent here, because there's no Xflow equivalent for SVG. The closest approximation I could find for that scenario in "pure" SVG (and which I would hope for an XML3D equivalent to exist), is accessing the referenced child documents in the manner proposed in http://stackoverflow.com/a/2997198/2740117
Again, animated assets are a valid proposition, but I think they're a vastly different use case from here and should be implemented and discussed separately. I even think one could implement a simple solution to the issue at hand on top of such an advanced system. (Basically omitting the Keyframe datapoint export.)
Small steps please, also +1.
Considering small steps:
Implementing group instantiation is most likely more work than implementing <datalist>
and <multimesh>
while the later solves both, the simple asset AND animated asset instantiation.
Right now XML3D is build on the assumption that each <mesh>
results in exactly one render object. As soon as we have group instantiation, this assumption doesn't work anymore.
The implication is, that each render node (group and meshes) need to store a list of world transformations and bounding boxes. The creation of render objects from the scene graph will have to be reimplemented in many parts.
In addition, we have to pay special attention to picking events. Picking events on instantiated <group>
nodes will need to point on the instantiating <group>
, not the internal <mesh>
node.
And these are just a couple of problems I just see right now when thinking about the implementation.
The difference is, that <group>
instantiation is an entirely new feature that requires a major reimplementation of the whole xml3d.js system.
<datalist>
and <multimesh>
on the other hand are basically syntactical sugar.
The implementation is mostly a separate system that does not require any changes in Xflow and only very few additions to the renderer implementation of xml3d.js.
So with respect to implementation overhead, <datalist>
+ <multidata>
are a smaller step compared to <group>
instantiation.
If I understand the various use cases correctly, wouldn't it be easiest to just retrieve the referenced group and add it to the DOM as a direct child of the group making the reference? We'd need to strip all IDs during the import to avoid duplicates in the DOM (or at least append some kind of numbered suffix), but at first glance I don't see this causing any problems. The imported object could still be given an ID by the user through the group node that references it. Eg:
<group id="firetruck_1" src="assets/models.xml #firetruck_model" transform="#ft1"/>
Aside from the code to import and append the referenced group structure nothing else would need to be done. In essence we're just saving the user the headache of having to request the asset, parse it and add it to the DOM himself. Since referencing assets (not just a single mesh element) is a very common use case I think it would be worth offering this shortcut, maybe even in addition to the new Xflow nodes lachsen proposes.
This approach is feasible to implement - but it is not a proper feature for an extension to HTML. It is very uncommon for an HTML declaration to automatically extend the DOM (in a way, that is accessible to the user afterwards).
It also comes with the disadvantage that this approach does not reduce the number of DOM nodes linked to the main document, which can have serious performance implication for larger scenes.
To me, this rather sound like an external library that can be used in combination with XML3D.
Just a quick comment: basic datalist and multimesh functionality is implemented. I still need to add further tests for dynamic changes and add some remaining features. But chances are high we'll have a working version in develop branch next week.
I got to my attention, that people don't like the way I was responding to this issue. I basically ignored the demands of the user and simply went ahead and implemented what I thought was right.
I understand that this is not the right way to handle issues and I'm sorry for that.
As a short explanation as to why I reacted the way I did:
I do the implementation of MultiMesh and DataList (without discussing the feature itself) to emphasize about the feasibility of the implementation and hopefully to demonstrate that it works well "in practice" (despite the less intuitive syntax).
In the end, MultiMesh+DataList are only a suggested approach (provided with implementation) on how to support complex assets within XML3D. It is not supposed to directly solve this issue.
Finally, note that none of this (neither MultiMesh+DataList nor Group Instantiation) fall into my PhD topic and are therefore not really my responsibility. I only implement MultiMesh+DataList because I myself believe it's the right approach. However, I can't decide whether it will go into the final specification or not.
In the end, MultiMesh+DataList can be just as well be rejected, even if there is an implementation.
Thus, I will not write about MultiMesh+DataList in this issue anymore. Just be aware that this is a potential alternative to Group instantation (that can still be implemented, afterall).
PS: The implementation of MultiMesh+DataList is almost done.
Similar to being able to reference shaders, transforms and meshes it should be possible to reference group nodes. Already in two applications we had to implement an xml parser that reads the group hierarchy and instantiates it in the target scene.
The referenced hierarchy can be completely inaccessible, I just want to instantiate an asset so to say.