Flattenning on Actors

actor = Actor("samples/Roaming-Ralph/models/ralph",
            {"run":"samples/Roaming-Ralph/models/ralph-run"})
actor.reparentTo(render)
actor.analyze()
actor.ls()
actor.flattenStrong()
actor.postFlatten()
actor.analyze()
actor.ls()

The results are different. Before:

3 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 0% of nodes have some render attribute.
2 Geoms, with 2 GeomVertexDatas and 2 GeomVertexFormats, appear on 1 GeomNodes.
4748 vertices, 4748 normals, 0 colors, 4748 texture coordinates.
GeomVertexData arrays occupy 158K memory.
GeomPrimitive arrays occupy 21K memory.
2374 vertices are unreferenced by any GeomPrimitives.
1 GeomVertexArrayDatas are redundant, wasting 5K.
3550 triangles:
  112 of these are on 36 tristrips (3.11111 average tris per strip).
  3438 of these are independent triangles.
1 textures, estimated minimum 768K texture memory required.

PandaNode Ralph
  Character __Actor_modelRoot
    GeomNode  (2 geoms: S:(ColorAttrib CullFaceAttrib TextureAttrib))

After:

3 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 0% of nodes have some render attribute.
2 Geoms, with 1 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 GeomNodes.
4748 vertices, 4748 normals, 0 colors, 4748 texture coordinates.
GeomVertexData arrays occupy 158K memory.
GeomPrimitive arrays occupy 21K memory.
2374 vertices are unreferenced by any GeomPrimitives.
3550 triangles:
  112 of these are on 36 tristrips (3.11111 average tris per strip).
  3438 of these are independent triangles.
1 textures, estimated minimum 768K texture memory required.

PandaNode Ralph
  Character __Actor_modelRoot
    GeomNode  (2 geoms: S:(ColorAttrib CullFaceAttrib TextureAttrib))

There is also different in performance. If I comment out flattenStrong parts in my instancing samples, the performance is significantly worse. It is the same for synchronous or asynchronous flattening (I implemented and tested both ways).

Hmm. Weird. So I don’t understand why you have to call actor.getChild(0) when you use the asynchronous version, or why actor.clearModelNodes() has any effect at all.

David

Probably, I didn’t explain myself well. actor.clearModelNodes() doesn’t make any effect. Both when I call it and not, I must use actor.getChild(0) with asynchronous flattening. Otherwise (if I pass actor itself or actor.getGeomNode()), animation is broken.
Here is the full sample I use for tests:

import sys
from pandac.PandaModules import *
from direct.actor.Actor import Actor
import direct.directbase.DirectStart

base.cam.setPos(render, 0, -20, 10)
base.cam.lookAt(0, 0, 0)

'''
# 1) Usual flattenStrong:
actor = Actor("samples/Roaming-Ralph/models/ralph",
            {"run":"samples/Roaming-Ralph/models/ralph-run"})
actor.reparentTo(render)
actor.analyze()
actor.ls()
actor.flattenStrong()
actor.postFlatten()
actor.analyze()
actor.ls()
actor.loop("run")
'''


# 2) asyncFlattenStrong:
def _onCallback(fmodel):
    actor.postFlatten()
    actor.loop("run")
actor = Actor("samples/Roaming-Ralph/models/ralph",
            {"run":"samples/Roaming-Ralph/models/ralph-run"})
#actor.clearModelNodes()
loader.asyncFlattenStrong(actor.getChild(0),
                        callback=_onCallback)
actor.reparentTo(render)
#actor.loop("run")


base.accept("enter", actor.analyze)
base.accept("escape", sys.exit)
base.accept("space", actor.loop, extraArgs=["run"])
run()