www.jpct.net

jPCT-AE - a 3d engine for Android => Support => Topic started by: AleNovi on May 27, 2017, 12:41:49 am

Title: Camera rotation
Post by: AleNovi 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 (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 (https://play.google.com/store/apps/details?id=com.tdcp.threedc) or this https://play.google.com/store/apps/details?id=jquinn.qubism.android (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.
Title: Re: Camera rotation
Post by: EgonOlsen on May 27, 2017, 05:01:34 pm
When is this method called and what is 'movement'?
Title: Re: Camera rotation
Post by: AleNovi 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 (http://www.jpct.net/wiki/index.php?title=MultiTouch_camera_controls)
Title: Re: Camera rotation
Post by: EgonOlsen 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?
Title: Re: Camera rotation
Post by: EgonOlsen 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?!
Title: Re: Camera rotation
Post by: AleNovi 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 (https://youtu.be/cEzp2dDiYgc)
During movement on the vertical axis, the camera is twitching
Title: Re: Camera rotation
Post by: AeroShark333 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 :)
Title: Re: Camera rotation
Post by: AleNovi 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?
Title: Re: Camera rotation
Post by: AeroShark333 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.
Title: Re: Camera rotation
Post by: AleNovi 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());
        }
Title: Re: Camera rotation
Post by: EgonOlsen 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/ (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...!?
Title: Re: Camera rotation
Post by: AleNovi 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);
}