Controlling Camera + Tips for Panda-newbie

Hi,
I’m a complete Panda-newbie with a few competed ‘tutorials’ from ‘documentation/manual’. :blush:

I’d like to ask you if someone has source code for moving camera (first person) - classic FPS camera -> w,s,a,d movement + mouse for direction.

I’d like to learn from these source codes and if there are some web pages with Panda tutorials or if exist any pages with Panda source codes please write me address.

thank you :wink:

How about it, anyone–surely one of you has written a camera controller like this?

I can also refer you to the code in direct/src/controls/NonPhysicsWalker.py and related classes. This is a fairly complex body of code, though, and it may be difficult to study it for examples.

David

Right - you named the problem, too comlex code. I’d like to study code as short and clean as possible :cry:

Well, if no one comes forward with a simpler example, perhaps you should take a hand at writing your own. :slight_smile:

It’s just a matter of listening for the appropriate keypress events (and keyrelease events) to keep track of which keys are currently being held down. Then, in a task, you can add the appropriate offsets to your position every frame according to what keys you know are being held. For instance, if the “w” key is currently down, you would do something like node.setPos(node, 0, 0.2, 0).

There should be examples in the manual and in the Panda sample programs that illustrate how to listen to keypress events and how to run tasks.

Ideally, you would use globalClock.getDt() to scale the amount that you move each frame, e.g. node.setPos(node, 0, 0.8 * globalClock.getDt(), 0). This will allow your movement speed to be independent of your simulation rate.

David

Ive not looked at anything like this yet, but through my travels I have spotted something which might help you get started.

In showbase is a function called oobe, Ill quote it from the source…

The code is pretty small and should be easy enough to read.
Its located in… pandaInstallDirectory/direct/src/showbase/ShowBase.py

Ive not tried this before but it does look interesting. Also check out the Manual, there is plenty of good info in there.

thanks a lot drwr + The_Sandman -> I’ll try what you suggest :laughing:

Personnally i extended the inputstate object from direct\controls.
I added two vars mouseX and mouseY that correspond at the polling of the mouse postion (as in airblade game).

So my dragon move left and right up and down only with mouse move.
However it’s not an fps like because no strafe and no moving on the ground.

For moving on the ground i prooftested the GravityWalker from Panda. Once stripped of some specific disney reference it works real good and cover

  • ground following
  • obstacle checking
  • jumping and strafing.

However i don’t use it in my current project…

Hello Manakel,

Could you, please, post an example of using GravityWalker?

Thanks.

Alberto

Hey guys, I thought you might want to look at this. Its a module I wrote for Half-life style camera control. It definitely needs more work, as well as the frame-rate independence that david talked about.

Unfortunately, it does not take into account ground geometry, or non-planar movement. If you take out the setZ(0) lines, you can get freerange, Descent-style control.



import direct.directbase.DirectStart
from pandac.PandaModules import *
from MouseControls import *
from direct.task import Task
from direct.showbase.DirectObject import DirectObject

#TO USE
#
#import hlview
#mouseControl=hlview.hlview()
#mouseControl.start()

#This is basically the drive mode with the ability to look up and down
#A version with keyboard navigation will be here too
#controls:
#Mouse looks around
#Left mouse button moves forward
#Middle mouse button toggles the control scheme
#Right mouse button moves backwards

class hlview(DirectObject):
    def __init__(self):
        self.m=MouseControls()
        base.enableMouse()
        #to allow mouse button navigation
        self.forward=False
        self.backward=False
        self.left=False
        self.right=False
        self.accept("q",self.toggle)
        self.running=False
        self.justHit=False
        self.speed=.1
        
    def setRunSpeed(self,speed):
        self.speed=speed
        
    def start(self):
        self.m.startMouse()
        base.disableMouse()
        par=camera.getParent()
        self.parent=par
        #Our base node that only holds position
        self.posNode=par.attachNewNode("PosNode")
        self.posNode.setPos(camera.getPos(par))
        #Two nodes that sits on posNode, and gives us directions
        self.forwardNode=camera.attachNewNode("forwardNode")
        self.forwardNode.setPos(0,.1,0)
        self.rightNode=camera.attachNewNode("strafeNode")
        self.rightNode.setPos(.1,0,0)

        
        #Orient the camera on the posNode
        camera.setPos(0,0,0)
        camera.reparentTo(self.posNode)
        
        #Task for changing direction/position
        taskMgr.add(self.camTask, "hlview::camTask")
        self.accept("w",setattr,[self,"forward",True])
        self.accept("w-up",setattr,[self,"forward",False])
        self.accept("s",setattr,[self,"backward",True])
        self.accept("s-up",setattr,[self,"backward",False])
        self.accept("a",setattr,[self,"left",True])
        self.accept("a-up",setattr,[self,"left",False])
        self.accept("d",setattr,[self,"right",True])
        self.accept("d-up",setattr,[self,"right",False])
        self.accept("mouse1",setattr,[self,"justHit",True])
        self.running=True       
    
    #call to stop control system
    def toggle(self):
        if(self.running):
            self.stop()
        else:
            self.start()
        
        
    #TODO: write a transform that allows for transition from hlview to 
    #trackball. In the end, probably should never allow the two to meet
    def stop(self):
        taskMgr.remove("hlview::camTask")
        camera.reparentTo(self.parent)
        
        #problem spot, base keeps a last position to update from that we 
        #need to change to the current pos
        #Unfortunately, transforming the position [i]and[/i] hpr such that
        #they conform to the trackball control scheme is no mean feat
        base.enableMouse()
        self.forward=False
        self.backward=False
        self.left=False
        self.right=False
        
        self.running=False
        self.m.stopMouse()
        self.ignore("w")
        self.ignore("w-up")
        self.ignore("s")
        self.ignore("s-up")
        self.ignore("a")
        self.ignore("a-up")
        self.ignore("d")
        self.ignore("d-up")
        self.ignore("mouse1")
    
    def camTask(self,task):
        #position change
        finalMove=Vec3(0,0,0)
        basePosition=self.posNode.getPos(self.parent)
        if(self.forward):
            #get derivative
            move=self.forwardNode.getPos(self.parent)-basePosition
            #and flatten it
            move.setZ(0)
            finalMove+=move
        if(self.backward):
            #get derivative
            move=self.forwardNode.getPos(self.parent)-basePosition
            #and flatten it
            move.setZ(0)
            finalMove-=move
        if(self.left):
            #get derivative
            move=self.rightNode.getPos(self.parent)-basePosition
            #and flatten it
            move.setZ(0)
            finalMove-=move
        if(self.right):
            #get derivative
            move=self.rightNode.getPos(self.parent)-basePosition
            #and flatten it
            move.setZ(0)
            finalMove+=move
        
        #The goal here is to make sure that pressing left and up doesn't
        #move you twice as fast 
        finalMove.normalize()

        #TODO: make the change in position scaled by dt, as david suggests
        finalMove*=self.speed
        
        self.posNode.setPos(self.posNode.getPos()+finalMove)
        
        if(not self.justHit):
            x=-self.m.mouseChangeX*.2
            y=-self.m.mouseChangeY*.1
            #orientation change
            camera.setH(camera.getH()+x)
            camera.setP(camera.getP()+y)
        else:
            self.justHit=0
        return Task.cont
    

[/code][/i]

zpavlov -
I’m very new to panda and python and I’m trying to test out your code provided above, but I get “ImportError: No module named MouseControls”
I’m going to assume that this is a module that isn’t by default included with Panda. Where can I get this module and is there any other non-standard modules I’ll need to get my hands on as well?
Thanks for you contributions!
-Justin DeVore