Hi All, I hope you’ll forgive me for starting a new thread. I was going to add this to my original thread, but that one’s getting a bit long and I thought that this new post might get overlooked.
Anyway, I’ve made some progress on my point & click player controls. I think I’ve solved the problem of the model moving backwards to a clicked position. It seems that to work correctly, the model’s orientation must be set in your modeling package to face away from the camera (when I used a model that had been modeled and exported facing backwards, it worked a treat ).
But now I have a new problem. My code to make the player turn towards a clicked position, seems to have a bug in it.
This is what I want to happen. I click a position on the ground (the red X represents the clicked position).
The player should make a half turn to the right and face in the direction of the clicked position:
But this is what actually happens. I click this position on the ground and the player makes a full turn in the opposite direction and then faces in the right direction.
If I click in the opposite corner the same thing happens:
The strange thing is, this only happens when I click in the bottom corners of the map. When I click in the top corners of the map it works just fine.
Anyhow, this is the code:
# This program turns a model to the position (point 3) of a left mouse click # on a 3d surface. 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 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 # 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)) # 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()) # This is the "start" position sPos = self.player.getPos() # Calculate the new hpr # Create a tmp NodePath and set it to the start position # Then make it "lookAt" the position we want to be at. # It will then create the hpr that we can turn to. a = NodePath("tmp") a.setPos(sPos) a.lookAt(self.position) # Look at the clicked position. newHpr = a.getHpr() # Create a turn animation from current hpr to the calculated new hpr. playerTurn = self.player.hprInterval(.2,Point3(newHpr,newHpr,newHpr)) playerTurn.start() p = Picker() run()
I’m really baffled by this one, so if anybody has any suggestions please advise me.