Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Jul 17, 2025 15:27

Foren-Übersicht » English » English Programming Forum
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 26 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Rotation Problem
BeitragVerfasst: So Aug 03, 2008 14:39 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
Bild

The problem i am having is that Rotations are applyed Localy rather than Globaly. The above image shows the problem. The Yellow arrow shows which direction it will be rotated when its matrix is Roll'd. Insted of rotating Globaly and always rotating around the same axis in the same direction, when its been rotated by Pitch/Yaw before applying Roll its rotation axis changes. Im wondering if anyone knows how to rotate a Matrix Globaly, or if anyone can see any bugs with the code im using. Due to the fact im also rendering to 2d Grids, i can't use the glmultmatrix command, so i have to apply all rotation "Manualy" using ApplyMatrixToVec3 when rendering/working out bounding box's/etc. Matrix_Roll, Matrix_Pitch and Matrix_Yaw are used to apply rotation to the matrix.

Note: Applying the Rotation to the actual vertex's and then setting the matrix rotation back to the IdentityMatrix would "Solve" the problem as far as i can see, but id like to keep the rotation in the Matrix so objects can always be reset to there default rotation easily(And without floating point errors). Some portions of code below are extracts from Sascha Willems glMatrixHelper unit.

Code:
  1. Function ApplyMatrixToVec3(M : TGLMatrixd4; V : TVec3) : TVec3;
  2. begin
  3.  Result[0] := ( V[0] * M[0,0] + V[1] * M[1,0] + V[2] * M[2,0] + M[3,0]);
  4.  Result[1] := ( V[0] * M[0,1] + V[1] * M[1,1] + V[2] * M[2,1] + M[3,1]);
  5.  Result[2] := ( V[0] * M[0,2] + V[1] * M[1,2] + V[2] * M[2,2] + M[3,2]);
  6. end;
  7.  
  8. function Matrix_Multiply(m1 : TMatrix4d; m2 : TMatrix4d) : TMatrix4d;
  9. var
  10.   r, c, i: Byte;
  11.   t: TMatrix4d;
  12. begin
  13. // Multiply two matrices.
  14. t := NullMatrix4d;
  15. for r := 0 to 3 do
  16.  for c := 0 to 3 do
  17.   for i := 0 to 3 do
  18.    t[r,c] := t[r,c] + (m1[r,i]*m2[i,c]);
  19. Result := t;
  20. end;
  21.  
  22. function Matrix_MakeYawMatrix(Angle : Single) : TMatrix4d;
  23. var
  24.  CA : Single;
  25.  SA : Single;
  26.  M  : TMatrix4d;
  27. begin
  28. SA := Sin(Angle);
  29. CA := Cos(Angle);
  30. M[0,0] := CA; M[1,0] := 0; M[2,0] := -SA; M[3,0] := 0;
  31. M[0,1] := 0;  M[1,1] := 1; M[2,1] := 0;   M[3,1] := 0;
  32. M[0,2] := SA; M[1,2] := 0; M[2,2] := CA;  M[3,2] := 0;
  33. M[0,3] := 0;  M[1,3] := 0; M[2,3] := 0;   M[3,3] := 1;
  34. Result := M;
  35. end;
  36.  
  37. function Matrix_MakeRollMatrix(Angle : Single) : TMatrix4d;
  38. var
  39.  CA : Single;
  40.  SA : Single;
  41.  M  : TMatrix4d;
  42. begin
  43. SA := Sin(Angle);
  44. CA := Cos(Angle);
  45. M[0,0] := CA;  M[1,0] := SA; M[2,0] := 0; M[3,0] := 0;
  46. M[0,1] := -SA; M[1,1] := CA; M[2,1] := 0; M[3,1] := 0;
  47. M[0,2] := 0;   M[1,2] := 0;  M[2,2] := 1; M[3,2] := 0;
  48. M[0,3] := 0;   M[1,3] := 0;  M[2,3] := 0; M[3,3] := 1;
  49. Result := M;
  50. end;
  51.  
  52. function Matrix_MakePitchMatrix(Angle : Single) : TMatrix4d;
  53. var
  54.  CA : Single;
  55.  SA : Single;
  56.  M  : TMatrix4d;
  57. begin
  58. SA := Sin(Angle);
  59. CA := Cos(Angle);
  60. M[0,0] := 1; M[1,0] := 0;   M[2,0] := 0;  M[3,0] := 0;
  61. M[0,1] := 0; M[1,1] := CA;  M[2,1] := SA; M[3,1] := 0;
  62. M[0,2] := 0; M[1,2] := -SA; M[2,2] := CA; M[3,2] := 0;
  63. M[0,3] := 0; M[1,3] := 0;   M[2,3] := 0;  M[3,3] := 1;
  64. Result := M;
  65. end;
  66.  
  67. procedure Matrix_Roll(var M : TMatrix4d; Angle : Single);
  68. begin
  69.  M := Matrix_Multiply(Matrix_MakeRollMatrix(DEG2RAD(Angle)),M);
  70. end;
  71.  
  72. procedure Matrix_Pitch(var M : TMatrix4d; Angle : Single);
  73. begin
  74.  M := Matrix_Multiply(Matrix_MakePitchMatrix(DEG2RAD(Angle)),M);
  75. end;
  76.  
  77. procedure Matrix_Yaw(var M : TMatrix4d; Angle : Single);
  78. begin
  79.  M := Matrix_Multiply(Matrix_MakeYawMatrix(DEG2RAD(Angle)),M);
  80. end;

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 04, 2008 07:07 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
But you can store your old matrix and reload it (Matrix Reloaded ;) ).
Or is this a problem for you?

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 04, 2008 12:57 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
Code:
  1. Program Matrix;
  2. begin
  3.  // Everything that has a begining has an end.
  4. end.


;)

Storing the Old Matrix(Or the opposite rotation operation) may work for undo/redo system (When i get round to it) but it would be nice to be able to set the matrix manualy, reset rotation/scale etc. Like what XSI(Mod Tool anyway) has at the right side. It would also help to reduce floating point errors when rotating multiple times.

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 07, 2008 17:23 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo Stucuk,

Zitat:
Im wondering if anyone knows how to rotate a Matrix Globaly, or if anyone can see any bugs with the code im using.

I can't see your code. I mean the relevant code, where you really manipulate the object by multiplying the two matrices. Maybe you have to multiply the matrices the other way round (not M1 * M2 but M2 * M1 - this is not the same).
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 08, 2008 18:29 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
I tryed the Matrix's both ways, one way it rotates around the center point, the other way it rotates around a corner/edge. The objects position is stripped, so the center of each object is [0,0,0], position is only added before rendering/etc. So the way which rotates around the center should be correct.

Zitat:
function Matrix_Multiply(m1 : TMatrix4f; m2 : TMatrix4f) : TMatrix4f;
var
r, c, i: Byte;
t: TMatrix4f;
begin
// Multiply two matrices.
t := NullMatrix4f;
for r := 0 to 3 do
for c := 0 to 3 do
for i := 0 to 3 do
t[r,c] := t[r,c] + (m1[r,i]*m2[i,c]);
Result := t;
end;


i have also tryed:

Zitat:
function MatrixMultiply(M1, M2: TMatrix4d): TMatrix4d;
// multiplies two 4x4 matrices
var I, J: Integer;
TM: TMatrix4d;

begin
for I := 0 to 3 do
for J := 0 to 3 do
TM[I, J] := M1[I, 0] * M2[0, J] +
M1[I, 1] * M2[1, J] +
M1[I, 2] * M2[2, J] +
M1[I, 3] * M2[3, J];
Result := TM;
end;

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 08, 2008 21:19 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo Stucuk,
I would solve it the same way I did the last time we met: I will make a little Delphi program. I will need a bit more time than I needed for the dome-demo, because the object has to be something where front/back, top/bottom can easily be distinguished, e.g. a fish or a boat or a plane and therefore the program has to have a simple loader.

Lets say - sunday morning I will come up anyway. The program will have the following content:

It will show an object centered anywhere - not only at the origin - and you can rotate/translate it as you like. You get the whole commented source code. As this is an experiment for me too, I'll try to take your matrices, but I can't guarantee that it works because it is not the way I usually do that. If I have problems I would switch to OpenGL-like matrices (angle/axis-driven).
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 10, 2008 03:31 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
Zitat:
I'll try to take your matrices


Actualy none of the Matrix code i use is my own work(See attachments). The only matrix code i have ever used comes from Geometry.pas by Mike Lischke and glMatrixHelper.pas by DGL's Sascha Willems (Some code in glMatrixHelper.pas was taken from Geometry.pas).

Zitat:
I would solve it the same way I did the last time we met: I will make a little Delphi program.


Thanks for trying.

Zitat:
. I will need a bit more time than I needed for the dome-demo, because the object has to be something where front/back, top/bottom can easily be distinguished, e.g. a fish or a boat or a plane and therefore the program has to have a simple loader.


Wouldn't a cube with different colours for each face work? Btw noeska has made a 3ds loader for use with Delphi + OpenGL. It can also load milkshape ascii files.


Dateianhänge:
glMatrixHelper.pas [14.29 KiB]
390-mal heruntergeladen
Geometry.pas [68.36 KiB]
391-mal heruntergeladen

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 10, 2008 19:50 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo Stucuk,

Yes, a cube with different colors would work, too. Or textures, for example. But this is not really a problem. I myself have an own simple obj-Loader. Maybe I can set up something per source code.

I am not yet ready with the demo-program. The reason is that I first thought about the representation of the object-rotation-status. We need to save this status, because we want to add new rotations to the existing rotation of our object. Now we have three possible solutions:

1) Save it as a angle/axis representation, like I did until recently. But this is useless here, because I can't add a new rotation to an angle/axis representation: no idea how to do this.

2) Save it as a matrix would work, but as you said already, this has the risk of growing floating point errors. Additionally a matrix is a big thing: 4X4 doubles = 8 Byte * 16 = 128 bytes per matrix.

3) So I ended up with Quaternions. As this is a little bit tricky, I need more time to set up a working program. So far I have implemented a camera with a quaternion rotation system. At the moment I am debugging.



As to your question above, I had an idea how to get over the "local" rotation:

I assume your rotating object has its center at 0/0/0. If you do shift your object, it is often the case that the object's position is filled in the last coloumn of the transformation matrix. If this is right, the following would help:

1. Create a translation matrix (ShiftMatrix) with the object's position in the last cloumn
2. Create a rotation matrix (Rotmatrix)
3. Multiply them as follows: Object matrix = ShiftMatrix x RotMatrix.

This assures that first the rotation is carried out and afterwards the translation.

I'll be back
Traude :wink:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 10, 2008 23:50 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
Traude hat geschrieben:
I assume your rotating object has its center at 0/0/0. If you do shift your object, it is often the case that the object's position is filled in the last coloumn of the transformation matrix. If this is right, the following would help:

1. Create a translation matrix (ShiftMatrix) with the object's position in the last cloumn
2. Create a rotation matrix (Rotmatrix)
3. Multiply them as follows: Object matrix = ShiftMatrix x RotMatrix.

This assures that first the rotation is carried out and afterwards the translation.


If that was the problem then wouldn't the object move from its position when rotated?

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Aug 13, 2008 18:11 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo Stucuk,
excuse me, I'm again a little bit late.

Zitat:
If that was the problem then wouldn't the object move from its position when rotated?

I assume that every object gets its position by translating it because the center of mass of every model is the origin and the position is only a stored 3D-Point. So you first have to carry out the rotation to bring it into the correct orientation and afterwards translate it to bring it to the correct position.




I'm ready with my transformation demo, it is attached below. I followed your advice to use a simple cube with different textures on each side. The object is "hard coded" in the unit "Classes3D". Rendering and the necessary math is separated in another two units: "Render3D and "Math3D".

I finally did NOT use quaternions for the rotations, because they do exactly the same as rotation matrices but are harder to understand and also harder to explain. Instead I used my old angle/axis representation. I make my rotation matrix on the basis of an angle and a vector (= a rotation axis), which I find very easy to understand. Unlike Euler angles you can rotate not only around the three main axes but around any vector in 3D space, which is imho a big advantage.

I only provide the pascal source code. Two needed units are not included: dglOpenGL.pas and glBitmap pas; I hope that is not unconvenient for you. Please read the "README.txt".

The shown effects should be exactly what you want. I had to make this program because I was unsure if I could explain it properly. A program is a hard prove that the problem can be solved. As there are many requirements that are often not mentioned - because people simply forget to mention - a program is a thing where nothing can be forgotten.
Traude


Dateianhänge:
TransfDemo.zip [20.34 KiB]
376-mal heruntergeladen
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 28, 2008 17:33 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
Your demo doesn't seem to solve the problem(Tho thanks for trying). If you click on Add?Rotation 45 Degree buttons the X and Y seem similer, but the Z is not rotating around the same "Global" Axis, its rotating around the objects "Local" Axis. When i say global rotation i mean that objects should rotate around the "Imaginary" X/Y/Z axis of the world, rather than based on how the object is currently facing.

P.S Sorry for the delay, been busy recently.

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 29, 2008 11:42 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo, Stucuk,
this cannot be true, because I do everything the same way and as a consequence everything must be wrong or everything must be correct.

I'll make an example:


First rotation 90 degree around the positive Y-axis (counter-clockwise):
-------------------------------------------------------------------------------------
The cube shows its blue left side. There should be no doubt that this is correct.


Second rotation 45 degree around the positive Z-axis (counter-clockwise):
-----------------------------------------------------------------------------------------
Please consider that the camera's Z-axis is unchanged and is therefore pointing at you (if you are sitting in front of the screen).

The cube's own Z-axis has been rotated around the Y-axis and is now the same as the camera's X-axis, that is, the horizontal axis.

If the cube - actually showing its left blue side - is rotating around the camera's Z-axis, the result of the second rotation should be a a tilted (I hope this is the right word here) view of its blue side. And so it is.

If the cube would rotate around its own Z-axis, the result would be the same as if you had chosen the button with the 45 degree X-axis: you would see not only the blue left side but the green top side, too.
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 29, 2008 13:30 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
Just using the default settings with the app (no 90 degree rotations) and just clicking on the 45 degree buttons, the object isn't rotated the same each time. As in the app is automaticaly rotating the object around an axis. This should always be the same rotation no matter what other rotations you are adding if the application is rotating Globaly rather than localy. When i click on the 45 Z button its rotating around a different point than the 45 X button. If it was rotating globaly the object should be rotated the same.

Iv made a recording of your application open 3 times with the only difference between the 3 is which 45 Degree button was clicked once. It shows local rotation as its always rotating based on the objects local space, rather than global space. I have also made a video showing global rotation in FME (which currently is just rotating the vertex's each time rotation is added rather than using a matrix/etc, which introduces alot of rotation errors). If you look at the top right grid when viewing the global rotation video u can see what i mean by global rotation, each time i press the middle button it will rotate exactly the same even when the orientation of the object is changed.

- Local Rotation
- Global Rotation

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 29, 2008 14:09 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 21, 2004 22:39
Beiträge: 360
Wohnort: UK, Scotland
Hmm, i flipped RotMatrix and AddRotMatrix in the Matrix Multiply function and now its rotating globaly.

_________________
Free Map Editor - Game Requirements - Stucuk.Net
-Stu


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 29, 2008 18:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
This was meant to be a VERY limited application. First you should click one of the 90 degree buttons and AFTERWARDS one of the 45 degree buttons. If you do it the other way round, do not hold me responsible for the results. :twisted:


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 26 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » English » English Programming Forum


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.015s | 17 Queries | GZIP : On ]