1

Description

I have three vectors d (forward vector), up and right as you can see here enter image description here.

p represents the position of the camera, d should always face straigt forward, right should face to the right and up should face up. I the camera gets rotated the three vectors should be updated, that they still face in the right directions. My coordinatesystem is: +x to the right, +y up and +z out of the screen:

enter image description here

Approach:

// create the three vectors
// Vector4f because opengl only allows to transform with Matrix4f
d = new Vector4f(0, 0, -1, 0);
right = new Vector4f(1, 0, 0, 0);

// create a transformation matrix
Matrix4f matrix = new Matrix4f();
matrix.setIdentity();
Matrix4f.rotate((float) Math.toRadians(cam.getPitch()), new Vector3f(1, 0, 0), matrix, matrix);
Matrix4f.rotate((float) Math.toRadians(cam.getYaw()), new Vector3f(0, 1, 0), matrix, matrix);
Matrix4f.rotate((float) Math.toRadians(cam.getRoll()), new Vector3f(0, 0, 1), matrix, matrix);

// Transform the 3 vectors with the matrix
Matrix4f.transform(matrix, d, d);
Matrix4f.transform(matrix, right, right);

up = Vector3f.cross(right.xyz, d.xyz, null);

// normalize them
d.normalise(); up.normalise(); right.normalise();

Problem

When the camera points in the direction of the x-axis the vectors are:

Cam Pos(-63, 15, 100) Cam Rot(0, 90, 15)

d(-1, 0, 0); up(0, 1, 0); right(0, 0, -1)

desired: d(1, 0, 0); up(0, 1, 0); right(0, 0, 1)

direction of z-axis:

Cam Pos(-15, -15, 51) Cam Rot(0, 0, 15)

d(0, 0, 1); up(0, 1, 0); right(-1, 0, 0)

desired: d(0, 0, 1); up(0, 1, 0); right(-1, 0, 0)

direction of y-axis (look in the sky)

Cam Pos(-11, -48, 104) Cam Rot(0, 90, -90)

d(-1, 0, 0); up(0, 0, -1); right(0, -1, 0)

desired: d(0, 1, 0); up(-1, 0, 0); right(0, 0, 1)

As you can see no coordinate is correct and I'm not sure, why not...

Maybe someone can figure out, what went wrong while rotating the vectors.

If you need more information feel free to ask and I'll edit the post


EDIT 1:

I got confused with the coordinatesystem. Now it's right.


EDIT 2: I made some progress and edited the source code and the examples. The result is much better, but still not right. For me it looks like a small mistake, maybe someone will find one. And is there a condition for the rotation? (for example only -180° to +180° or something like that?)

This is how my matrix look like (moved from comment by Spektre):

matrix

Spektre
  • 45,598
  • 10
  • 100
  • 347
Niklas
  • 109
  • 1
  • 10
  • 1
    Not sure that is the issue but the way you put it should `right` not be `(0,0,-1)`? I believe the following needs to be true: `cross(up, d) == right`. Anyway for your "wrong" example please provide testable scenario. So please provide `cam` values that you used in your example that produced wrong results. – Matic Oblak Apr 23 '18 at 14:01
  • Then the rotation might be off from what you expect. I am not sure what values are in your `cam` but if for instance `cam.x` represents a value that from user perspective turns left or right then the rotation must be done around "up", not around "right"... – Matic Oblak Apr 23 '18 at 14:08
  • Also be clear about creating the 3 camera vectors. Are these called every time (are they reset to original before new values are processed) because now it looks like they are part of some method but since you normalize them at the end we might expect they are initialized once and then the matrix multiplication is being called many times. If so then it is most likely the construction of your rotation matrix is wrong because you need to rotate around current base vectors. But this again depends on what you expect to have as a result. – Matic Oblak Apr 23 '18 at 14:14
  • Ok, I edited it. Now you also have Cam Pos and Cam Rotation. (cam.x is the x value of camera rotation ofc). To the first aspect: This would make sense but if you imagine that you stand at the origin (0,0,0). In my coordinate system d would go forward (in the screen) (1,0,0), up would go up (0,1,0) and then right has to go to the right (0,0,1). What am I missing? And has `cross(up,d)==right` to be true or `cross(d, up)==right`? – Niklas Apr 23 '18 at 15:23
  • Answer to your 3rd post: The 3 vectors are then used to calculate a view frustum (maybe you know it, for frustum culling). But they don't get changed I just use them for a few vector additions and scalar products and then call the method again next frame – Niklas Apr 23 '18 at 15:26
  • you can obtain your vectors directly from camera matrix see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214). You can even apply transform matrix on your vectors you just need to temporarily set the matrix origin to `(0,0,0)` so you do not offset the vectors. – Spektre Apr 24 '18 at 07:03
  • What do you mean by camera matrix? My only 2 matrices are projectionMatrix, viewMatrix (and transformationMatrix). Is this the same as a viewMatrix, or how do I get the camera matrix? And could you maybe explain your idea more in depth? :) – Niklas Apr 24 '18 at 09:07
  • I edited the post to be up to date. Seems like we got closer to the solution – Niklas Apr 24 '18 at 11:58
  • well I am talking about [`ModelView` matrix which is the multiplication of Model matrix (placing of rendered object in space) and View matrix (inverse of camera matrix)](https://stackoverflow.com/a/49841796/2521214). If you got just one matrix on CPU side (on GPU you can have just one) than you do not have direct access to your camera nor object placing other than in the right place in between the incremental transformation calls. Projection matrix hold just the projection (usually perspective) and does not have any relation to camera placing (otherwise you got projection matrix abuse) – Spektre Apr 24 '18 at 18:49
  • the last 3 links in the **Understanding 4x4 homogenous transform** I linked before deals with camera and player control which is most likely what you want to see ... – Spektre Apr 24 '18 at 18:51
  • Ahh I forgot, I also have a ModelView matrix. I have a modelMatrix with the cameras rotation, a viewMatrix and a modelViewMatrix. Im no sure, how I can extract the 3 vectors out of the modelViewMatrix. Could you explain it? – Niklas Apr 24 '18 at 21:06
  • you are using some `matrix4f` class I do not know (I do not code in JAVA) but if you can access individual cells of it see in which places the vectors and origin are located. The image in the link of mine is for OpenGL convention. The DirectX has it transponated. In pure OpenGL you can use `float m[16]; glGetFloatv(GL_MODELVIEW_MATRIX,m);` btw. to notify user `nick` present in the thread you should add `@nick` to your comment and site will notify the user automatically (not needed for author of the tread which is you here but for all others you should so we see you commented us) – Spektre Apr 25 '18 at 06:45
  • so the `x,y,z` axises and `o` origin are either first 4 columns in matrix (OpenGL) or rows (DirectX) ignoring the last element which holds `w` and projection. – Spektre Apr 25 '18 at 06:48
  • @Spektre my matrix is [this](https://ibb.co/fP8nwx). I guess, that the columns are `x,y,z` and `o`, aren't they? And this are my desired straight, up and right vectors? Because it seems that they are the negativ. Can this be because I didnt invert the viewMatrix? – Niklas Apr 25 '18 at 08:18
  • @Niklas render them and you will see. They can be both it depends on the multiplication order (`matrix*vector` or `vector*matrix`) is used and the order of matrix storage (row-major,column major) . So easier is to try one render and see if not OK than it is the other. to render the matrix just extract `X,Y,Z,O` and render lines `O,O+X*a` , `O,O+Y*a` and `O,O+Z*a` where `a` is size of the axises to render. The numbers suggest you are using rows (**DirectX** style) so origin is `O(47.5,-47.42,90.82)` I moved the image to this site into your question. It is better to have it here – Spektre Apr 25 '18 at 08:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/169760/discussion-between-niklas-and-spektre). – Niklas Apr 25 '18 at 12:35
  • @Niklas IIRC chat does not notify so you need to check it periodically on your own. I added some stuff there – Spektre Apr 25 '18 at 13:00

0 Answers0