Actors are more flattened than static objects?

In my current project, I use tags assigned in Blender to indicate various node-specific pieces of data–such as, relevantly to this thread, indicating that the node in question should use a specific custom shader.

For static objects, this seems to work well enough.

(Well, in the SDK, at least. I do worry a little that I’ll find it no longer working in a distributable build, after it’s been through egg2bam. Is that an issue?)

However, I’ve just found that, for at least one model, it doesn’t seem to work well for Actors.

Specifically, what seems to happen is this: The model in question has two nodes and an armature (that affects both nodes). If I “apply” the armature modifiers and export just the two nodes (thus making it static), calling “ls()” on the resultant NodePath indicates that it contains two GeomNodes, one of which has the intended tags. If I instead export the two nodes and their armature, with the armature modifiers intact (thus producing an Actor), I instead get a single GeomNode, containing two Geoms. The tags are, naturally, lost at this point.

Looking at the egg file, I think that the two nodes are intact, even in the “Actor” version. This suggests to me that the issue may be occurring on import, or perhaps later, under the influence of a “flatten” operation. (I would have to check whether I’m flattening after attaching objects like this. If so, however, it seems unexpected that an Actor would be affected differently by a “flatten” command than a “static” object.)

I could work around this, I imagine, by specifying (either via tags or in my level-editor) that the object in question should load a second, external object and parent it to a given joint. However, this is a bit more awkward than just exporting the whole thing.

What do you think? Where does the problem lie, and what might be done about it?

Yes, geometry under a <Dart> tag is loaded differently, at least by default, because of the special way that geometry needs to be organised for skinning to take place. This is why egg-optchar is usually needed in order to tag specific nodes to remain exposed when exporting an actor.

It sounds like you’ve hit a situation where the tags are getting lost even though they don’t need to. Could you attach a file that can be used to reproduce this situation?

Ah, fair enough, and thanks.

Sure! Here it is: (239.7 KB)


"armature.blend"–A Blender file containing two simple nodes, controlled by a basic armature. The nodes have separate materials–I found that without this measure, they were reduced to a single Geom.

"testArmature.egg"–The above model, exported with the armature.

"testStatic.egg"–The same, but with the “armature” modifiers having been applied and the armature itself excluded, to create a static model.

""–A simple test-program that loads the two models, places them within the default camera-view, and calls “ls()” on each.

This is the output of the calls to “ls()” from a run of the above-test program on my machine, I believe:

ModelRoot testStatic.egg T:(pos -2 15 0)
  GeomNode Plane (1 geoms: S:(MaterialAttrib)) T:m(pos -0.348504 0.185512 0.193137 hpr 90.1342 1.78351e-06 -39.7967)
  GeomNode Plane.001 (1 geoms: S:(MaterialAttrib)) [shader] T:m(pos 0.348504 -0.880022 1.47414 hpr 90.1342 1.78351e-06 -39.7967)
PandaNode Armature T:(pos 2 15 0)
  Character __Actor_modelRoot
    GeomNode  (2 geoms: S:(MaterialAttrib))

When I export the armature, and press shift+L in pview, I see

  ModelRoot armature.egg
    Character Armature
      GeomNode  (2 geoms: S:(MaterialAttrib))

which would suggest that the tags are completely lost upon loading an animated model, because the structure is flattened.

There is a small modification you can make to the .egg file, though: find the <Dart> { 1 } flag, and change the 1 to structured. If you load it now, you will see that it is not flattened, and the tag is preserved:

  ModelRoot armature.egg
    Character Armature
      PandaNode Bone T:m(...)
        PandaNode Bone.001 T:m(...)
      GeomNode Plane (1 geoms: S:(MaterialAttrib)) T:m(...)
      GeomNode Plane.001 (1 geoms: S:(MaterialAttrib)) [shader] T:m(...)

Would this work in your scenario?

Hmm… It seems that it sort-of works–and indeed, I can go one better than hand-editing the files, I think, by altering my copy of YABEE to automatically use the “structured” value when I add a tag by that name to the armature.

That works as far as getting the nodes to be separate, and the tags to be retained.

However, it looks as though something then goes wrong with the movement of the tagged node. While it moves as expected in Blender, PView shows it moving… oddly. I’m not sure of quite what it’s doing, other than “not what I intended”.

If I replicate this with the simple blend file that I showed above by adding a simple, repeating animation to it, it looks as though the nodes are now rotating about their own axes, rather than around the joint-origins.

Having given it further thought, I think that I’m going to make the model a static object. In this specific case, the model is a small kitchen cupboard, with a marking on its door. As I don’t currently intend to keep anything inside the cupboard, it’s perhaps not a bad idea to make it non-interactive (albeit perhaps examinable).

Thus I think that the issue is no longer a problem for me, for the moment at least. It may come up again later, of course–we’ll see!

Thank you for your help, nevertheless! :slight_smile:

Another way to make it interactive is just to have the cupboard door as a separate object with its pivot point at the hinges, and in your code, you can find() the door part and use a LerpHprInterval to swivel it. The same can be done with drawers. This may be more efficient than vertex animation depending on the situation.

That’s not a bad idea, thank you. :slight_smile:

In my case, I don’t think that animations are proving to be a major source of performance issues–likely because I really don’t have all that many, I think. In addition, I find that it’s easier to add detail to skeletal animations–a slight pause near the start of an opening animation, or a bounce after dropping a lid, for example.

That said, I do actually have an case in which I do something such as you describe: I have “sliding door” objects (which have found use beyond just doors) that do a soft lerp from one position to another. I don’t use intervals for them, confessedly–I’ve generally been a little shy of intervals. Instead, I use some simple Python code.

(It hadn’t occurred to me to use something similar for my non-sliding doors, I think.)