Attaching physical rotation to camera control

Is it a good idea to attach setAngularMovemet to rotate the BulletCharacterNode?Because I have some glitches with regular setH/Hpr.BulletCharNode’s rotation isnt synchronized with the player node.

Here is my code, I know it isnt correct.Camera slide when I stop it.My code is based on the enn0x’s sample.

def cameraTask(self, task):                                
        omega = self.pitch and self.heading

        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if base.win.movePointer(0, 100, 100):
            self.heading = self.heading - (x - 100)*0.2
            self.pitch = self.pitch - (y - 100)*0.2
        self.player.node().setAngularMovement(omega)
        return task.cont

Hmmm… I guess it is up to me to answer this post.

I don’t understand this sentence. setAngularMovement is a method of BulletCharacterControllerNode. What does “attach” mean here? Do you want to replace this method with some other methode? This is not possible, since the class is implemented in C++.

Which glitches? Maybe you found a bug, but without further information I don’t know where to look for a possible bug.

Likewise, I don’t understand this one. In my terminology the BulletCharacterControllerNode is the player node. Are you perhaps refereing to the Actor node (class Actor), which is the visual presentation of the character, and should be reparented to the BulletCharacterControllerNode?

What I think you want to ask for is perhaps that you want to use the translation part of the BulletCharacterControllerNode for positioning the visual character model, and the orientation part of this transform for rotating a thrid person camera. This is not a good idea. You are better of with an own node for the camera (which can be a child of the character node, of course, and thus moves with the character node).

http://www.filehosting.org/file/details/324466/bandicam_2012-03-25_21-56-28-303.avi
Sorry for my english, this vid will explain better.

I can’t use this download link.

rapidshare.com/files/3465248970 … 13-728.avi

the axes of LinearMovement rotate faster than camera, and they dont point at the same spot with the camera, so I want to move forward but instead my node moves where those axes point(randomly)

Ok, I was able to watch the video now. What I see is that your character rotates with high angular speed each time the camera rotates.

Now, have a look at you code:

self.player.node().setAngularMovement(omega)

The angular movement is the input signal for player rotation, so you are using the right method. The parameter omega is expected to be an angular velocity (in physics usually named omega). Angular velocity means “angle per time”, here “degrees per second”.

You pass the variable “omega”. Fine. So let’s see where you assign omega:

omega = self.pitch and self.heading

Huh? Both pitch and heading are numeric values, right? The logical operator “and” is nonsense here:

  • If pitch is 0.0 (evaluates to False) you will get 0.0
  • If pitch is not 0.0 you will get heading

And both pitch and heading are… angles, and not angular velocities.

Oh wait, the variables pitch and heading have misleading names. Everybody would expect angles (e. g. degree or radian)! But this is what you assigning:

self.heading = self.heading - (x - 100)*0.2
self.pitch = self.pitch - (y - 100)*0.2

Not angles, but still a measure of distance. Hence the huge rotation speed.

Conclusion: your problem is that you rotate the camera based on the pixel distance on the 2D screen. But in order to rotate the character you need an angular velocity (degrees per second).

If you have the “delta angle” then you get the angular velocity by divinding delta_angle / dt. So now you need the delta angle. One way would be to read the current heading of the Panda3D camera node, then rotate the camera, read the new heading of this node. The delta angle is the difference between old heading and new.

Thanks!now my code is working correctly.This is what I
come up with:

def cameraTask(self, task):
        dt = globalClock.getDt()
        md = base.win.getPointer(0) 
        x = md.getX() 
        y = md.getY()
        if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2):
            degree = base.camera.getH() -  (x - base.win.getXSize()/2)

        omega = degree/dt
        self.player.node().setAngularMovement(omega)
        return task.cont