Hi All,
I hope somebody can help…
I have the following issue:
I create an empty node and attach another two nodes to the left and to the right. Then I attach the first node to the model and apply the billboard effect (setBillboardPointWorld()). I want to have usual model in the center and two controlling models on the right and on the left that would rotate around and show always one side for the camera.
But when I’m trying to detect the collision using mouse click, I see that collision mesh is not rotating the same way as the visible geometry, or something like that. Seems like this effect only rotates visible geometry and leaves the collision mesh on the same place.
Is it possible to use this effect and be able to correctly detect the models?
I created simple example of my problem here http://www.ut.ee/~radan/example.zip
Just click to the arrows on the left and on the right.
I tried to search for the solution in the forum but wasn’t successful.
Code for reference:
from direct.showbase.ShowBase import ShowBase
from pandac.PandaModules import CollisionRay,CollisionNode,GeomNode,CollisionHandlerQueue,CollisionTraverser,LineSegs
from direct.task import Task
class World(ShowBase):
def __init__(self):
ShowBase.__init__(self)
#load models
self.circleModelNext = self.loader.loadModel("models/circle2")
self.circleModelPrev = self.loader.loadModel("models/circle2")
circlePrev_tex = self.loader.loadTexture("textures/circle_next_tex.png")
circleNext_tex = self.loader.loadTexture("textures/circle_back_tex.png")
self.circleModelNext.setTexture(circleNext_tex, 1)
self.circleModelPrev.setTexture(circlePrev_tex, 1)
self.circleModelNext.setScale(0.5)
self.circleModelPrev.setScale(0.5)
self.clusterModel = self.loader.loadModel("models/cluster")
cluster_tex = self.loader.loadTexture("textures/cluster_tex.png")
self.clusterModel.setTexture(cluster_tex, 1)
#collider set
self.setCollider()
#set mouse and camera
self.accept("mouse1", self.mouseSelect)
self.accept("mouse1-up", self.clearSelect)
self.camLens.setFov(80)
self.camCenter = self.render.attachNewNode('camCenter')
self.camera.reparentTo(self.camCenter)
self.camera.setPos(-20,5,10)
self.camera.lookAt(0,0,0)
self.disableMouse()
self.connecter = LineSegs("lines")
#draw X Y Z coordinate lines
self.connecter.setColor(1,0,0,0.3)
self.connecter.setThickness(1.0)
self.connecter.moveTo(0.0, 0.0, 0.0)
self.connecter.drawTo(25, 0, 0)
self.render.attachNewNode(self.connecter.create()) #X (RED)
self.connecter.setColor(0,0,1,0.3)
self.connecter.moveTo(0.0, 0.0, 0.0)
self.connecter.drawTo(0, 25, 0)
self.render.attachNewNode(self.connecter.create()) #Y (BLUE)
self.connecter.setColor(1,0,1,0.3)
self.connecter.moveTo(0.0, 0.0, 0.0)
self.connecter.drawTo(0, 0, 25)
self.render.attachNewNode(self.connecter.create()) #Z (PINK)
#self.camera.place()
self.genObject()
self.cameraTask = taskMgr.add(self.moveCam, "moveCam")
def genObject(self):
#one test instance of model with specific tags
cluster = self.render.attachNewNode('Cluster')
self.clusterModel.instanceTo(cluster)
center = cluster.attachNewNode('center')
next = center.attachNewNode('next')
prev = center.attachNewNode('prev')
self.circleModelNext.instanceTo(next)
self.circleModelPrev.instanceTo(prev)
next.setPos(-2,0,0)
prev.setPos(2,0,0)
next.setTag('type', 'cluster_control')
prev.setTag('type', 'cluster_control')
next.setTag('action', 'next')
prev.setTag('action', 'prev')
next.setTag('cluster','ref to cluster1')
prev.setTag('cluster','ref to cluster1')
center.setBillboardPointWorld()
def moveCam(self, task):
self.camCenter.setH(self.camCenter, 1)
return task.cont
#select 3D object by mouse click
def mouseSelect(self, showMenu = False):
if self.mouseWatcherNode.hasMouse():
mpos=self.mouseWatcherNode.getMouse()
self.pickerRay.setFromLens(self.camNode, mpos.getX(), mpos.getY())
self.mtraverser.traverse(self.render)
amount = self.colHandler.getNumEntries()
cnt = 0
if amount > 0:
self.colHandler.sortEntries() #this is so we get the closest object
found = False
while cnt < amount:
pickedObj=self.colHandler.getEntry(cnt).getIntoNodePath()
pickedObj=pickedObj.findNetTag('type')
if not pickedObj.isEmpty():
found = True
cnt = amount #set flag to stop loop
type = pickedObj.getTag('type')
if type == 'cluster_control':
#controlling cluster
action = pickedObj.getTag('action')
if action == "next":
print action
#not good idea but only for this test
self.circleModelNext.setColor(0,1,0,1)
if action == "prev":
print action
#not good idea but only for this test
self.circleModelPrev.setColor(0,1,0,1)
cnt = cnt + 1
if not found:
print "collision list didn't have nodepath with 'action' type"
else:
print 'Nothing found!'
def clearSelect(self):
self.circleModelNext.setColor(1,1,1,1)
self.circleModelPrev.setColor(1,1,1,1)
def setCollider(self):
self.mtraverser = CollisionTraverser()
self.colHandler = CollisionHandlerQueue()
self.pickerNode = CollisionNode('mouseRay')
self.pickerNP = self.camera.attachNewNode(self.pickerNode)
self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
self.pickerRay = CollisionRay()
self.pickerNode.addSolid(self.pickerRay)
self.mtraverser.addCollider(self.pickerNP, self.colHandler)
#self.mtraverser.showCollisions(render)
w = World()
w.run()