Not able to click 3d objects and move them.

I want to click on the loaded models and move them around. I used the code from chess sample examples and panda 3d tutorial without any success. Can someone figure out whats wrong with the code.

Thanks

from math import pi, sin, cos
import sys
from direct.showbase.ShowBase import ShowBase
import direct.directbase.DirectStart
from direct.task import Task
from panda3d.core import TextNode
from direct.gui.OnscreenText import OnscreenText
from panda3d.core import CollisionTraverser, CollisionNode
from panda3d.core import CollisionHandlerQueue,CollisionRay
from panda3d.core import Point3,Vec3,Vec4,BitMask32
from direct.showbase.DirectObject import DirectObject
from panda3d.core import AmbientLight,DirectionalLight,LightAttrib

 
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

     
        # quit when esc is pressed
        self.accept('escape',sys.exit)

        #base.disableMouse()


        # load the box model
        self.box = self.loader.loadModel("models/xbox")
        self.box.reparentTo(camera)
        self.box.setScale(2.0, 2.0, 2.0)
        self.box.setPos(8, 50, 0)


        self.keyMap ={"w" :False ,"s" :False,"a":False,"d":False, "mouse1" :False, "mouse3" :False}


        # CollisionTraverser  and a Collision Handler is set up
        self.picker = CollisionTraverser()
        self.pq = CollisionHandlerQueue() 


        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))
        self.box.setCollideMask(BitMask32.bit(1)) 
        
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.picker.addCollider(self.pickerNP,self.pq)



        self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
        self.accept("mouse1",self.setKey,["mouse1",True])
        

    def mouseTask(self,task):
        # check if we have access to the mouse
        if base.mouseWatcherNode.hasMouse():

            # get the mouse position
            mpos = base.mouseWatcherNode.getMouse()

            # set the position of the ray based on the mouse position
            self.pickerRay.setFromLens(base.camNode,mpos.getX(),mpos.getY())
            self.picker.traverse(render)
            # if we have hit something sort the hits so that the closest is first and highlight the node
            if self.pq.getNumEntries() > 0:
                self.pq.sortEntries()
                pickedObj = self.picker.getEntry(0).getIntoNodePath()
                

    def setKey(self,key,value):
        self.keyMap[key] = value
 
   
app = MyApp()
app.run()

Hi there

I think you need to set the bitmask on your models:
self.box.setCollideMask(BitMask32.bit(1))
self.cube.setCollideMask(BitMask32.bit(1))
self.sphere.setCollideMask(BitMask32.bit(1))

@tah : thanks for the reply. I set bitmask on the models but it still doesn’t click on the models loaded and move them around. Any other thing I am missing ?

If you are basing your program off of one of the examples, it might be a good idea to compare your program with the example to see what is different.
Even better, make small changes and test as you go. When the program stops working as expected, then you only have a few lines of code to check for the problem.
This will make it a lot easier to find where the problem is instead of having to look at the whole program and figure out what it is doing.
For example if your program was 1000 lines of code, no one will be able to take the time to read the entire program to try and help.

in this bit:

pickedObj = self.picker.getEntry(0).getIntoNodePath()
picketObj = pickedObj.findNetTag('box')
if not pickedObj.isEmpty():
handlePickedObject(pickedObj) 

you want to only activate picking if the collided object has the tag ‘box’. But I think you’re missing the part where you actually set the tag on the box, or any of the other objects. Remove that requirement - it doesn’t matter much because you’re using bitmasks to control which things are pickable anyway.

Thanks teedee … i did start making changes to the sample code and ended up with the above code. I am newbie and its difficult in the first instance to understand what each line of code is doing. The main problem is I am not getting any errors and when i try to make changes to it I keep getting errors. Please if you can look up the code and find out I would really appreciate it .

@ benchang : Thanks for the reply . I have removed that part of code. Any idea why the selecting a model and moving in the world is not working

First of all, when you post, do you have the option “Disable BBCode in this post” checked? If so, that might explain why your quote- and code- blocks seem to break, leaving them a little more difficult to parse (the code blocks especially).

That said, am I correct in understanding that, at time of writing, the code in your first post is the entirety of your code for this purpose?

It so, then the main problem seems to be that you’re not doing anything with the object that you picked: You seem to have removed the last two lines of that block of code, the latter of which (“handlePickedObject(pickedObj)”) looks as though it would perform the relevant actions with your picked object.

That said, I also don’t see a “handlePickedObject” function. Perhaps it would help to reinstate that, and then take the filling out of that function a single step at a time: first have it simply print out the picked object to check that you’re correctly picking it, then have it set that object’s position to some specific point, then have it place the object at the current mouse position, etc.

Hi again

try this:

base.win.enableKeyboard()

Here is how you do it…

from math import pi, sin, cos
import sys
from direct.showbase.ShowBase import ShowBase
from pandac.PandaModules import *

 
class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

     
        # quit when esc is pressed
        self.accept('escape',sys.exit)

        #base.disableMouse()


        # load the box model
        self.box = self.loader.loadModel("models/xbox")
        self.box.reparentTo(render)
        self.box.setScale(2.0, 2.0, 2.0)
        self.box.setPos(8, 50, 0)


        #self.keyMap ={"w" :False ,"s" :False,"a":False,"d":False, "mouse1" :False, "mouse3" :False}


        # CollisionTraverser  and a Collision Handler is set up
        self.picker = CollisionTraverser()
        self.picker.showCollisions(render)
        self.pq = CollisionHandlerQueue() 


        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))
        self.box.setCollideMask(BitMask32.bit(1)) 
        
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.picker.addCollider(self.pickerNP,self.pq)



        #self.mouseTask = taskMgr.add(self.mouseTask, 'mouseTask')
        self.accept("mouse1",self.mouseTask)
        

    def mouseTask(self):
        print('mouse click')
        # check if we have access to the mouse
        if base.mouseWatcherNode.hasMouse():

            # get the mouse position
            mpos = base.mouseWatcherNode.getMouse()

            # set the position of the ray based on the mouse position
            self.pickerRay.setFromLens(base.camNode,mpos.getX(),mpos.getY())
            self.picker.traverse(render)
            # if we have hit something sort the hits so that the closest is first and highlight the node
            if self.pq.getNumEntries() > 0:
                self.pq.sortEntries()
                pickedObj = self.pq.getEntry(0).getIntoNodePath()
                print ('click on '+pickedObj.getName())

                

    #def setKey(self,key,value):
    #    self.keyMap[key] = value
 
   
app = MyApp()
app.run()
1 Like

10 posts were split to a new topic: Question about moving 3D objects