|
|
|
Return to Scripting Issues
by doublereedkurt » Sun Sep 09, 2012 5:47 pm
So, I've basically followed two of the tutorials which work in isolation, but not together.
How to move the camera: self.camrea.setHpr / self.camera.setQuat
http://www.panda3d.org/manual/index.php ... the_Camera
(My code which copies this: https://github.com/doublereedkurt/roide ... y#L224-239)
How to detect clicks:
http://www.panda3d.org/manual/index.php ... 3D_Objects
(My code which copies this: https://github.com/doublereedkurt/roide ... y#L100-142 )
Everything works, except that the CollisionRay seems to be "left behind" by the camera moves. I'm hoping someone more experienced with the scene graph can point out what I need to do.
Do I need to add a node-path above the camera that both the CollisionRay and camera are reparented to so that they move in synch? Should I be moving the CollissionRay and camera in parallel?
The really weird thing is that the built-in camera controls work fine. (I tried looking at how the default camera controls are implemented, but that seems to be in C++, so copying that didn't seem like an option.) If anybody knows how the default camera controls are implemented, that would be helpful since they seem to work.
Thanks in advance for your help!
-
doublereedkurt
-
- Posts: 10
- Joined: Sun Jul 15, 2012 11:39 pm
by kurohyou » Mon Sep 10, 2012 7:36 pm
Do I need to add a node-path above the camera that both the CollisionRay and camera are reparented to so that they move in synch? Should I be moving the CollissionRay and camera in parallel?
You don't have to create another node - you can parent the collision node to the camera itself instead. That way you can move the camera without having to always call base.camera.getParent().
-
kurohyou
-
- Posts: 209
- Joined: Tue Jun 29, 2010 9:59 pm
-
by doublereedkurt » Mon Sep 10, 2012 7:56 pm
picker_node = CollisionNode('mouse_click_ray')
self.picker_node_path = self.camera.attachNewNode(picker_node)
So, I should be doing something else there?
Actually, in general I am confused -- CollisionNode.addSolid() is used to create the collision geometry. But, all scene graph manipulation is done via NodePaths, not Nodes right?
So, whats going on here? Can the same CollisionNode be in several different places in the scene graph? Or is collision geometry an exception to the normal rules about Nodes and NodePaths?
(BTW: thank you very much for the reply, I suspect I am thinking about Panda's API still in some fundamentally wrong ways, and once those are cleared up everything will go smoothly.)
-
doublereedkurt
-
- Posts: 10
- Joined: Sun Jul 15, 2012 11:39 pm
by Nemesis#13 » Mon Sep 10, 2012 8:25 pm
Under the hood the scene graph consists out of PandaNodes. The NodePath class is a handle for the PandaNode, which contains many convenience functions.
What is a bit confusing in your code is the assignment of attachNewNode(), which returns the attached node. The same node should already be saved in picker_node. When reparenting nodes or attaching existing nodes you usually don't carry about the return value.
Typical usage:
node1 = loader.loadModel("whatever.egg") # this returns a node path
node2 = NodePath("new empty node") # this does as well
node1.reparentTo(node2) # now node1 is a child of node2
-

Nemesis#13
-
- Posts: 1041
- Joined: Mon Aug 04, 2008 8:09 pm
- Location: Germany
by doublereedkurt » Mon Sep 10, 2012 9:54 pm
Thanks very much for the explanation.
Hmm... CollisionNodes don't seem to have a reparentTo?
>>> from pandac.PandaModules import CollisionNode
>>> c = CollisionNode('c')
>>> c.reparentTo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'libpanda.CollisionNode' object has no attribute 'reparentTo'
The tutorial also shows the use of attachNewNode():
http://www.panda3d.org/manual/index.php ... 3D_Objects
Maybe collision geometry works a bit differently?
I guess I'll try reading some more code.
-
doublereedkurt
-
- Posts: 10
- Joined: Sun Jul 15, 2012 11:39 pm
by kurohyou » Mon Sep 10, 2012 11:22 pm
If I remember correctly, CollisionNode is still just derived from PandaNode - so it's not a NodePath yet. So your code would in effect be doing this:
- Code: Select all
NodePath CollisionNode CollisionSolid01 CollisionSolid02 CollisionSolid03 etc
Eg: - Code: Select all
collSolid = CollisionSphere( 1 ) collNode = CollisionNode( 'collNode' ) collNode.addSolid( collSolid ) myNp.attachNewNode( collNode )
-
kurohyou
-
- Posts: 209
- Joined: Tue Jun 29, 2010 9:59 pm
-
by doublereedkurt » Mon Sep 10, 2012 11:34 pm
Is this:
- Code: Select all
node_path = parent_node_path.attachNewNode(my_node)
Equivalent to this: - Code: Select all
node_path = NodePath(my_node) node_path.reparentTo(parent_node_path)
I think this is the case: - Code: Select all
(Pdb) self.picker_node_path render/camera/mouse_click_ray
Hmm... is there a way to make collision solids visible for debug purposes? Or maybe I could attach a line segment as a sibling of the CollisionNode? I tried something a little bit along those lines, but had some troubles: - Code: Select all
#debug: make a visible line segment from pandac.PandaModules import LineSegs, LVecBase4f, NodePath seg_drawer = LineSegs() seg_drawer.setColor(LVecBase4f(1, 0, 0, 1)) #red seg_drawer.moveTo(0,0,0) seg_drawer.drawTo(0,100,0) NodePath(seg_drawer.create()).reparentTo(self.picker_node_path)
[/code]
-
doublereedkurt
-
- Posts: 10
- Joined: Sun Jul 15, 2012 11:39 pm
by doublereedkurt » Mon Sep 10, 2012 11:48 pm
iiiiiiinteresting (maybe)
If I reparentTo() the linesegs directly to self.camera, they show up; if they are reparentTo()'d the picker_node_path, they are invisible.
-
doublereedkurt
-
- Posts: 10
- Joined: Sun Jul 15, 2012 11:39 pm
by doublereedkurt » Tue Sep 11, 2012 12:24 am
Okay, I think the problem is not in the collision geometry, but in the camera moving.
I added this little debug thingie so I could press 'c' to get the current camera Hpr:
- Code: Select all
self.accept('c', lambda: sys.stdout.write(repr(self.camera.getHpr())+"\n"))
I discovered, with the default camera controls, the Hpr would change as expected. - Code: Select all
LVecBase3f(0, 0, 0) LVecBase3f(67.589, 44.3592, -27.9738) LVecBase3f(149.885, 20.7343, -74.9179) LVecBase3f(176.79, -65.4756, -66.9206)
However, when calling setHpr or setQuat on the camera in code, getHpr() on the camera would always report 0,0,0 - Code: Select all
LVecBase3f(0, 0, 0) LVecBase3f(0, 0, 0) LVecBase3f(0, 0, 0)
- Code: Select all
def camera_task(self, task): q2 = Quat() q2.setHpr( (0, task.time, 0) ) self.camera.setQuat(q2)
So, the problem is apparently that even though the display rendered appears to be moving, as far as the scene graph is concerned, the camera is not.
The collision geometry is working correctly, it is just being left pointed in direction (0,0,0) since the camera NodePath is not updating.
-
doublereedkurt
-
- Posts: 10
- Joined: Sun Jul 15, 2012 11:39 pm
by kurohyou » Tue Sep 11, 2012 1:34 am
Is this:
Code:
node_path = parent_node_path.attachNewNode(my_node)
Equivalent to this:
Code:
node_path = NodePath(my_node) node_path.reparentTo(parent_node_path)
Essentially, yes.
You should be able to show collision geometry by calling show() on the NodePath holding the CollisionNode. Parenting things to a hidden node will also cause them to hide, which may explain your linesegs issue.
With regards to your camera issue, are you transforming base.camera or base.cam? base.cam is the actual camera, base.camera is its parent. Try outputting the xforms of both these nodes to see what's going on.
-
kurohyou
-
- Posts: 209
- Joined: Tue Jun 29, 2010 9:59 pm
-
Return to Scripting Issues
Who is online
Users browsing this forum: Dolkar, Google [Bot] and 0 guests
| | |