springy camera

if ive got a player flying about in a jet, i need the camera to folow him. i can always set the camera’s position to something like 5 behind the player model. but the camera sticks there like glue. is it possible to make the camera more ‘springy’? how would i go about doing this?

i’d try something like this:

  • define a point where the camera should be (this is the point the camera has in your current implementation).
  • have the camera as a separate moving object, which moves towards that first point.
# dummy code
cameraTargetPos = pointBehindAircraft.getPos(render) # point behind the aircraft
cameraCurrentPos = camera.getPos(render)
cameraMoveVec = cameraTargetPos - cameraCurrentPos # or current - target?
camera.lookAt(cameraTargetPos)

# 0.1 is the factor how fast the camera follows this point, it's depending on your taste
camera.setPos(camera, cameraMoveVec * globalClock.getDt() * 0.1) 

still having trouble with this one. the code above caused the camera to drift backwards. i played around with it alot but its still not doing it for me. :frowning:

(IMHO)Your ship moves too fast and the cpu doesn’t allow to update it faster. One solution is to slow down the ship’s move and “accelerate” the other objects[size=75](if the ship moves z+1 instead of original z+2, then all other objects will have to move z-1)[/size].
Next solution is to “attach” the ship to the camera making the dummy-camera node being the parent of the ship. I think it would bypass some of the limitations.

Here’s an example how do I imagine that:

[size=117]camera node

…[/size]
…dummyNode[size=75](because attaching it directly to the camera would make problems)[/size][size=117]
…|
…|
…Ship


…Models, textures, sounds and etc.[/size]

i should have mentioned before: the ship isnt moving.

im expecting the camera to sit 5 units behind the player right now, and do nothing. but it just keeps floating backwards. i have no idea where this is happening.

        #empty node that the camera will get its Z pos and hpr from
        self.cameraHelperNP = self.playerShipNP.attachNewNode("Camera helper")
        self.cameraHelperNP.setPos(0,-5,0)
        #camera is assigned to a node
        self.cameraNP = render.attachNewNode("Camera")
        self.cameraNP.setPos(0,0,0)
        base.camera.reparentTo(self.cameraNP)

        
        taskMgr.add(self.updateCam,"updateCameraTask") 

   def updateCam(self,task):
        self.cameraTargetPos = self.cameraHelperNP.getPos(render)# point behind the aircraft
        self.cameraCurrentPos = self.cameraNP.getPos(render)
        self.cameraMoveVec = self.cameraTargetPos - self.cameraCurrentPo # or current - target?
        self.cameraNP.lookAt(self.playerShipNP)
        # 0.1 is the factor how fast the camera follows this point, it's depending on your taste
        self.cameraNP.setPos(self.cameraNP, self.cameraMoveVec * globalClock.getDt() * 0.1) 
        
        return Task.cont

i understand what it should be doing, but it isnt doing it.

base.disableMouse()
base.camera.setZ(ship.getZ()+5)

?

have you tried (as suggested in the “dummy code”) to replace target and current pos:

instead of:

self.cameraMoveVec = self.cameraTargetPos - self.cameraCurrentPo # or current - target? 

this:

self.cameraMoveVec = self.cameraCurrentPo - self.cameraTargetPos

ive swapped that. it does the opposite - flies off in the other direction.

besides, his one is correct. if im at a Y of 10, and his at a Y of 2, then i need to move -8 Y to reach him… or 2-10, or

 self.cameraMoveVec = self.cameraTargetPos - self.cameraCurrentPos 

i’ve put together a complete sample and found the errors in my code. the camera was moved relative to itself, while the movevec was in render coordinates.

from pandac.PandaModules import *

class X:
  def __init__(self):
    self.playerShipNP = loader.loadModel('misc/sphere.egg.pz')
    self.playerShipNP.reparentTo(render)
    
    #empty node that the camera will get its Z pos and hpr from
    self.cameraHelperNP = self.playerShipNP.attachNewNode("Camera helper")
    self.cameraHelperNP.setPos(0,-5,1)
    #camera is assigned to a node
    self.cameraNP = render.attachNewNode("Camera")
    self.cameraNP.setPos(0,0,0)
    base.camera.reparentTo(self.cameraNP)
   
    taskMgr.add(self.updateCam,"updateCameraTask")

  def updateCam(self, task):
    cameraTargetPos = self.cameraHelperNP.getPos(render)# point behind the aircraft
    cameraCurrentPos = self.cameraNP.getPos(render)
    cameraMoveVec = cameraTargetPos - cameraCurrentPos
    # 0.1 is the factor how fast the camera follows this point, it's depending on your taste
    self.cameraNP.setPos(cameraCurrentPos + cameraMoveVec * globalClock.getDt() * 0.95)
    self.cameraNP.lookAt(self.playerShipNP)
   
    return task.cont


if __name__ == '__main__':
  from direct.directbase import DirectStart
  
  base.disableMouse()
  base.camera.setPos(0,-10,0)
  x = X()
  
  base.accept('w-repeat', x.playerShipNP.setPos, [x.playerShipNP, Vec3(0,.1,0)])
  base.accept('a-repeat', x.playerShipNP.setHpr, [x.playerShipNP, Vec3(5,0,0)])
  e = loader.loadModel('environment.egg.pz')
  e.reparentTo(render)
  
  run()

press and keep pressed ‘a’ or ‘w’ to test.

my final problem is a very jittery camera. the camera sort of moves to the right spot for one frame, goes back a little for the other, and then repeats this. it works fine other than that, tracking the player perfectly… its just that the entire scene jitters back and forward as i move around.

edit:
please note that the camera can rotate fine. its all smooth when it rotates. however, a change in pos is what makes it jittery. (leaving me the conclude that the problem is at the step where we do the springy thing)

Didnt read that carefully the whole thread but maybe this is of some use:
A while back i neede a smooth camera movement that tracked a moving object smoothly by following it with a few steps behind(like lag), so what did i do:
I made the camera to lookAt the object. then i added a empty node and reparented it to the object. the empty nodes distance from the object was the minimum distance the camera could ever go(i added no maximum gap).
Then i did the following. i made the camera move half the distance closer to the point.(distance was the distance between camera and empty node).

I made the camera move cam.setPos(cam,xdist/speed,ydist/speed,zdist/speed), and it worked for me.
(its pretty much (objPos-camPos)/speed)
Speed is the speed at what it follows. Speed 2 was pretty fast, so if you wanted a smoother follow make it 6 or even bigger number if needed.

theoretically the cam will never reach the point, so if you wish at some point remove the rediculosly small calculations add:
if dist<0.1:
move(false)
else:
move(true)

thanks for trying to help but you pretty much summed up what we’ve just accomplished