If you have the time, please help me with the following:
I would like to bind the attributes of one nodePath to a function of attributes of a collection of nodePaths.
Specifically, I would like to create a nodepath which will inherit the average position of two other “parent” nodepaths and update that average whenever the parents update.
I can do the following:
node1 = render.attachNewNode("1")
node2 = render.attachNewNode("2")
childNode = render.attachNewNode("child")
childNode.setPos( (node1.getPos()+node2.getPos())/2 )
but the child node won’t update when node1 & node2 update.
I can bruteforce this by calling childNode.setPos() whenever I call node1.setPos(), but this can become cumbersome, especially if I want to inherent from 100s of “parent” nodes.
You could create a task in which you set the position of the child node every frame.
Yes this is the bruteforce method I currently have implemented, but it isn’t as elegant as I’d like: if I’m averaging over 100 nodes, I would have a 100 line codeblock (or a hundred line list of parents) to iterate over.
Anyway, when you do something like
It will update the child’s attributes when the parent’s are updated.
I guess I want something like
Just to complete this thread, I found the simplest solution was to use the panda messenger system.
I define createNode and updateNode methods to send and accept messages via the messenger (this manual page needs some work)
#Create a node and listeners for a list of virtual Parents
def createNode(realParent, virtualParents = , *args, **kwargs):
childNode = realParent.attachNewNode(*args, **kwargs)
if '_messengerName' in kwargs:
for parent in virtualParents:
self.accept(parent._messengerName+' updated', self.updateNode,[childNode])
#can accept more calls
#Update a node and send a message (which the children will hear)
def updateNode(node, *args, **kwargs):
####Do some updates
self.messenger.send(node._messengerName + ' updated')