Camera matching Object3d Z Axis

Started by .jayderyu, January 07, 2009, 12:33:44 AM

Previous topic - Next topic

.jayderyu

Ok so things are mostly going well. Outside of the other thread.

I've tried playing around with some of the axis, vectors, alligning.... but I can't seem to figure out how to make it work.

I'm trying to get the camera Z roation(ie looking at it from a 2d perspective) to rotate with the target object. So if I flip the target object upside down through rotation. I want the camera to match. So it seems like the object always is upright.


.jayderyu

Sorry, doesn't seem to do anything :(

Sorry it's in lua, but it's pretty basic.

   update = function()
     player = _global:get("player"); -- works
     _camera:align(player); -- no rotation when watching the object rotate. the object rotates a lot
   
     o = player:getOrigin(); -- works
     _camera:setPosition(o.x, o.y, -70.0); -- works. follows the object really well
     _camera:lookAt(player:getOrigin()); -- looks at the object really well
   end;

EgonOlsen

That's because lookAt() replaces the camera's rotation matrix that align() has already set...the two methods can't be combined in that way, because both of them create a new matrix. Isn't the align sufficient? Where's the point in aligning the camera and doing a lookAt right afterwards  ???

paulscode

I am also having a little difficulty visualizing what you are attempting to do here (perhaps a simple picture might help).  Are you trying to keep the camera's up-direction matching the target's up-direction while at the same time having the camera always point toward the target.

AGP

Some of this is Egon's. It's for my Rogue Squadron program. The camera is always behind the ship, wherever it goes or turns. Since I also don't know exactly what you want, I'm not sure if it will, but does that help?


     private void follow() {
Matrix matrix = xWing.getWorldTransformation().invert3x3();
camera.setBack(matrix);
camera.setPosition(xWing.getTransformedCenter());
camera.rotateCameraX((float)Math.toRadians(120));
camera.moveCamera(Camera.CAMERA_MOVEOUT, cameraToObjectDistance);
      }

paulscode

#6
-- EDIT -- Oops, my bad.  I didn't notice that it was AGP who wrote the last post.

AGP

I'm not the one who started the thread. Just trying to help him. And no, no problem. It works great.

.jayderyu

hmm, I thought I was clear, but clearly what I'm thinking needs to be relayed better since I don't need to fill in the blanks. Since I know what I'm thinking about :)

ok let's say I have my 2d Mario jump into the air. The camera moves up with Mario keeping Mario at the center of the screen. 2d Mario is rotated say 90 degress. So his head is now "east/right". What i'm trying to figure is how to keep the camera looking at mario, but rotate the camera so that 2d mario "appears" to be upright.

paulscode

#9
Just to make sure I am tracking, you want to be able to both rotate the object seperately from camera and also be able to rotate it in conjunction with the camera, correct?

One thing you could do is create a camera "pivot / satelite" type of setup, something like this (I am not at a computer where I can test this, so let me know if it doesn't work):

Varriables needed:
private Object3D cameraPivot = null;
private Object3D cameraSatellite = null;
private Camera camera = null;


Set up the camera assembly:
    private void initCamera()
    {
        cameraPivot = Object3D.createDummyObj();
        cameraSatellite = Object3D.createDummyObj();
        // distance you want the camera to start out:
        cameraSatellite.translate( new SimpleVector( 0, 0, -20 ) );
        cameraPivot.addChild( cameraSatellite );
       
        camera = world.getCamera();
        resetCameraPosition();
    }


Align the actual camera up with the camera satellite and pivot objects:
    private void resetCameraPosition()
    {
        SimpleVector look = new SimpleVector( cameraPivot.getZAxis() )
                                                                   .normalize();
        SimpleVector up = new SimpleVector( cameraPivot.getYAxis() )
                                                                   .normalize();
        camera.setOrientation( look, up );
        camera.setPosition( cameraSatellite.getTransformedCenter() );
    }


Make Mario a child of the camera Pivot:
cameraPivot.addChild( marioObject3D );

When changing Mario's position, move the cameraPivot (causes both Mario and the cameraSatelite to move):
cameraPivot.translate( someSimpleVector );
resetCameraPosition();


When rotating Mario around the X-axis or Z-axis (or whatever axis you want only Mario but not the cameraSatelite to rotate around), call rotate methods for marioObject3D:
marioObject3D.rotateX( someAngle );

But when rotating Mario around the Y-axis (or whatever axis you want both Mario and the cameraSatelite to rotate around), rotate the cameraPivot instead:
cameraPivot.rotateY( someAngle );
resetCameraPosition();


To "zoom in", move the cameraSatelite closer to the cameraPivot:
SimpleVector direction = cameraPivot.getTransformedCenter().calcSub( cameraSatelite.getTransformedCenter() ).normalize();
direction.scalarMul( someValue );  // how 'fast' to zoom (negative to "zoom out")
cameraSatelite.translate( direction );


Oh, and one more thing, if you also want to be able to rotate the camera seperately from Mario, you could create a "masterPivot", which both the cameraPivot and marioObject3D are a child of.  That way translating/rotating masterPivot affects both Mario and the Camera, while translating/rotating cameraPivot only affects the Camera.

.jayderyu

hmm I never thought about .addChild(). I'll try this out soon.

Though one thing I noticed. The marioObject in question is prone to the physics engine alot. So I don't actually know how much I move objects. So I tend to use .setOrigin() base on the current position the object is in the physics world.

EgonOlsen

Quote from: .jayderyu on January 10, 2009, 10:21:01 AM
hmm I never thought about .addChild(). I'll try this out soon.

Though one thing I noticed. The marioObject in question is prone to the physics engine alot. So I don't actually know how much I move objects. So I tend to use .setOrigin() base on the current position the object is in the physics world.
But the origin isn't taken into account when calculating parent-child-translations. You can switch to


obj.getTranslationMatrix().setIdentity();
obj.translate(<whatever>);


That should have the same effect as setOrigin(), but it will be taken into account in the calculations.

paulscode

One potential issue I thought of -- you will definitely need the camera alignment to take into account any parent rotations, so if you use the "masterPivot" idea that I mentioned above, you should use the code from AGP's 'follow' method, changing method 'resetCameraPosition' to something like this (I am unable to test this at the moment):
    private void resetCameraPosition()
    {
        Matrix matrix = cameraSatellite.getWorldTransformation().invert3x3();
        camera.setBack( matrix );
        camera.setPosition( cameraSatellite.getTransformedCenter() );
    }


Also, if you use that 'zoom' code I posted earlier, be sure to call 'resetCameraPosition()' (I forgot to type that in).

slenkar

I used AGP's method but the camera is upside down, can anyone help?

The ship is a md2 so is it the mesh that is upside down?

EgonOlsen

Quote from: slenkar on May 30, 2009, 03:57:06 AMThe ship is a md2 so is it the mesh that is upside down?
Maybe...how does it look like if you load the model without any further modifications, place it at 0,0,0, place the camera at 0,0,0 too and move the camera out until the model is visible?