Render Tree Data

Hi,
I need to have a few lists of different objects for my game. So far, I have linked them all in a well constructed tree. I would like to know what is the best way to change the status of some node in the tree. How can I get the one child I want to modify with render.getChild(n).getChild(n) calls? Do I have to keep a reference to every single model in a list to modify each one of them separately?

Well, storing a handle to the nodes that you plan to modify is one answer, and unless you have thousands of nodes to deal with, it may be a particularly easy answer (Python handles this well). It’s also the only way to retain any Python-specific information that you may have attached to the nodes (for instance, by subclassing from NodePath, as is done with the Actor interface).

But for just retrieving ordinary nodes, there are also other good options. The easiest way to find a particular node is to use the nodePath.find() method, as documented in the manual under the topic “Searching the Scene Graph”.

David

Thanks,
So keeping references have to be done as in this code :


def createIcons():
    icons = ModelNode("Icons")
    node = NodePath(icons)
    node.reparentTo(render)
    iconList = {}

    patchX = 8
    patchY = 8

    for i in range(patchX):
        for j in range(patchY):
            data = EggData()
            vp = EggVertexPool('Cells')
            data.addChild(vp)
            
            polyA = EggPolygon()
            polyB = EggPolygon()

            data.addChild(polyA)
            data.addChild(polyB)

            v1 = EggVertex()
            v2 = EggVertex()
            v3 = EggVertex()
            v4 = EggVertex()
            v5 = EggVertex()
            v6 = EggVertex()
            
            v1.setPos(Point3D(    i,     j, 0.01))
            v2.setPos(Point3D(i + 1,     j, 0.01))
            v3.setPos(Point3D(    i, j + 1, 0.01))

            v4.setPos(Point3D(    i, j + 1, 0.01))
            v5.setPos(Point3D(i + 1,     j, 0.01))
            v6.setPos(Point3D(i + 1, j + 1, 0.01))

            v1.setColor(Vec4(0.1, 0.65, 1.0, 0.65))
            v2.setColor(Vec4(0.1, 0.25, 1.0, 0.65))
            v3.setColor(Vec4(0.1, 0.15, 1.0, 0.65))
            v4.setColor(Vec4(0.1, 0.15, 1.0, 0.65))
            v5.setColor(Vec4(0.1, 0.25, 1.0, 0.65))
            v6.setColor(Vec4(0.1, 0.65, 1.0, 0.65))
            
            polyA.addVertex(vp.addVertex(v1))
            polyA.addVertex(vp.addVertex(v2))
            polyA.addVertex(vp.addVertex(v3))
            polyB.addVertex(vp.addVertex(v4))
            polyB.addVertex(vp.addVertex(v5))
            polyB.addVertex(vp.addVertex(v6))

            polyA.triangulateInPlace(1)
            polyB.triangulateInPlace(1)

            nodeData = loadEggData(data)
            nodePath = NodePath(nodeData)
            nodePath.reparentTo(node)
            nodePath.hide()
            iconList[i + patchY * j] = nodePath
    node.reparentTo(render)
    return iconList

This function create a 2d patch of squares. Just to be sure, do I have to keep a reference to the iconList list to show / hide each cell?

It seem to me that accessing them through the render tree would be nice, as I would be able in reparent them and not caring of any pointer to them but render.

I would say keeping the iconList is the easiest and fastest way to do it. But you can also rely entirely on the render tree if you like.

For instance, instead of assigning the iconList, you could use the tag interface to indicate the index number of each node:


nodePath.setTag('index', str(i + patchY * j))

Then when you want to hide a particular cell:


root.find('**/=index=%s' % (indexNumber)).hide()

David

Thanks! That will help a lot!