questions on handling AnimationClip and Skeleton

I have some questions about how to handle several aspects of a collada file:

In the documentation, it says that, when a collada file has Animation and AnimationClip, a default animation should only animate those Animation objects that are not referenced by AnimationClips. My question is, that includes all children of an Animation? In other words: if an AnimationClip references only one Animation object, but that Animation object has child Animations, should I include them as part of part of the AnimationClip (and discard them for default animation) or an AnimationClip should explicitly reference each Animation?

Another tricky scenario: in Collada, SceneNodes can be instanced, so a SceneNode hierarchy can be reused many times within the main scene. Now, what if we have a controller skin instance (within the main VisualSceneNode) that targets a skeleton node which happens to be a SceneNode in the NodeLibrary (that is, a SceneNode NOT in the main scene hierarchy, but a SceneNode intended to be instanced) How do we handle this? or it’s simply forbidden to do that?

thanks

V

Yes.

COLLADA is declarative so there are no “special cases” when it comes to instatiating the node hierarchy. I.e. it doesn’t matter where a node is declared within a .dae document (local or remote URL). Everything about the COLLADA scene is declared in local object space (a node is nothing more then a place) and is able to be instantiated (shared) many times without surprises. See Chapter 3 (pdf page 25) of the 1.5 specification.

As you build the scene(s) in your application, the (transform) path from your scene to each node of interest is what defines the local coordinate system for each place of instantiation… of geometry, controller, camera, node, etc… I.e. the <instance_*> element cherry-picks elements declared elsewhere in the document(s).

It’s the skin controller the one that’s giving me headaches; for example, when processing the MoonBuggy demo, the only way to make the whole thing to display correctly is to pass the world transform of the skeleton nodes to the skin controller, I’ve been unable to make it work with any other transforms combinations.

This is how my pipeline works:

I visit each node in the scene, at some point, I reach the node that holds the “moon buggy astronaut character” , since I am visiting each node recursively, I know from which node I come, so I am able to build a world transform of that node. Within the astronaut node, I find the instance_controller and a reference to a skeleton. Since in the “Moon Buggy” the skeleton node is also within the scene, there’s no problem either: I scan the scene from the root, until I find the skeleton node, and I build its world transform, so I can create the world transform of the child nodes too.

But, if the skeleton node is a node in a node library, it’s not associated to the scene root, so in theory, it would be unable to calculate a world transform from it, so I don’t know how this might be solved.

My Thougts are:

1- I may be doing something wrong with the skin transform, and, indeed, the transform of the skeleton root node is its own local transform (or always the identity matrix?), but, if that’s the case, how can, at some point, the parent node of the skeleton node affect the final result?

2- If the nodes of a skeleton are instanced, with an instance_node , and a controller targets directly the skeleton node (which is in the library, not in the scene), how the controller knows which instance_node to follow, to compute the world transform of the skeleton?

A practical example would be this: A scene in which a legion of soldiers march, all doing exactly the same synchronized movement, but each soldier in its own position. Instead of having to animate each soldier independently, a dae node would look like this:


<node_library>
     <node id="soldier_skeleton> type="JOINT"> skeleton bones here </node>
</node_library>

<scene>
<node id="Soldier1"> <instance_controller skeleton="#soldier_skeleton"> </node>
<node id="Soldier2"> <instance_controller skeleton="#soldier_skeleton"> </node>
<node id="Soldier3"> <instance_controller skeleton="#soldier_skeleton"> </node>
<scene>

In the example above, Soldier1,Soldier2 and Soldier3 have been positioned in different places of the scene, when I instantiate each soldier, how do I resolve the world transform of the skeleton? or this is a not well formed scene?

Hope this helped clarify my question.

Thanks

V

The example as shown has all three soldier nodes at the scene (world) origin as there are no transform elements. Let’s assume that you transform each one differently as you said.

Each and every node is a local coordinate system. The skeleton hierachy in the node library is in its own object space.

Each controller instance, strictly speaking, is invalid since there is no url attribute referring to the actual controller.

Have a look at instance_controller on pdf page 97, and object space skinning on pdf page 37, of the 1.5 spec. I think you want to pay particular attention to the explanation about “JMi” as it pertains to the destination object space of the skeleton.

Sounds like you are doing world space skinning, and so you have to (declare or) instantiate the root node of your skeleton “soldier_skeleton” in the root of the visual scene.

If I understood you correctly, what I should do is this:

1- I visit each node of the scene recursively, building the world matrix of each node as I visit them.

2- when I find a node with a skin instance controller, I lookup the skeleton root node, and I “virtually attach it” to the current node, so when I visit the joints, I am able to build their world matrices. This makes sense and effectively allows to reuse a skeleton in multiple instances.

Alas, I’ve been using “Moon Buggy” for testing and it does not look so well. If I do what you say (instancing the skeleton nodes within the context of the node that holds the instance controller) the head, hands and feet of the Moon Buggy astronaut appear way off their rights positions. But if I use the skeleton world matrices as they appear in the scene, everything looks fine! So one of the two: I might still be missing something, or the Moon Buggy scene is not right; Indeed I am doing world space skinning, but only because it seems to be the only way in which Moon Buggy looks correct (and since it’s supposed to be a reference object, I assume it’s been approved as a valid DAE)

Now, I have a funny feeling: the Moon Buggy example, uses IDREF_array in the Skin Controllers, so it’s binding directly to specific nodes in the scene.

Sooo… can it be that, if the skin controller uses IDREF_array, I must use the world matrix of the skeleton within the scene, but if the skin controller uses Name_Array to reference the bones, then I should use the instance_controller’s node as parent of the skeleton?

EDIT: After further review to the MoonBuggy(lunar_vehicle_tris.dae) file, I think it’s indeed wrong.

The scene has a node with id “back_root”, which is the root of a skeleton structure.
Then, there’s 7 nodes with skin controllers using it, these are the key values:



           <node id="_left_hand_left_hand" name="left_hand">
                <instance_controller url="#left_hand-lib-skin">
                    <skeleton>#left_shoulder</skeleton>

           <node id="_right_hand_right_hand" name="right_hand">
                <instance_controller url="#right_hand-lib-skin">
                    <skeleton>#right_shoulder</skeleton>

            <node id="geometries_5" name="geometries_5">
                <instance_controller url="#geometries_5-lib-skin">
                    <skeleton>#right_knee</skeleton>

            <node id="geometries_6" name="geometries_6">               
                <instance_controller url="#geometries_6-lib-skin">
                    <skeleton>#upper_back</skeleton>
                    
            <node id="geometries_7" name="geometries_7">                
                <instance_controller url="#geometries_7-lib-skin">
                    <skeleton>#upper_back</skeleton>
                    
            <node id="geometries_1" name="geometries_1">               
                <instance_controller url="#geometries_1-lib-skin">
                    <skeleton>#back_root</skeleton>
                    
            <node id="geometries_4" name="geometries_4">
                <instance_controller url="#geometries_4-lib-skin">
                    <skeleton>#left_knee</skeleton>


So, what’s happening is that the skins of the limbs are not targeting the skeleton root but joints inside of it, so when each skeleton is processed in its local space, it’s missing part of the transforms of its parent joints, which are neccesary to display it correctly; that’s why if I use local space skinning, the scene displays wrong, and it only works with world space skinning.

Funny enough, if I fix the scene, by simply changing all the <skeleton> tags to point to #back_root , and do local space skinning instead of world space skinning, the scene displays correctly, so that makes me thing the moon buggy scene is malformed and it can only work with world space skinning, I can’t think of another explanation

thanks

V

The moon buggy is a very old export (originally done in COLLADA 1.2 and 1.3 internally by Sony) and is probably not a good example. It’s also not an “approved reference object” by any means. Please use the Khronos COLLADA 1.4 Conformances Test Suite as your source for “reference” test data.

Yes a skin that uses IDREF are not so reusable as one using SIDREF. IDREF are not relative and so COLLADA designed SIDREF as a way to enable more sharing of instances (including skeletons). I.e. a skin that uses an IDREF_array does not even use the <skeleton> since it must search for ID attributes in XML document scope only.

Now, I have a funny feeling: the Moon Buggy example, uses IDREF_array in the Skin Controllers, so it’s binding directly to specific nodes in the scene.

Sooo… can it be that, if the skin controller uses IDREF_array, I must use the world matrix of the skeleton within the scene, but if the skin controller uses Name_Array to reference the bones, then I should use the instance_controller’s node as parent of the skeleton?
:smiley: