[SOLVED] change center position of camera?

I read it is possible, but how?
I simply want to rotate the camera along a model which is not in the center of the camera view.
Like here:

PS. No I cant simply rotate the model itself.

Example:

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *

environment = loader.loadModel("environment")
environment.reparentTo(render)
environment.setScale(0.1)

model = loader.loadModel("panda")
model.setScale(0.1)
model.reparentTo(render)
model.setZ(-0.5)
#model.setX(-0.3)

targetpoint = render.attachNewNode("targetpoint")

base.cam.reparentTo(targetpoint)
base.cam.setY(-5)

i = LerpHprInterval(targetpoint, 8, VBase3(360, 0, 0), VBase3(0, 0, 0))
i.loop()

run()

See that if I change the model’s x, it won’t work

Is ‘nodal point’ even what I’m looking for?

A possible solution is to put an empty-node in middle of your scene, reparent the camera and the car to that empty so they will rotate with it. Then rotate your car arround itself.
This will give the illusion that your car is fixed!

No that wont work

If you move the the mouse the interval stops and the camera starts to move with the mouse, rotating around the model.

The nodal point is not what you’re looking for.

I bet you could rotate the model if you really wanted to. But still, you don’t have to rotate the model to achieve this effect. Just put the camera on a long arm, and rotate the arm. Like this:

arm = model.attachNewNode('arm')
camera.reparentTo(arm)
camera.setPos(0, -20, 0)
camera.setHpr(0, 0, 0)
arm.hprInterval(4, hpr = (360, 0, 0), startHpr = (0, 0, 0)).loop()

It’s also similar to the example in the solar system demo, except that you put the camera where the planets are, and you put the model where the sun is.

David

I wonder why it is difficult for me to visualise this in my head. I have done similar things many times.

Anyway, thanks.

Oh, I forgot why this didnt work for me,

See if I just do this, but allow the players to zoom close or far from the model, this how it will end up:

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *

environment = loader.loadModel("environment")
environment.reparentTo(render)
environment.setScale(0.1)

model = loader.loadModel("panda")
model.setScale(0.1)
model.reparentTo(render)
model.setZ(-0.5)

targetpoint = render.attachNewNode("targetpoint")

base.cam.reparentTo(targetpoint)
base.cam.setPos(2, -10, 0)
base.cam.setHpr(0, 0, 0)

#targetpoint.hprInterval(4, hpr = (360, 0, 0), startHpr = (0, 0, 0)).loop()

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

base.accept('w', lambda : base.cam.setY(base.cam.getY()+1))
base.accept('s', lambda : base.cam.setY(base.cam.getY()-1))

# camera rotation task
def thirdPersonCameraTask(task):
   global heading
   global pitch
   global targetpoint
   
   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
   
   targetpoint.setHpr(heading, pitch,0)
   
   return task.cont

taskMgr.add(thirdPersonCameraTask, 'thirdPersonCameraTask') 

run()

I just added these lines:

base.accept('w', lambda : base.cam.setY(base.cam.getY()+1))
base.accept('s', lambda : base.cam.setY(base.cam.getY()-1))

Use w and s to zoom.

That’s because the camera has X offset.
You should change its heading instead, so on zoom it moves perfectly along Y and it won’t go off the model.

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *
import os

base.disableMouse()
environment = loader.loadModel("environment")
environment.reparentTo(render)
environment.setScale(0.1)

model = loader.loadModel("panda")
model.setScale(0.1)
model.reparentTo(render)
model.setY(0.1)
modelCenter = model.getBounds().getCenter()

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

camera.setPos(modelCenter)
camera.setP(pitch)
base.cam.setY(-10)
base.cam.lookAt(model.getParent(), modelCenter+Vec3(2,0,1))

base.accept('wheel_up', lambda : base.cam.setY(base.cam.getY()+1))
base.accept('wheel_down', lambda : base.cam.setY(base.cam.getY()-1))
base.accept('escape', os._exit, [0])

# camera rotation task
def thirdPersonCameraTask(task):
   global heading, 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 = clampScalar(-170, -10, pitch - (y - 300) * 0.5)

   camera.setHpr(heading, pitch,0)

   return task.cont

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

I also clamped the pitch, you might not want that for 3rd person though.
I use mouse wheel to zoom.

Of course,
Thanks!

hi, i’ve been trying to get my camera setup correctly also this is just so frustrating.

In the above code it works for almost what I want it to do.

But maybe you can help me modify it a bit please.

I need the mouse to be active with the above code the mouse is just used for rotating but I need it to select menu options.

Second thing its is i need the camera to rotate down and up 360 with no problems right now it rotates only up and around but not down and around.

Any help would be great! I really just want the camera to rotate around the 0,0,0 world coordinats and zoom in and out thats it and it has become a nightmare!

As I said, I clamp the pitch so it doesn’t dive below ground. If you don’t want that, remove the clampScalar, look at the original code.

If you need to use the mouse for menu, stop the rotation task.

You should have a look at the “Code Snippets” section, or use the Search
[orbiting camera controls)

The problem with this method is that the center of the lense is still in the center of the display region, so the object is of course distorted by the lense, especially if you use higher fov values.

Also, I still would like to know if you can change the nodal point of a camera.

Right now if I want to change the center (pivot point) of a camera, I make an empty parent node for it, then position the camera.

Don’t confuse the nodal point with the pivot point.

You can’t change the camera’s, or any node’s, pivot point. This is a property of the kind of transform matrix that Panda uses, and it’s always the node’s (0, 0, 0) point.

A camera’s nodal point has nothing to do with its pivot point. The nodal point is a property of the lens, and it is the point at which the lens will focus parallel lines–or, the point-of-view from which the lens sees the world. It is normally (0, 0, 0), because that’s where you expect a lens to see the world from. It’s possible to move it by supplying a different matrix to the lens, but this is almost always a bad idea. It certainly won’t change the rotational behavior of your camera.

David

OK.

OK rotation behaviour left aside, what about my former question, isnt this what I’m looking for?:

I don’t understand your illustration, precisely. Your first image shows a head-on view of an object. The second image shows a view from a rotated angle. The third image shows the head-on view, offset to the side.

None of those images illustrate the kind of distortion you get from an object near the edge of a wide-angle fov, but it is true that this distortion is real. If you want to avoid it, one possibility is to pull the camera farther back, so that you need a lower fov. Another possibility is to go with an orthographic lens, which completely avoids fov distortion.

Or, if you really want to move the center of the lens to the left of the frame, then you’re talking about shifting the lens offset: base.camLens.setOffset(x, y). Try shifting it by small amounts, in the range -1 … 1, to see what happens.

David

look below

No no rotation is applied, only the x position of the monkeyhead is changed. Do you get it now?

You have to agree for real game these arent practical.

This might be it. Ill try it out

David
[/quote]

What you are describing is just the effect of using an FOV-based (“perspective”) lens, and drwr is correct that in order to reduce this effect you should use a lens with a narrower FOV. As an example the original image you posted of the car has been rendered with a narrow FOV, I would guess about 15 to 25 degrees.
Such a narrow lens would not be used for actual gameplay, except maybe a zoomed “sniper” view. Usually you would see something like 45 degrees for a third person camera or 60 degrees or so for a first person camera.
A 3D side-scroller is another case altogether, when it would be beneficial to use an extremely low FOV or orthographic lens.

Didnt drwr already say that? There is a way to change the center of the lense, which is the best solution for me.

Yes he did, and I specifically mentioned that fact. I was attempting to point out which of his solutions appeared to be the correct one for your situation after your reply to his post providing additional details as to the meaning of the image posted.

You say regarding changing the FOV “for real game these arent practical”, which is not the case, games can use many different FOVs for different purposes, even using more than one at the same time. As an example in first person shooter games often the “weapon and hands” model is rendered with a lower FOV than the rest of the game.

This gave me a bit of a chuckle since you have obviously decided that the best solution is one you have not tried yet. I am trying to be helpful here but maybe it is a waste if you will be so obstinate.