Author Topic: Camera rotation  (Read 5262 times)

Offline AleNovi

  • byte
  • *
  • Posts: 10
    • View Profile
Camera rotation
« on: May 27, 2017, 12:41:49 am »
Hi All!
I'm starting to develop an application that should display a 3D model, but i can't understand how correctly rotate camera around object.
I tried to use this guide http://www.jpct.net/wiki/index.php?title=MultiTouch_camera_controls but it not exactly what i need.
I want to rotate camera like in this app https://play.google.com/store/apps/details?id=com.tdcp.threedc or this https://play.google.com/store/apps/details?id=jquinn.qubism.android
Now i have this code to move camera, based on guide which i wrote above.
    private void moveCamera() {
        Movement movement = _movementhandler.getMovement();
        SimpleVector cam_pos = new SimpleVector();
        Object3D MyObject = one_layer.get(one_layer.size()/2);

        if (movement.hasMovement()) {
            Camera camera = world.getCamera();
            camera.getPosition(cam_pos);
           
            SimpleVector backVect = MyObject.getTransformedCenter();
            backVect.scalarMul(-1.0f);
            Matrix rotationmatrix = new Matrix();
            rotationmatrix.translate(backVect);
            rotationmatrix.rotateY(movement.cameraRotationY);
            rotationmatrix.translate(MyObject.getTransformedCenter());

            cam_pos.matMul(rotationmatrix);
            camera.setPosition(cam_pos);
            camera.lookAt(one_layer.get(one_layer.size()/2).getTransformedCenter());

            camera.moveCamera(Camera.CAMERA_MOVEUP, movement.worldRotationX*10);
            camera.moveCamera(Camera.CAMERA_MOVEIN, movement.cameraMovementZ);
        }
    }


The camera twitches during the rotation so I probably need to change the code.
Maybe someone knows good examples with the source code. I will be grateful for any help.

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Camera rotation
« Reply #1 on: May 27, 2017, 05:01:34 pm »
When is this method called and what is 'movement'?

Offline AleNovi

  • byte
  • *
  • Posts: 10
    • View Profile
Re: Camera rotation
« Reply #2 on: May 27, 2017, 06:52:58 pm »
This method called in onDrawFrame:
public void onDrawFrame(GL10 gl) {
               if (!stop) {
                    fb.clear(back);
                    mSkybox.render(world,fb);
                    world.renderScene(fb);
                    world.draw(fb);
                    moveCamera();
                    fb.display();
                } else {
                    if (fb != null) {
                        fb.dispose();
                        fb = null;
                    }
                }
        }


'movement' i took from this example http://www.jpct.net/wiki/index.php?title=MultiTouch_camera_controls

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Camera rotation
« Reply #3 on: May 28, 2017, 12:07:11 am »
I see... Looks fine to me at first glance. What exactly goes wrong. I'm not sure what you mean by twitching? Some glitch in the rotation that happens every now and then?

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Camera rotation
« Reply #4 on: May 28, 2017, 12:09:48 am »
And by the way: The HelloWorld example rotates an object on swipe as well, but I guess that's not exactly what you want?!

Offline AleNovi

  • byte
  • *
  • Posts: 10
    • View Profile
Re: Camera rotation
« Reply #5 on: May 28, 2017, 01:53:44 am »
The crux of the problem: that example turns the camera around its axis in single touch. In multi touch it moves camera left/right/up/down and in/out.
I need the camera to rotate around the object in the single touch mode.
I recorded a video for a visual display of the problem https://youtu.be/cEzp2dDiYgc
During movement on the vertical axis, the camera is twitching

Offline AeroShark333

  • float
  • ****
  • Posts: 319
    • View Profile
Re: Camera rotation
« Reply #6 on: May 28, 2017, 02:11:46 am »
Ah... I used to have an issue similar to yours, this is how I fixed it.
I avoid using the Camera.lookAt method because I think that's where the vertical twitching you described happens.

Anyway, my fix:

Create 2 variables for touch input:
private float touchX;
private float touchY;

In your touch listener:
touchX += some calculation for a dragging single finger;
touchY += some calculation for a dragging single finger;

In OnDraw:
camera.rotateX(touchY);
touchY = 0.0f;
camera.rotateY(touchX);
touchX = 0.0f;
camera.setPosition(someObjectYouWantToRotateAround.getTransformedCenter());
camera.moveCamera(Camera.MOVEOUT, someRadiusYouWantToRotateAroundTheObject);

Maybe not the neatest way but it worked for me :)
« Last Edit: May 28, 2017, 02:13:32 am by AeroShark333 »

Offline AleNovi

  • byte
  • *
  • Posts: 10
    • View Profile
Re: Camera rotation
« Reply #7 on: May 29, 2017, 01:57:18 pm »
Thanks for reply. I tried this method and camera not twitching but now i need to lock camera's z axis.
    private void moveCamera() {
        Movement movement = _movementhandler.getMovement();
        SimpleVector cam_pos = new SimpleVector();
        Object3D MyObject = one_layer.get(one_layer.size()/2);

        if (movement.hasMovement()) {
            Camera camera = world.getCamera();
            camera.getPosition(cam_pos);
            camera_z-=movement.cameraMovementZ;//variable to add distance to object
            camera.rotateX(-movement.worldRotationX);
            movement.worldRotationX = 0.0f;
            camera.rotateY(-movement.cameraRotationY);
            movement.cameraRotationY = 0.0f;

            camera.setPosition(MyObject.getTransformedCenter());
            camera.moveCamera(Camera.CAMERA_MOVEOUT, camera_z);
            camera.moveCamera(Camera.CAMERA_MOVEIN, movement.cameraMovementZ);
        }
    }

In other words, the camera should always look at the object having 0 degrees of rotation along the Z axis.
how to do it in best way w/o camera.lookAt?

Offline AeroShark333

  • float
  • ****
  • Posts: 319
    • View Profile
Re: Camera rotation
« Reply #8 on: May 30, 2017, 08:01:51 am »
Hmmm, perhaps it would work to keep a variable of the total rotation in X and Y.
And in onDraw clear the camera rotation everytime and apply the total (cumulative) X and Y rotations... (I think that should avoid getting a rotation in Z). (Clearing the rotation here means resetting te camera to the default rotation)

I don't really know how to do this otherwise, sorry.
« Last Edit: May 30, 2017, 08:04:26 am by AeroShark333 »

Offline AleNovi

  • byte
  • *
  • Posts: 10
    • View Profile
Re: Camera rotation
« Reply #9 on: June 15, 2017, 12:03:45 pm »
I made some tests and this code works fine except one thing - when camera's x rotate reaches +/- 90 degrees it twitches. I really don't know how to fix it. I tried to made limits (rotate camera's x only when summary angle in -1.56f<x<1.56f range) but there was one more bug - when i rotate camera's Y axis, X axis rotates too and my limit variable = 1.56f when real angle= 1.0f or less. Is there any way to get the current value of the camera's rotation angle except to create a variable that will sum the total rotation?
    private void moveCamera() {
        Movement movement = _movementhandler.getMovement();
        Object3D MyObject = one_layer.get(0);

        if (movement.hasMovement()) {

            Camera camera = world.getCamera();

            if(camera_z-movement.cameraMovementZ>10 && camera_z-movement.cameraMovementZ<200)
            camera_z-=movement.cameraMovementZ;

            camera.rotateX(-movement.worldRotationX);
            camera.rotateY(-movement.cameraRotationY);
     
            camera.setPosition(MyObject.getTransformedCenter());
            camera.moveCamera(Camera.CAMERA_MOVEOUT, camera_z);
            camera.lookAt(MyObject.getTransformedCenter());
        }

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12295
    • View Profile
    • http://www.jpct.net
Re: Camera rotation
« Reply #10 on: June 15, 2017, 01:17:43 pm »
There's calcAngle() in SimpleVector. You could use it to calculate the angle between, for example (1,0,0) and the vector returned by Camera.getXAxis(), but I'm not sure if this the best idea. Another way is described here: http://www.jpct.net/forum2/index.php/topic,2254.0/

Anyway, I'm still confused about what you actually need. Or in other words: I don't see the difference between the video example that you've posted and what the HelloWorld example does!? I'm not sure what exactly you mean by this single touch/multi touch thing...!?

Offline AleNovi

  • byte
  • *
  • Posts: 10
    • View Profile
Re: Camera rotation
« Reply #11 on: June 15, 2017, 02:33:08 pm »
Thank You very much! That was exactly what i needed!
I created limit in 1.56f and camera now don't twitches at 90 degrees.
SimpleVector limit_vector = new SimpleVector(0,1,0);
float angle = limit_vector.calcAngle(camera.getYAxis());
if(angle+Math.abs(movement.worldRotationX)<1.56f){
    camera.rotateX(-movement.worldRotationX);
    camera.rotateY(-movement.cameraRotationY);
} else {
    camera.rotateY(-movement.cameraRotationY/10);
}