want the rotating camera to always face an object in center

Hi,
this is what i was able to do:
rotate the camera in a circular motion.

this is what i want to achieve:
rotate the camera on a mouse click in a circular motion to face any object placed in the center.
i tried playing with the “H” factor of the HPR leaving me with the current code which rotates my camera too fast around its own axis and also the circular path around the object. This is my second panda program. Pl. guide.

Here’s the code as it exists now:

import direct.directbase.DirectStart
from direct.task import Task
from direct.actor import Actor
from pandac.PandaModules import*
from direct.showbase.DirectObject import DirectObject
import math
import sys

environ = loader.loadModel(“models/environment”)
environ.reparentTo(render)
environ.setScale(0.15,0.15,0.15)
environ.setPos(-8,42,0)

class World(DirectObject):

def __init__(self):
 
     base.disableMouse()
     self.angle= 90
     self.mov = 0
     
     self.accept("arrow_left", self.SpinCamLeft)
     
def SpinCamLeft(self): 
     base.camera.setPos(math.sin(self.angle)*50, math.cos(self.angle)*50,4)
     self.angle+= 0.1
     self.mov += 6
     if self.mov > 360:
        self.mov = 0
     base.camera.setHpr(self.mov,0,0)
     if self.angle > 360:
        self.angle= 0
        

def SpinCamRight(self):
     base.camera.setPos(-(math.sin(self.angle)*10), -(math.cos(self.angle)*10),3)
     self.angle-= 0.1
     
     if self.angle > 360:
        self.angle= 0

world = World()

run()

Hello,

I did not test your code because I am too lazy to do all the indention for each line myself. Using [ c o d e ] and [ / c o d e ] in forum posts makes it much more easy for others to test your code! They just have to copy and paste it to a file.

From looking at your code I see some strange things:

(1) math.sin( ) and math.cos( ) want an angle in radians, while Panda3D setHpr( ) wants degrees. I think this is why you increase self.angle by 0.1 and self.mov by 6.0. But: 0.1 radians is about 5.7 degrees. So the two rotations are not synchronized. One rotates faster than the other. Consider this:

math.degrees( 0.1 )

(2) Why do you first set the cameras position and then update the parameter that determines the position (self.angle), but for the cameras heading you do it the other way round, first increase and then set the heading. This would give a slight offset.

(3) Use a paper and pen to find out where your camera is for what value of “self.angle”, and then think about what heading would be required if you set x=sin, y=cos, z=0:

angle     sin(angle)    cos(angle)       heading
0            0                 1           +180
90           1                 0            +90
180          0                -1              0
270         -1                 0            -90

So there would be an offset to heading!

        h = 180.0 - math.degrees( self.angle )
        base.camera.setH( h )

Oh, and you can use np.setH( ) if you want to set only heading. Faster than setting heading & pitch & roll via setHpr( ).

(4) Instead of calculating the camera’s heading yourself (all the “self.mov” stuff), just make the camera look at the circle’s center:

base.camera.lookAt( 0, 0, 0 )

Putting everything together gives:

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
import sys
import math

class World( DirectObject ):

    def __init__( self ):
        base.disableMouse( )
        base.camera.setPos( 0, -50, 0 )

        self.accept( 'arrow_left', self.spinCamLeft )

        np = loader.loadModel( 'models/box' )
        np.reparentTo( render )
        np.setPos( 0, 0, 0 )

        self.angle = 0.0
        self.radius = 50.0

    def spinCamLeft( self ):
        self.angle += 0.1

        x = math.sin( self.angle ) * self.radius
        y = math.cos( self.angle ) * self.radius
        #h = 180.0 - math.degrees( self.angle )

        base.camera.setPos( x, y, 0 )
        base.camera.lookAt( 0, 0, 0 )
        #base.camera.setH( h )

world = World( )
run( )

Warning: This is not your code (see above), but something I slapped up to see if what I say is right. So copy and past to your code won’t work.

enn0x

why not just create a dummynode and reparent the camera to this node… just like in the solar system example^? :wink: