| Autor |
Beitrag |
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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:
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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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.
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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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: 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 
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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.
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
      
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
|
Verfasst: 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.
|
|
|