Point & Click Turning Bug!

Thankyou so much for this Russ. This time I was able to get the code working. But sadly, it’s still not doing what I want it to do :imp:.

The player now makes a small quarter turn in the direction of the click, which results in him sometimes moving sideways or even backwards to the clicked position (sometimes he turns and moves correctly too, it just depends on where you click :unamused:).

It’s kind of difficult to explain. So it’s probably better to show you. I don’t know if this is of any use, or even if you’d have the time to test it, but I’ve uploaded the models that I’m using to Rapidshare. So if you want to, you could take a look at it with the same models:

rapidshare.de/files/18379082/Tes … s.rar.html

And this is the new code (Note: The Fleet model isn’t animated, so I removed the animation references):

# This program turns a model to the position (point 3) of a left mouse click 
# on a 3d surface and then moves it to that position.

import direct.directbase.DirectStart # Start Panda 
from pandac.PandaModules import * # Import the Panda Modules
from direct.showbase.DirectObject import DirectObject # To listen for Events
from direct.task import Task # To use Tasks
from direct.actor import Actor # To use animated Actors 
from direct.interval.IntervalGlobal import * # To use Intervals
import math # To use math (sin, cos..etc)
from math import sqrt
from direct.showbase.PythonUtil import closestDestAngle
import sys  

class Picker(DirectObject): 
    def __init__(self): 
        base.disableMouse()
        # Position the camera
        camera.setPos(0, -35, 18) # X = left & right, Y = zoom, Z = Up & down.
        camera.setHpr(0, -25, 0) # Heading, pitch, roll.
        # Declare variables
        self.position = None
        self.playerMovement = None
        self.movementSpeed = 8.0 # Controls how fast the player moves.
        # Load an environment
        self.environ = loader.loadModel("MODELS/grass")
        self.environ.reparentTo(render)
        self.environ.setPos(0, 0, 0)
        self.player = loader.loadModel("MODELS/fleet")
        self.player.reparentTo(render)
        self.player.setPos(0, 0, 0)
        self.player.setHpr(0, 0, 0)
        self.player.setColor(Vec4(0, 148, 213, 1))
        self.npLook = self.player.attachNewNode("npLook")
        # Setup collision stuff. 
        self.picker= CollisionTraverser() 
        self.queue=CollisionHandlerQueue() 
        self.pickerNode = CollisionNode('mouseRay') 
        self.pickerNP = camera.attachNewNode(self.pickerNode) 
        self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) 
        self.pickerRay = CollisionRay() 
        self.pickerNode.addSolid(self.pickerRay) 
        self.picker.addCollider(self.pickerNode, self.queue)
        # Setup controls
        self.accept("escape", sys.exit) 
        self.accept('mouse1', self.moveToPosition)

    def getPosition(self, mousepos):
        self.pickerRay.setFromLens(base.camNode, mousepos.getX(),mousepos.getY()) 
        self.picker.traverse(render) 
        if self.queue.getNumEntries() > 0: 
            self.queue.sortEntries()
            # This is the clicked position. 
            self.position = self.queue.getEntry(0).getSurfacePoint(self.environ) 
            return None
        
    def moveToPosition(self):
        # Get the clicked position 
        self.getPosition(base.mouseWatcherNode.getMouse())
        # Calculate the new hpr
        self.npLook.lookAt(self.position) # Look at the clicked position.
        currHpr = self.player.getHpr()
        newHpr = self.npLook.getHpr(render)
        newH = closestDestAngle(currHpr[0], newHpr[0])
        # Create a turn animation from current hpr to the calculated new hpr.
        playerTurn = self.player.hprInterval(.2, Point3(newH, newHpr[1], newHpr[2]))
       
        # Calculate the distance between the start and finish positions.
        # This is then used to calculate the duration it should take to
        # travel to the new coordinates based on self.movementSpeed
        travelVec = self.position - self.player.getPos()
        distance = travelVec.length()
       
        playerMove = self.player.posInterval((distance / self.movementSpeed), self.position)

        self.playerMovement = Sequence(playerTurn, playerMove)
        self.playerMovement.start() 
        
p = Picker() 

run()

This has got to be one of the hardest and most frustrating things I’ve ever tried to do. I can’t tell you how much I appreciate your help with this. My respect and awe for game programmer’s has increased enormously.

Thanks heaps.