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[0],newHpr[1],newHpr[2]))
playerTurn.start()
p = Picker()
run()
I’m really baffled by this one, so if anybody has any suggestions please advise me.
Cheers