Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (483)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (550)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Rotate camera around origin problem  (Read 2024 times)
0 Members and 1 Guest are viewing this topic.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Posted 2014-01-18 15:08:33 »

Hey guys!

I'm trying to rotate a camera around the global origin, as if it was moving on a sphere, maintaining the same length to the origin at all times. Like the movement that is typical for any 3D model-viewer.

It works great when just rotating around the y-axis, pointing upwards.
1  
2  
3  
4  
camera.rotateAround(
                new Vector3(0f, 0f, 0f),
                new Vector3(0f,1f,0f),
                1f);


The API is like this, for reference:
1  
2  
3  
4  
camera.rotateAround(
                point,
                axis,
                degrees);


However, when I want the camera to rotate upwards or downwards, I need to take care that the camera might already be rotated. Therefore, I can't just rotate around the x- og z-axis. I tried finding the perpendicular vector in 2D and rotating it around that, and that worked!
1  
2  
3  
4  
5  
6  
7  
camera.rotateAround(
                new Vector3(0f, 0f, 0f),
                new Vector3(
                      -camera.position.z,
                      0f,
                      camera.position.x),
                1f);


Here's the problem though: Whenever my camera is directly above or directly below the origin, this math breaks and I can no longer rotate. I'd like to, though. How can I solve this problem, so it doesn't break in these two cases?

Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Reply #1 - Posted 2014-01-18 16:23:03 »

It sounds like you are running into gimbal lock, which this video does a good job of explaining:

http://www.youtube.com/watch?v=zc8b2Jo7mno

The best solution to this is to represent your rotations by quaternions instead of Euler angles.  The math for those can be a little confusing at first, but once you get the hang of it you'll really like them.

Hello!
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #2 - Posted 2014-01-19 09:29:21 »

Thanks for the reply!

I tried using Quaternions instead, and it works.. kind of. When rotating the camera around itself, there are no problems. However, when I try to rotate it around the origin, the gimbal lock problem persists.

This is what I do.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
Quaternion quat = new Quaternion( // Assemble the quaternion from perpendicular vector
               new Vector3(
                      -camera.position.z,
                      0f,
                      camera.position.x),
                Gdx.input.getDeltaY() // This is supposedly the angle of rotation. I'm using the mouse to move the camera.
         );
camera.position.set(0f, 0f, 0f);
camera.rotate(quat);
camera.position.add(
                new Vector3(  // Moving the camera 10 units away, along the opposite vector of the cameras facing direction
                     -camera.direction.x,
                      -camera.direction.y,
                      -camera.direction.z).nor().mul(10f)
                );


The problem is probably how I make that quaternion, but I don't know how else I'd do it. I'm using LibGDX, by the way.  Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Roquen
« Reply #3 - Posted 2014-01-19 09:51:54 »

You can't get gimbal lock with quaternions...describe what camera control you're trying to implement.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #4 - Posted 2014-01-19 09:57:32 »

You can't get gimbal lock with quaternions...describe what camera control you're trying to implement.

There's an invisible sphere around the origin, on which the camera can move. The camera will always point to the center of the sphere (the origin). This creates the effect of rotating the actual world.

The reason I need this behavior, is that I need to be able to look at a model in the origin, from any angle.

Offline Roquen
« Reply #5 - Posted 2014-01-19 13:44:55 »

I'd say: arcball.  It's a nice start.  I like to modify it so that when you click-and-drag outside of the invisible sphere that camera rotates about the vector into the screen.  The combo makes it really easy to look at something in an arbitrary orientation.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #6 - Posted 2014-01-19 14:25:05 »

I'd say: arcball.  It's a nice start.  I like to modify it so that when you click-and-drag outside of the invisible sphere that camera rotates about the vector into the screen.  The combo makes it really easy to look at something in an arbitrary orientation.

I'm quite sure arcball is not what I am looking for. I find it very hard to control what I'm looking at, with that solution.

Is there anything wrong with the code I posted? Am I doing something wrong with the quaternions? It was a shot in the dark for me, using them, so I can't tell if I'm doing something horribly wrong.

EDIT: I just found out my implementation has the same annoying thing as arcball, where the whole scene is tilted and it's impossible to adjust this with the mouse. The gimbal lock also persists. I'm all ears about how to implement the camera without the silly gimbal lock.


Offline Roquen
« Reply #7 - Posted 2014-01-19 14:57:40 »

The mod I suggested is to deal with the tilt.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #8 - Posted 2014-01-19 15:12:09 »

I don't know how to implement this, then. I'd still do it the way I showed you, and that doesn't really work when I run it. Googling did nothing, as it seems I'm currently doing it correctly. Or maybe I can't clearly see what they are doing differently.
 
I don't know how I would implement your modification either.

Can you post some pseudocode, or be more specific about how an arcball is different from what I'm currently doing, or what I am doing wrong? Smiley

Offline Roquen
« Reply #9 - Posted 2014-01-19 15:19:51 »

I'll try to find time tom. (monday)
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Reply #10 - Posted 2014-01-19 16:26:36 »

Use this method to convert from a quaternion to a rotation matrix:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
public static Matrix4f rotationFromQuaternion(Quaternion q) {
   Matrix4f mat = new Matrix4f();

   float xSq = q.x * q.x;
   float ySq = q.y * q.y;
   float zSq = q.z * q.z;
   float wSq = q.w * q.w;
   float twoX = 2.0f * q.x;
   float twoY = 2.0f * q.y;
   float twoW = 2.0f * q.w;
   float xy = twoX * q.y;
   float xz = twoX * q.z;
   float yz = twoY * q.z;
   float wx = twoW * q.x;
   float wy = twoW * q.y;
   float wz = twoW * q.z;

   mat.m00 = wSq + xSq - ySq - zSq;
   mat.m10 = xy - wz;
   mat.m20 = xz + wy;
   mat.m30 = 0;
   mat.m01 = xy + wz;
   mat.m11 = wSq - xSq + ySq - zSq;
   mat.m21 = yz - wx;
   mat.m31 = 0;
   mat.m02 = xz - wy;
   mat.m12 = yz + wx;
   mat.m22 = wSq - xSq - ySq + zSq;
   mat.m32 = 0;
   mat.m03 = 0;
   mat.m13 = 0;
   mat.m23 = 0;
   mat.m33 = 1;
   return mat;
}


You can just multiply this matrix by your camera matrix and it will give you what you want.  org.lwjgl.util.Quaternion has the method Quaternion.setFromAxisAngle() for constructing a quaternion from a vector and an orientation.  My guess is that you should be using that.

Hello!
Offline Roquen
« Reply #11 - Posted 2014-01-19 17:04:14 »

It's a little more involved than converting a quat to matrix.  You have an initial quat prior to a mouse action which you need to compose with something that feels like a natural manipulation of the object (which is another quaternion) to get the new result.  Choose an axis based on the direction of the mouse-drag has never felt very good to me.
Offline DavidW

Junior Member


Medals: 3
Exp: 7 years



« Reply #12 - Posted 2014-01-19 19:12:13 »

That is a good point.  I guess it all depends on how his rotation method is actually implemented.  Are you using cross products to compute the up, forward, and right vectors of the camera?  If so, make sure that you are not taking a cross between two parallel vectors as this will output the zero vector and is an undesirable result.

Hello!
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #13 - Posted 2014-01-20 07:16:06 »

Thanks for the help guys!

The next section is about upward/downward rotation only. The vector to rotate about changes, because I'm also rotating around the y-axis (poiting upwards).

Currently, I'm finding the vector to rotate about, by taking the taking the x/z coords of the camera position, switching them around and negating the new x-coord.
This is to find the perpendicular vector to the camera position, in 2D space (the y-axis points upwards).

I imagine the problem arises when trying to define this perpendicular vector, when both the x-coord and z-coord are both zero (the case where the camera is directly above or below the origin). I think thats the reason it doesn't help to use the vector "as" a quaternion, because the vector will still never be assembled correctly.

Now, I think my problem comes down to this: How can I find this vector in a reliable way? A way that doesn't break in specific cases. Tongue

Offline Roquen
« Reply #14 - Posted 2014-01-24 09:04:09 »

Haven't had a time window yet to toss this together...just saying I remember and still plan on doing it.
Offline Roquen
« Reply #15 - Posted 2014-01-24 13:28:10 »

OK.  In the spirit of hack-and-slash, here's the 10 minute version.  Slight modified source of SHC as a test harness:

http://pastebin.java-gaming.org/f7d425d0481
http://pastebin.java-gaming.org/9f7d4420d84

Most likely very buggy and only standard arcball (without constraint support):

http://pastebin.java-gaming.org/7d42d640181

I've set the projected radius to .5 so that you can drag outside of the sphere easy to correct for tilt without any extra bells and whistles for evalulation purposes.  Somebody surely has a nice clean java version somewhere.
Offline Roquen
« Reply #16 - Posted 2014-01-24 16:45:49 »

Oh yeah...it doesn't even account for the screen aspect (so the sphere/circle is warped)...so all the controls ARE going to feel off.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CopyableCougar4 (15 views)
2014-08-22 19:31:30

atombrot (28 views)
2014-08-19 09:29:53

Tekkerue (25 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (15 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (61 views)
2014-08-11 02:49:23

BurntPizza (39 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (38 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!