Transformations in Panda3D, what am I doing wrong??

Hi everyone,

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.

You changed the node which the camera parented to…

self.camera.reparentTo(node) 

This code makes the camera position is (0,45,15) from the panda model position (which you called “node”)

Without adding that code then the camera position will be (0,45,15) in global coordinates

That’s why camera position changes

I recommend reading this page:
http://www.panda3d.org/manual/index.php/Scene_Graph_Manipulations

I wish that could help

Hi D_A_M_H,

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!

cheers

Sjoerd

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?

cheers

Sjoerd

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.

cheers

Sjoerd

Both the original and second script you have posted should work fine if you reparent “node” under render:

node.reparentTo(self.render)

There is no need to create an instance, unless you are using it for some other purpose.