Skip to content

Instantly share code, notes, and snippets.

@ubald
Last active January 18, 2018 16:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ubald/f5ecf614fe1051d61fc732104da5cf99 to your computer and use it in GitHub Desktop.
Save ubald/f5ecf614fe1051d61fc732104da5cf99 to your computer and use it in GitHub Desktop.
Demostration of picking bug in Panda3D with changing geometry
#!/usr/bin/env python
import math
from direct.showbase.DirectObject import DirectObject
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from panda3d.core import CollisionHandlerQueue, CollisionNode, CollisionRay, CollisionTraverser, Geom, GeomNode, GeomTriangles, GeomVertexData, GeomVertexFormat, GeomVertexWriter, LVector3, PerspectiveLens, Spotlight
base = ShowBase()
base.disableMouse()
base.camera.setPos(0, 0, 0)
def normalized(*args):
myVec = LVector3(*args)
myVec.normalize()
return myVec
def makeSquare(x1, y1, z1, x2, y2, z2, square=None):
format = GeomVertexFormat.getV3n3cpt2()
vdata = GeomVertexData('square', format, Geom.UHDynamic)
vertex = GeomVertexWriter(vdata, 'vertex')
normal = GeomVertexWriter(vdata, 'normal')
color = GeomVertexWriter(vdata, 'color')
texcoord = GeomVertexWriter(vdata, 'texcoord')
# make sure we draw the sqaure in the right plane
if x1 != x2:
vertex.addData3(x1, y1, z1)
vertex.addData3(x2, y1, z1)
vertex.addData3(x2, y2, z2)
vertex.addData3(x1, y2, z2)
normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
normal.addData3(normalized(2 * x2 - 1, 2 * y1 - 1, 2 * z1 - 1))
normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
normal.addData3(normalized(2 * x1 - 1, 2 * y2 - 1, 2 * z2 - 1))
else:
vertex.addData3(x1, y1, z1)
vertex.addData3(x2, y2, z1)
vertex.addData3(x2, y2, z2)
vertex.addData3(x1, y1, z2)
normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z1 - 1))
normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z1 - 1))
normal.addData3(normalized(2 * x2 - 1, 2 * y2 - 1, 2 * z2 - 1))
normal.addData3(normalized(2 * x1 - 1, 2 * y1 - 1, 2 * z2 - 1))
# adding different colors to the vertex for visibility
color.addData4f(1.0, 0.0, 0.0, 1.0)
color.addData4f(0.0, 1.0, 0.0, 1.0)
color.addData4f(0.0, 0.0, 1.0, 1.0)
color.addData4f(1.0, 0.0, 1.0, 1.0)
texcoord.addData2f(0.0, 1.0)
texcoord.addData2f(0.0, 0.0)
texcoord.addData2f(1.0, 0.0)
texcoord.addData2f(1.0, 1.0)
# Quads aren't directly supported by the Geom interface
# you might be interested in the CardMaker class if you are
# interested in rectangle though
tris = GeomTriangles(Geom.UHDynamic)
tris.addVertices(0, 1, 3)
tris.addVertices(1, 2, 3)
if square is None:
square = Geom(vdata)
else:
square.clear_primitives()
square.set_vertex_data(vdata)
square.addPrimitive(tris)
return square
square = makeSquare(-1, -1, -1, 1, -1, 1)
snode = GeomNode('square')
snode.addGeom(square)
square_np = render.attachNewNode(snode)
square_np.setPos(0, 10, 0)
class PickingBug(DirectObject):
def __init__(self):
slight = Spotlight('slight')
slight.setColor((1, 1, 1, 1))
lens = PerspectiveLens()
slight.setLens(lens)
self.slnp = render.attachNewNode(slight)
self.slnp1 = render.attachNewNode(slight)
self._ray = CollisionRay()
self._ray.set_origin((0., -10., 0.))
self._ray.set_direction((0., 1., 0.))
self._collision_node = CollisionNode("collision_node")
self._collision_node.set_from_collide_mask(GeomNode.get_default_collide_mask())
self._collision_node.add_solid(self._ray)
self._collision_node_np = render.attach_new_node(self._collision_node)
self._collision_node_np.show()
self._collision_handler = CollisionHandlerQueue()
self._traverser = CollisionTraverser()
self._traverser.add_collider(self._collision_node_np, self._collision_handler)
self._traverser.show_collisions(render)
self._start_time = globalClock.getFrameTime()
taskMgr.add(self.pick)
def pick(self, _):
size = ((math.sin((globalClock.getFrameTime() - self._start_time) / 2.0) + 1.0) / 2.0) * 2.0 + 1.0
makeSquare(-size, -size, -size, size, -size, size, square)
if base.mouseWatcherNode.has_mouse():
mpos = base.mouseWatcherNode.getMouse()
self._ray.setFromLens(base.camNode, mpos.get_x(), mpos.get_y())
self._traverser.traverse(base.render)
return Task.cont
t = PickingBug()
base.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment