Autor Beitrag
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: So 17.06.07 19:18 
Wie kombiniere ich die Transformationsmatritzen zu einer Matrix?[meta]DirectX, Transformierung, Matrix, Rotation, Skalierung[/meta]

Frage offen

Hallo erstmal,

Ich bin dabei, eine Engine zu schreiben (oder erstmal, einfache Funktionen mit DelphiX hinzukriegen). Ich hab da ein Buch, mit dem bin ich bis jetzt auch ganz gut vorwärts gekommen, aber jetzt habe ich ein Problem. Der Autor hat die Weltmatrix folgendermaßen erklärt:

matrix

Wie ihr sehen könnt, sind _11, _22 und _33 mit 3 Werten belegt. Wie sollen die denn immer gleich sein?
Ich hab schon viel rumprobiert und mein Quader hat sich auch schon oft in eine komische Konstruktion verwandelt, aber geklappt hat es bis jetzt immer nur mit einer Achse, wenn alle anderen auf 0 sind. Ganz zu schweigen von der Skalierung, die noch hinzukommt.

Hier habe ich das Programm mal zum angucken:

Game Studio (zip, 8.29 KB)

Hoffentlich könnt ihr mir helfen.

PS: Gibt es auch DelphiX für Delphi 2005 oder Turbo 2006?
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von Yogu am Mo 13.12.10 18:25, insgesamt 4-mal bearbeitet
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mo 18.06.07 08:36 
IIRC muss 44 = 1 sein.

Ferner gilt für unskalierte Matrizzen (also wenn X=Y=Z=1) dass 11*22*33*44=1.

HTH.

P.S.: ggf. mal hier nen kurzen Blick drauf werfen (ich denk mal, die rechnen korrekt) und dort 3 Einheitsmatrizzen nehmen und jeweils um eine Achse rotieren. Anschließend die drei Ergebnismatrizzen (X*Y)*Z multiplizieren.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Yogu Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Mo 18.06.07 19:16 
Ich hab das ganze jetzt mal angewendet.
Die Y-Drehung klappt wunderbar, aber bei X und Z klappt der Quader in sich zusammen.
Hab ich irgendwas falsch gemacht? Ich paste hier nur die Funktionen, die ich zusammengebastelt hab. Falls ihr den ganzen Code haben wollt, könnt ihr ihn euch hier runterladen.

ausblenden volle Höhe Delphi-Quelltext
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:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
function D3DRotateMatrixX(Rotation: TD3DValue): TD3DMatrix;    
function D3DRotateMatrixY(Rotation: TD3DValue): TD3DMatrix;
function D3DRotateMatrixZ(Rotation: TD3DValue): TD3DMatrix;
function D3DMultiplyMatrices(Matrices: array of TD3DMatrix): TD3DMatrix;
procedure UpdateMatrices;

function D3DRotateMatrixX(Rotation: TD3DValue): TD3DMatrix;
begin
  with Result do
  begin
    _11 :=  1;
    _12 :=  1;
    _13 :=  1;
    _14 :=  0;
    _21 :=  1;
    _22 :=  cos(Rotation);
    _23 :=  sin(Rotation);
    _24 :=  0;
    _31 :=  1;
    _32 := -sin(Rotation);
    _33 :=  cos(Rotation);
    _34 :=  0;
    _41 :=  0;
    _42 :=  0;
    _43 :=  0;
    _44 :=  1;
  end;
end;

function D3DRotateMatrixY(Rotation: TD3DValue): TD3DMatrix;
begin
  with Result do
  begin
    _11 :=  cos(Rotation);
    _12 :=  1;
    _13 := -sin(Rotation);
    _14 :=  0;
    _21 :=  1;
    _22 :=  1;
    _23 :=  1;
    _24 :=  0;
    _31 :=  sin(Rotation);
    _32 :=  1;
    _33 :=  cos(Rotation);
    _34 :=  0;
    _41 :=  0;
    _42 :=  0;
    _43 :=  0;
    _44 :=  1;
  end;
end;

function D3DRotateMatrixZ(Rotation: TD3DValue): TD3DMatrix;
begin
  with Result do
  begin
    _11 :=  cos(Rotation);
    _12 :=  sin(Rotation);
    _13 :=  1;
    _14 :=  0;
    _21 := -sin(Rotation);
    _22 :=  cos(Rotation);
    _23 :=  1;
    _24 :=  0;
    _31 :=  1;
    _32 :=  1;
    _33 :=  1;
    _34 :=  0;
    _41 :=  0;
    _42 :=  0;
    _43 :=  0;
    _44 :=  1;
  end;
end;

function D3DMultiplyMatrices(Matrices: array of TD3DMatrix): TD3DMatrix;
var i: Integer;
begin
  with Result do
  begin
    _11 := 1; _12 := 1; _13 := 1; _14 := 1;
    _21 := 1; _22 := 1; _23 := 1; _24 := 1;
    _31 := 1; _32 := 1; _33 := 1; _34 := 1;
    _41 := 1; _42 := 1; _43 := 1; _44 := 1;
  end;
  
  for i := Low(Matrices) to High(Matrices) do
  with Matrices[i] do
  begin
    Result._11 := Result._11 * _11;
    Result._12 := Result._12 * _12;
    Result._13 := Result._13 * _13;
    Result._14 := Result._14 * _14;
    Result._21 := Result._21 * _21;
    Result._22 := Result._22 * _22;
    Result._23 := Result._23 * _23;
    Result._24 := Result._24 * _24;
    Result._31 := Result._31 * _31;
    Result._32 := Result._32 * _32;
    Result._33 := Result._33 * _33;
    Result._34 := Result._34 * _34;
    Result._41 := Result._41 * _41;
    Result._42 := Result._42 * _42;
    Result._43 := Result._43 * _43;
    Result._44 := Result._44 * _44;
  end;
end;

procedure UpdateMatrices;
begin
  WorldMatrix := D3DMultiplyMatrices([
    D3DRotateMatrixX(TurnVector.X),
    D3DRotateMatrixY(TurnVector.Y),
    D3DRotateMatrixZ(TurnVector.Z)]);
  with WorldMatrix do
  begin
    _41 :=  ViewVector.X;
    _42 :=  ViewVector.Y;
    _43 :=  ViewVector.Z;
  end;
end;
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 19.06.07 07:46 
Man beachte meinen verlinkten Source bzgl. Matrix-Multiplikation. Matrizzen werden nicht multipliziert, indem man diese Feldweise überlagert und multipliziert, sondern indem man die Quellmatrix Zeilenweise und die Zielmatrix Spaltenweise multipliziert. Eine Multiplikation von mehr als 2 Matrizzen gleichzeitig ist nicht definiert.

Siehe auch: Suche in Wikipedia HIER, hier und hier. Auch wenn die letzten Links für OGL erklärt sind, die Grundlagen zur Linearen Algebra gelten genauso auch für DX ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Yogu Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 19.06.07 17:18 
Ich hab das ganze mal probiert, auch die Seiten angeschaut, aber ich blick das nicht ganz. Ich hab mal das ganze Zeilenweise und spaltenweise probiert, klappt aber immer noch nicht.

ausblenden volle Höhe Delphi-Quelltext
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:
36:
function D3DMultiplyMatrices(M1, M2: TD3DMatrix): TD3DMatrix;
begin
  with Result do
  begin
    _11 := M1._11 * M2._11;
    _12 := M1._12 * M2._21;
    _13 := M1._13 * M2._31;
    _14 := M1._14 * M2._41;
    _21 := M1._21 * M2._12;
    _22 := M1._22 * M2._22;
    _23 := M1._23 * M2._32;
    _24 := M1._24 * M2._42;
    _31 := M1._31 * M2._13;
    _32 := M1._32 * M2._23;
    _33 := M1._33 * M2._33;
    _34 := M1._34 * M2._43;
    _41 := M1._41 * M2._14;
    _42 := M1._42 * M2._24;
    _43 := M1._43 * M2._34;
    _44 := M1._44 * M2._44;
  end;
end;

procedure TD3DWorld.UpdateMatrices;
begin
  WorldMatrix := D3DMultiplyMatrices(D3DMultiplyMatrices(
    D3DRotateMatrixX(TurnVector.X),
    D3DRotateMatrixY(TurnVector.Y)),
    D3DRotateMatrixZ(TurnVector.Z));
  with WorldMatrix do
  begin
    _41 :=  ViewVector.X;
    _42 :=  ViewVector.Y;
    _43 :=  ViewVector.Z;
  end;
end;


Gesamter Quelltext wie immer hier.
NeoInDerMATRIX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 245

Win95, Win98(+se), WinNT, Win2000, WinME, WinXP(+pro), VISTA, Linux(SuSe), DOS [MultiMon(3)], Vista
D6 PeE + (FP 2.0l) + D3 Pe + D2005+ D2006 Arch
BeitragVerfasst: Do 28.06.07 21:44 
Eventuell solltest du dich bevor du damit weiter machen möchtest mit einigen Tutorials auseinander setzen. Die Materie ist doch recht anspruchsvoll. Die entsprechenden Links hat ja BenBE bereits gepostet.