Frame rate drop down using NodePath.setPos()

Bug #952815 reported by Alessandro
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Panda3D
Invalid
Undecided
David Rose

Bug Description

FORUM TOPIC REFERENCE: http://www.panda3d.org/forums/viewtopic.php?t=13099

OPERATING SYSTEM: Windows 7 home premium 32 bit, service pack 1, 4Gb ram, Video card: nVidia GTX260.
TESTED WITH "1.8.0" and with "Panda3D-2012.03.11-523.exe" (NIGHTLY BUILD)

THE PROBLEM:

I'm creating many objects (about 100000) not linked to "render" node. See this code:

--- CODE: -----------------------------------------------------------------

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        # Load the environment model.
        theBarrel = self.loader.loadModel("models/barrel.egg")

        cache = NodePath("cache")

        NUM_OF_OBJECTS = 222

        for x in range(NUM_OF_OBJECTS):
                for y in range(NUM_OF_OBJECTS):
                    placeholder = cache.attachNewNode("Barrel")
                    placeholder.setPos(x, y, 1) # <------------------------
                    theBarrel.instanceTo(placeholder)

        #cache.reparentTo(render)

app = MyApp()
app.run()

--- CODE: -----------------------------------------------------------------

I create many object instances attached to a main node called "cache". "cache" node is NOT attached to "render".
If I set the position of "placeholder" as (x, 0, 0) or (1, 1, 1) or (99, 11, 22) or (1, 9999, -9999) etc.... the program works.
If I set the position as (x, y, 1) the frame rate drops down incredibly (from 700fps to 150fps).

It seems there is a problem related to the 3D position of the placeholder. The problem is evident when I set the object position using at least two coordinates modified (in the previous case I use both "x" and "y").

This is a critical problem for me, in fact I need to create a big scenario off the "render" node (using "cache" node), then I will move the nodes from "cache" node to "render" node based on player position (imagine a scenario divided in sectors).

I made some tests using "pstats" and seems my program spend so much time in "app" task! It's crazy, since I have no background tasks, no heavy calculation. Furthermore my "cache" node is not rendered at all!

UPDATE: I noticed the problem is probably related to NodePath(), in fact even the following code has the same problem:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import *

--- CODE: -----------------------------------------------------------------

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        # Load the environment model.
        theBarrel = self.loader.loadModel("models/barrel.egg")

        cache = NodePath("cache")

        NUM_OF_OBJECTS = 222

        for x in range(NUM_OF_OBJECTS):
                for y in range(NUM_OF_OBJECTS):

                    # LOOK AT THE FOLLOWING CODE:
                    placeholder = NodePath("myPlaceHolder")

                    placeholder.setPos(1, 1, 1) # <---- GOOD PERFORMANCE

                    #placeholder.setPos(x, y, 1) # <---- POOR PERFORMANCE

app = MyApp()
app.run()

--- CODE: -----------------------------------------------------------------

Thank you!

Alessandro (ale870)
description: updated
description: updated
Alessandro (ale870)
description: updated
Revision history for this message
David Rose (droklaunchpad) wrote :

Short answer: add "transform-cache 0" to your Config.prc file.

Long answer: It's not a bug; it's just a misusage of Panda's transform cache. Because Transforms (4x4 matrices) can be relatively expensive to operate on--to multiply, invert, and/or decompose--and to make implicit coordinate-space transforms between nodes more efficient, Panda stores every Transform in the world in a reusable cache. This allows nodes that share the same transforms to reuse the same computations over and over again, instead of having to recompute them each time.

But when you create many thousands of nodes, each with a unique Transform; and you don't actually use those Transforms for any computations (or at least, not right away), then the overhead for maintaining that cache will dwarf any potential savings from the cache. In this case, you're better off not having a cache at all.

If you set "transform-cache 0" in your Config.prc file you tell Panda not to create a cache of Transforms, but rather to make each computation on-demand.

David

Changed in panda3d:
status: New → Invalid
assignee: nobody → David Rose (droklaunchpad)
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.