Mouse picking for terrain

Hi, I’m still struggling with picking/collision issues. What is the most common way to perform picking points on the terrain? There is no collision solid that resemble height fields.

Also, I’ve been trying to do something like this, largely by hacking away from the Chessboard tutorial, but nothing really seems to work.

    def SetupPicker(self):
        # Custom traverser
        self.picker = CollisionTraverser()
        # handler Queue
        self.pq = CollisionHandlerQueue()
        # Collision Node
        self.pickerNode = CollisionNode('mouseRay')
        self.pickerNodePath = camera.attachNewNode(self.pickerNode)
        # Collide Mask
        self.pickerNode.setFromCollideMask(BitMask32.bit(1))
        # Ray
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        self.picker.addCollider(self.pickerNodePath, self.pq)
        
        taskMgr.add(self.mouseTask, 'mouseTask')
        
    def mouseTask(self, task):
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            
        self.picker.traverse(render)
        if self.pq.getNumEntries() > 0:
            self.pq.sortEntries()
            print self.pq.getEntry(0).getIntoNode().getTag('flag')
            
        return task.cont

    def MakePickable(self, NP, tag, value):
        NP.node().setIntoCollideMask(BitMask32.bit(1))
        NP.node().setTag(tag, str(value))

The problem seems to be that although mouseTask runs, nothing ends-up in the CollisionQueue even through the terrain and other objects all are passed through “MakePickable”. calling self.pickerNode.show() doesn’t do anything. I can’t really see what is done in the Chessboard tutorial that isn’t in my code.

Anyone can help?

(Please note: This is said based on my current knowledge of Panda, which is not yet advanced, I don’t believe. ^^; )

Could you not create a CollisionPolygon version of your terrain, run your collision test based on that using a collision queue, and, in your collision handling, sort the queue and use the result of the “getSurfacePoint” method in the first collision entry?

[edit]
If you want a particular vertex (as I imagine that you do) rather than simply the clicked-on point, then take the x- and y- coordinates of the result of getSufacePoint and find or calculate the terrain point that is nearest to that, ignoring the z-axis.

If your terrain has its points regularly-spaced, then this should be a fairly simple calculation (based on the origin point of the terrain, the spacing of the points, and the selected point, all in the x-y plane). If the points are not regularly-spaced, it becomes a little more complex, but still not overly so, I don’t believe.