orbiting camera controls

Thought I should repost it here for others.
No credit needed.

MOUSE CONTROLS:

import direct.directbase.DirectStart
from panda3d.core import *

base.disableMouse() # disable default mouse controls

# hide mouse cursor, comment these 3 lines to see the cursor
props = WindowProperties()
props.setCursorHidden(True)
base.win.requestProperties(props)

# a scene
environ = loader.loadModel('environment')
environ.setScale(0.1)
environ.setZ(-5)
environ.reparentTo(render)

# model for the camera to orbit along
model = loader.loadModel('smiley')
model.reparentTo(render)

# dummy node for camera, we will rotate the dummy node fro camera rotation
parentnode = render.attachNewNode('camparent')
parentnode.reparentTo(model) # inherit transforms
parentnode.setEffect(CompassEffect.make(render)) # NOT inherit rotation

# the camera
base.camera.reparentTo(parentnode)
base.camera.lookAt(parentnode)
base.camera.setY(-10) # camera distance from model

# camera zooming
base.accept('wheel_up', lambda : base.camera.setY(base.camera.getY()+200 * globalClock.getDt()))
base.accept('wheel_down', lambda : base.camera.setY(base.camera.getY()-200 * globalClock.getDt()))


# global vars for camera rotation
heading = 0
pitch = 0

# camera rotation task
def thirdPersonCameraTask(task):
   global heading
   global pitch
   
   md = base.win.getPointer(0)
      
   x = md.getX()
   y = md.getY()
   
   if base.win.movePointer(0, 300, 300):
      heading = heading - (x - 300) * 0.5
      pitch = pitch - (y - 300) * 0.5
   
   parentnode.setHpr(heading, pitch,0)
   
   return task.cont

taskMgr.add(thirdPersonCameraTask, 'thirdPersonCameraTask')      
      
   
run()

WSAD CONTROLS:

import direct.directbase.DirectStart
from panda3d.core import *
 
base.disableMouse() # disable default mouse controls

# Load the scene.
environ = loader.loadModel('environment')
environ.setScale(0.1)
environ.setZ(-5)
environ.reparentTo(render)

# model for the camera to orbit along
model = loader.loadModel('smiley')
model.reparentTo(render)

# dummy node for camera
parentnode = render.attachNewNode('camparent')
parentnode.reparentTo(model) # inherit transforms
parentnode.setEffect(CompassEffect.make(render)) # NOT inherit rotation

keyMap = {"a":0, "d":0, "w":0, "s":0}

#Records the state of the arrow keys
def setKey(key, value):
   keyMap[key] = value

# the camera
base.camera.reparentTo(parentnode)
base.camera.lookAt(parentnode)
base.camera.setY(-10) # camera distance from model

def cameraMovement(task):
   if (keyMap["a"]!=0):
      parentnode.setH(parentnode.getH()-200 * globalClock.getDt())
   if (keyMap["d"]!=0):
      parentnode.setH(parentnode.getH()+200 * globalClock.getDt())
   if (keyMap["w"]!=0):
      parentnode.setP(parentnode.getP()-200 * globalClock.getDt())
   if (keyMap["s"]!=0):
      parentnode.setP(parentnode.getP()+200 * globalClock.getDt())
   
   return task.cont


taskMgr.add(cameraMovement, 'cameraMovement')

# camera zooming
base.accept('wheel_up', lambda : base.camera.setY(base.cam.getY()+200 * globalClock.getDt()))
base.accept('wheel_down', lambda : base.camera.setY(base.cam.getY()-200 * globalClock.getDt()))

# camera rotation
base.accept('a', setKey, ["a",1])
base.accept('a-up', setKey, ["a",0])
base.accept('d', setKey, ["d",1])
base.accept('d-up', setKey, ["d",0])
base.accept('w', setKey, ["w",1])
base.accept('w-up', setKey, ["w",0])
base.accept('s', setKey, ["s",1])
base.accept('s-up', setKey, ["s",0])
1 Like

I think you should be using base.camera rather than base.cam

I’m a noob, so not sure if its true, but that’s what I think.

Maybe i should, i dont know. I think base.camera is just a dummy child node of base.cam. If you know anything, do tell.

It’s the other way around. Alshain is correct.

well almost

so base.camera is sill a dummy node, but base.cam is the child instead.

The manual doesnt give any explanation for the purpose of having base.cam and base.camera as far as I know, only calls it a “convention”.
The only reason I see is the use of "Out of body experience (oobe):

Would like to know more about this.

Hi Anon,
Here is my take.

(1) As far as I understand base.camera is a node to which is attached the default camera (camera 0).

You can attach to base.camera other nodes, such as for instance additional cameras nodes with different lens properties. You can also switch each of them on/off. In this case base.camera would become a ‘camera rack’.

(2) As of “Out of body experience (oobe)”, I’d like to know more too!

Well, that doesnt really explain much.
Why do we need base.cam and base.camera?

For the sake of oobe(), for example. Another reason is that you can attach multiple cameras to base.camera that all update with the same position. (For example, if you wanted to manually make some sort of cubemap camera, you could attach five other cameras with different orientations.)

In general, you don’t need to mess with base.cam and you can just work with base.camera.

Well then my assumptions were correct.
I don’t really undertsand the second point though, you can have a common parent for 2 other nodes if you want them both to share transforms, but then again you could just make on the child of the other.

That would be another way to do it.