I am Sjoerd, and I am new to Panda3D. First of all, a great thumbs up to the developers, thank you for this great program!
I am trying to learn how transformations work in Panda. I have programmed in OpenGL and I know about rotation matrices, but I cannot understand why my camera moves upon reparenting. Here is a snippet that reproduces the problem:
from direct.showbase.ShowBase import ShowBase
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.disableMouse()
# Load the environment model.
self.environ = self.loader.loadModel("models/environment")
# Reparent the model to render.
self.environ.reparentTo(self.render)
# Apply scale and position transforms on the model.
self.environ.setScale(0.25, 0.25, 0.25)
self.environ.setPos(-8, 42, 0)
### New code 1
self.camera.setPos(0,45,15)
self.camera.setHpr(180,-10,0)
### New code 2
print "before:"
print self.camera.getNetTransform(),
print self.camera.getPos(self.render)
node = self.loader.loadModel("panda")
self.camera.reparentTo(node)
print
print "after:"
print self.camera.getNetTransform(),
print self.camera.getPos(self.render)
app = MyApp()
app.run()
After adding “New code 1”, it works as expected, but adding “New code 2” moves the camera to the panda’s backside. The net transform doesn’t change, still it moves.
What am I doing wrong???
Thanks in advance,
Sjoerd
EDIT: for some reason, the new code doesn’t show up as part of init, but it should be.
Thanks for your answer, but I still don’t understand the whole thing. The model should be at the origin, so the global coordinates should remain (0,45,15), right?
Neither getNetTransform nor getPos(render) changes upon reparenting, but the screen does!
You have forgotten to reparent “node” under render. The camera determines what to render based on where it is parented in the scene hierarchy. In this case since “node” is not under render, it is off in it’s own separate hierarchy and the camera is rendering this instead of “render”. The camera has not actually moved, it just appears that way since the environment is not being rendered.
Thanks Teedee, I am understanding the problem better now. What I actually wanted to do is like this:
from direct.showbase.ShowBase import ShowBase
from panda3d.core import NodePath
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.disableMouse()
# Load the environment model.
self.environ = self.loader.loadModel("models/environment")
# Reparent the model to render.
self.environ.reparentTo(self.render)
# Apply scale and position transforms on the model.
self.environ.setScale(0.25, 0.25, 0.25)
self.environ.setPos(-8, 42, 0)
### New code 1
self.camera.setPos(0,45,15)
self.camera.setHpr(180,-10,0)
### New code 2
print "before:"
print self.camera.getNetTransform()
print self.camera.getPos(self.render)
node = self.loader.loadModel("panda")
node2 = NodePath("")
node.instanceTo(node2)
node2.reparentTo(self.render)
### New code 3
self.camera.reparentTo(node)
print "after:"
print self.camera.getNetTransform()
print self.camera.getPos(self.render)
app = MyApp()
app.run()
So, both the model instance and the environment show up in the scene if I add “New code 1” and “New code 2”, because both are reparented to render. However, if I add “New code 3”, the environment disappears again! How can this be?
OK, I think that I got it. Even if a model has only one instance, the scene will not find it by itself, and will not find a path to the render node.
So I must reparent the camera to an instance, not to the model itself.