Java-Gaming.org Hi !
 Featured games (84) games approved by the League of Dukes Games in Showcase (574) Games in Android Showcase (154) games submitted by our members Games in WIP (620) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Rotate camera around origin problem  (Read 2648 times) 0 Members and 1 Guest are viewing this topic.

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?

DavidW

Junior Devvie

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:

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!

JGO Ninja

Medals: 26
Projects: 3
Exp: 6 years

One for all!

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

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.

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.

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.

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.

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.

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

The mod I suggested is to deal with the tilt.

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?

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

I'll try to find time tom. (monday)
DavidW

Junior Devvie

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!
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.
DavidW

Junior Devvie

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!

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.

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.
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.
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.

 Riven (31 views) 2015-04-16 10:48:47 Duke0200 (43 views) 2015-04-16 01:59:01 Fairy Tailz (33 views) 2015-04-14 20:13:12 Riven (34 views) 2015-04-12 21:36:37 bus hotdog (50 views) 2015-04-10 02:39:32 CopyableCougar4 (52 views) 2015-04-10 00:51:04 BurntPizza (52 views) 2015-04-06 22:06:58 ags1 (54 views) 2015-04-02 10:58:48 Riven (53 views) 2015-04-01 18:27:05 ags1 (70 views) 2015-03-31 10:55:12
 theagentd 27x BurntPizza 17x wessles 15x 65K 11x kingroka123 11x Rayvolution 11x alwex 11x KevinWorkman 9x kevglass 8x phu004 8x Hanksha 7x SHC 7x Olo 7x ra4king 7x Ecumene 7x Roquen 7x
 How to: JGO Wikiby Mac702015-02-17 20:56:162D Dynamic Lighting2015-01-01 20:25:42How do I start Java Game Development?by gouessej2014-12-27 19:41:21Resources for WIP gamesby kpars2014-12-18 10:26:14Understanding relations between setOrigin, setScale and setPosition in libGdx2014-10-09 22:35:00Definite guide to supporting multiple device resolutions on Android (2014)2014-10-02 22:36:02List of Learning Resources2014-08-16 10:40:00List of Learning Resources2014-08-05 19:33:27
 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