www.tombraiderforums.com

Go Back   www.tombraiderforums.com > Community Forums > General Chat

Reply
 
Thread Tools
Old 23-10-18, 21:29   #1
moodydog
Relic Hunter
 
moodydog's Avatar
 
Join Date: Jun 2006
Location: Middle of Somewhere
Posts: 9,313
Default Aaah need some maths/ programming help!!

Not sure if I should post this here, as it's quite niche and possibly a post that would alienate most people, but I would really like some assistance... just to make sure I'm going on right path, as I'm currently quite stuck.

If anyone has any knowledge of using openGL, or any linear algebra knowledge, please read on.

I'm following a course in openGL, and one of the assignments is about rotating the camera about an object by changing the coordinate frame of the camera. There is a skeleton code for me to fill in my answers. I've been given an empty function that when called, should rotate the camera left and right, and another than rotates the camera up and down. Both take in the arguments, float angle, vec3 eye and vec3 up. eye is the vector from the camera to the object, and up is the... vector pointing "up" at all times (the orientation vector).
I've also been given an empty function that performs the rotation, which takes in two arguments, float angle and vec3 axis.

Within the rotation function, I believe I need to provide the general form of the rotation matrix... which is:

R = I + sin($)K + (1 - cos($))K^2

where K is skew-symmetric.

With this, I have tried construction the above formula using the angle and axis arguements... which looks something like this...

Code:
	
mat3 rotationMatrix = mat3(0, axis.z, -axis.y, -axis.z, 0, axis.x, axis.y, -axis.x, 0);
	return mat3(1, 0, 0, 0, 1, 0, 0, 0, 1) 
		+ sin(degrees)*(rotationMatrix)
		+ (1 - cos(degrees))*(rotationMatrix)*(glm::transpose(rotationMatrix));
Now starting with the function that rotates the camera left and right, initially I had this which works fine, just the basic rotation formulas for rotation around y:

Code:
void left(float angle, vec3& eye, vec3& up) {
  float x = eye.x*cos(angle) + eye.z*sin(angle);
  float y = eye.y;
  float z = -eye.x*sin(angle) + eye.z*cos(angle);
  eye.x = x;  
  eye.y = y; 
  eye.z = z;
}
However, I would need to use the matrix above, and would need to use the "up" vector too.
I've assumed that the K vector is the axis argument, (hence K.x == axis.x etc), however, not sure how this relates to the eye/ up vector?

Apologies, this is a horrid explanation, which is why I'm kind of hoping someone out there has some experience in this, and vaguely knows what I'm on about.
__________________
joined the cult of Tumblr or something -Catapharact

Last edited by moodydog; 23-10-18 at 21:31.
moodydog is offline   Reply With Quote
Old 24-10-18, 02:38   #2
Catapharact
Tomb Raider
 
Catapharact's Avatar
 
Join Date: Jun 2005
Location: Canadiana
Posts: 22,187
Default

Before I assume anything, I take it that the "up" vector is being defined as the Yaw movement of the Camera?

If it is, then the Yaw orientation Euler Matrix would be:



So wouldn't the K value for the matrix in question be -Rz? That is, if we are using Eular Angles of rotation. I feel like you have missed quite a few steps in terms of what has been defined as what .
__________________
I am sorry for not offending you. Please be patient. I'll get to you shortly.

Last edited by Catapharact; 24-10-18 at 03:27.
Catapharact is offline   Reply With Quote
Old 24-10-18, 04:59   #3
Cochrane
Gold Contributor
 
Cochrane's Avatar
 
Join Date: Apr 2006
Location: Germany
Posts: 15,644
Default

If I understand the problem description correctly, the “rotate left right” function should:
- Call the Rotation matrix function to create a rotation matrix with the given angle around the “up” vector.
- Rotate the “eye” vector by that. Theoretically you'd also need to rotate the “hol vector by that but that is clearly unnecessary.

Rotating around the “up” vector is the key here, because “left”/“right” are only meaningful in relation to that. E.g. if your game is a flight simulator and you're flying straight up.

The “rotate up down” method needs to be similar, but rotate around the vector pointing locally to the right instead. You can get that one from the cross product of the eye and up vector instead (or was it up and eye vector? Can’t remember right now). Here you'll definitely need to rotate both eye and up vector.



I honestly can’t remember whether your rotation matrix code is correct, but it doesn’t look wrong at least. Yes, you do need the general version for a rotation around axis and angle here. Make sure you normalize the axis vector, either here or wherever you end up calling the function.


Sorry, not sure any part of that makes sense, I literally just woke up.



Edit to add: Okay, slightly more awake now, and I think what I wrote above should be sort of correct. I'm not familiar with the formula for the rotation matrix you gave, so I'm just going to assume you know what you're doing and it is the correct one (I think it may be equivalent with the one I know, I'd just have to do the maths to make sure, and I'm too lazy). Key is that for rotation around "left/right" (yaw) in screen direction, you need to rotate around the "up" vector; for rotation "up/down" (pitch) in screen coordinates, you need to rotate around the (model) the "right" (or left) vector. Rotation around the eye vector would be roll, by the way.

General coding note: In your matrix rotation function, you use the term "rotation matrix" for the matrix you generate from the axis. But it's not; the rotation matrix is the result. Give that variable some other name, even just "k" if you can't think of anything, because otherwise, this will confuse the hell out of you in the future.

Please let me know if anything is unclear or if I completely missed the point!
__________________
Güter auf die Bahn!

Last edited by Cochrane; 24-10-18 at 06:37.
Cochrane is offline   Reply With Quote
Old 24-10-18, 17:17   #4
moodydog
Relic Hunter
 
moodydog's Avatar
 
Join Date: Jun 2006
Location: Middle of Somewhere
Posts: 9,313
Default

Hey thanks for your replies... so as much as I also understand... the "up" vector is a vector that always points up. That is, imagine a camera with a pencil on top pointing upwards... whatever position the camera is pointing, is invariant to the pencil (which always points upwards).
i.e...



I'm currently working on it now again, and following your advice, I'll let you know if I get further with it.

I think the functions are confusingly named (I don't think the function "up" and the vector "up" are the same thing)
__________________
joined the cult of Tumblr or something -Catapharact
moodydog is offline   Reply With Quote
Old 24-10-18, 18:10   #5
Cochrane
Gold Contributor
 
Cochrane's Avatar
 
Join Date: Apr 2006
Location: Germany
Posts: 15,644
Default

No, the up vector should be perpendicular to the eye vector.

Does the rest of the code use the ever popular gluLookAt? In that case it doesn’t matter, because that will calculate its own accurate up vector from the approximate one that was passed in. But in the end, when the camera matrix gets calculated, you need an up vector that is perpendicular to the eye vector.

I strongly agree at the naming system is horrible.
__________________
Güter auf die Bahn!
Cochrane is offline   Reply With Quote
Old 24-10-18, 19:44   #6
Cochrane
Gold Contributor
 
Cochrane's Avatar
 
Join Date: Apr 2006
Location: Germany
Posts: 15,644
Default

I first wrote this as a reply to a PM, but I thought it may be generally useful as well:

Alright then, maybe I'll start this at the basics. Sorry if I repeat something here. To set up a camera, you need three vectors (well, four if it's also supposed to have a non-zero position, but the code of your exercise skips that so I will too). These three vectors are:
- "eye": The direction along which the camera is looking; where the lens of a physical camera would be pointed.
- "up": Where the upper part of a physical camera would be pointed.
- "right": where the right-hand side of a physical camera would be pointed.

These three vectors all need to have unit length, and they all need to be perpendicular to each other; in other words, they need to form an orthonormal basis. Not coincidentally, the matrix they form together is exactly the matrix you need to put a camera model at the exact camera place in world coordinates. Also, for OpenGL (and I think DirectX too?), they need to form a right-hand coordinate system, meaning the "right" vector really needs to point right and not left.

Thanks to these requirements, you can actually get away with fewer of these vectors. In particular:
- You always need the eye vector to be precisely what you want to look at.
- Nobody ever specifies the "right" vector, you can calculate that from the other two.
- You need to provide only a general sense of "up"ness, i.e. a direction that's similar enough to what the actual "up" vector will be. If, in your code, it will not be possible to turn the camera on its head, then using "global up" - that's (0 1 0) - is usually correct. Note: If you can turn the camera on its head, e.g. because you're doing a flight simulator and want to do a looping, this will no longer work; a better approximation there is usually "last frame's up vector". This problem even appears just when looking straight up or straight down.

Wit the "eye" vector and the general sense of "up"-ness, you can calculate the "right" vector as the cross product of those two. Having the "eye" and "right" vector, you can now calculate the real "up" vector as the cross product of right and eye (I think… may have gotten the order wrong). Don't forget to normalise after every step in this calculation.

The resulting matrix is formed of (right, up, eye) (if you have a "centre" position defined, it's (right, up, eye, centre) and a mat4). As I said above, that's where you'd put a model of the camera in world coordinates. Since you actually want to put the entire world into camera coordinates, your view matrix is the inverse of that matrix. That's literally all there is to it.


With that in mind: It seems like the rotation functions "left" and "up" take the eye and up vector and update them, which, you know, is not what I'd have done, but if it works for the instructors, okay.

In either case you need to use your Transform::rotate function. This creates a matrix that can be used to rotate vectors by a given amount around a given axis. The question then becomes "rotate around what?". For "left", it needs to rotate around the up vector. For "up", it needs to rotate around the "right" vector. As noted above, nobody stores that; you calculate it on demand as the cross product of eye and up.

In either case, multiply both vectors by the resulting matrix, and that should do the trick.

Note that this stuff took me years to understand, and I may be missing some parts here, so if you have any questions, just ask!
__________________
Güter auf die Bahn!
Cochrane is offline   Reply With Quote
Reply

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT. The time now is 14:57.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.