Translation mit Matrixen bei ner Hirachie

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Markus2

Betreff: Translation mit Matrixen bei ner Hirachie

BeitragMi, Aug 24, 2005 20:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ihr kennt ja diesen Translate Befehl von Blitz3D
wo man nen Entity einfach entlang den Weltachsen verschieben kann .

Sowas brauche ich auch aber bekomme es nicht gebacken Embarassed

Also ich habe ein Entity das wieder an einem anderen Entity hängt und so weiter .
Jedes hat eine lokale Achse (Vector für) X,Y,Z
und jetzt will ich ein Entity in der Hirachie den Weltachsen entlang verschieben doch irgendwie kommt bei meinen Matrixen rechnen nur
Müll raus .
Die Position eines Entitys ist in der Hirachie relativ zum Parent .
Also wenn ich das erste so drehe (um Z Achse) das oben rechts ist und das
zweite nach oben bewege z.B. Y=Y+10 dann geht das ja normal
auch nach rechts wenn es an dem ersten dran hängt .
Beim Translate muß ich das aber so umrechnen das ich weiß
das X=X-10 oben ist .
 

Dreamora

BeitragMi, Aug 24, 2005 21:10
Antworten mit Zitat
Benutzer-Profile anzeigen
1. Translate kommt in die 4te Zeile der Transformationsmatrix (also [3,0] = x, [3,1] = y, [3,2] = z in einer Matrix mit 0-3)

2. Die lokale Matrix einer Entity ist immer "lokale Matrix Parent " * "lokale Transformation". Die lokale Transformation ist dabei das was nach deinen veränderungen entsteht und die lokale Matrix das, was effektiv angewandt wird.

3. Punkt 2 ist rekursiv anzuwenden. Das heisst wenn du eine Hierarchy aufbaust musst du von den Weltkoordinaten rekursiv die Transformationen berechnen, wobei beim "oberensten Parent" die Welttransformation die benötigte lokale Transformation ist.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Markus2

BeitragMi, Aug 24, 2005 21:55
Antworten mit Zitat
Benutzer-Profile anzeigen
@Dreamora
bei 90° Winkeln gehts es aber wenn ich z.B. 45 Grad nehme kommt
da
x=-7.07106781
y=7.07106781
z=0.000000000
raus , ist doch richtig oder ?

Ein Beispiel wie ich es versuche
Code: [AUSKLAPPEN]

Local T:TV3D=TV3D.Create(0,10,0)
Local POS:TV3D=TV3D.Create(0,0,0)
Local AX:TV3D=TV3D.Create(1,0,0)
Local AY:TV3D=TV3D.Create(0,1,0)
Local AZ:TV3D=TV3D.Create(0,0,1)
Local MA:TMatrix=TMatrix.Create()
Local MB:TMatrix=TMatrix.Create()
Local MC:TMatrix=TMatrix.Create()

Local ROT:TV3D=TV3D.Create(0,0,1)
Local MR:TMatrix=TMatrix.Create()

'MatrixCreateIdentity MA
MatrixCreateTranslate T,MA

MatrixCreateAxisRotate ROT,-45,MR
VTRANS AX,MR
VTRANS AY,MR
VTRANS AZ,MR

  MB.A[0, 0] = AX.x
  MB.A[0, 1] = AY.x
  MB.A[0, 2] = AZ.x
  MB.A[0, 3] = 0
  MB.A[1, 0] = AX.y
  MB.A[1, 1] = AY.y
  MB.A[1, 2] = AZ.y
  MB.A[1, 3] = 0
  MB.A[2, 0] = AX.z
  MB.A[2, 1] = AY.z
  MB.A[2, 2] = AZ.z
  MB.A[2, 3] = 0
  MB.A[3, 0] = Pos.x
  MB.A[3, 1] = Pos.y
  MB.A[3, 2] = Pos.z
  MB.A[3, 3] = 1

MatrixMultiply MA,MB,MC
MatrixCopy MC,MA

AX.Set 1,0,0
AY.Set 0,1,0
AZ.Set 0,0,1

  MB.A[0, 0] = AX.x
  MB.A[0, 1] = AY.x
  MB.A[0, 2] = AZ.x
  MB.A[0, 3] = 0
  MB.A[1, 0] = AX.y
  MB.A[1, 1] = AY.y
  MB.A[1, 2] = AZ.y
  MB.A[1, 3] = 0
  MB.A[2, 0] = AX.z
  MB.A[2, 1] = AY.z
  MB.A[2, 2] = AZ.z
  MB.A[2, 3] = 0
  MB.A[3, 0] = Pos.x
  MB.A[3, 1] = Pos.y
  MB.A[3, 2] = Pos.z
  MB.A[3, 3] = 1

MatrixMultiply MA,MB,MC
MatrixCopy MC,MA

VTrans T,MA

DebugLog "T"
DebugLog T.x
DebugLog T.y
DebugLog T.z

DebugLog "MA"
DebugLog  MA.A[3, 0]
DebugLog  MA.A[3, 1]
DebugLog  MA.A[3, 2]

End




Code: [AUSKLAPPEN]


'----------------------------------------------------------------------

Type TV3D
 Field x:Float
 Field y:Float
 Field z:Float
 
 Function Create:TV3D(x:Float=0,y:Float=0,z:Float=0)
  Local T:TV3D=New TV3D
  T.x=x
  T.y=y
  T.z=z
  Return T
 End Function

 Method Set(x:Float,y:Float,z:Float=0)
  self.x=x
  self.y=y
  self.z=z
 End Method
 
End Type

'---------------------------------------------------------------

Type TMatrix
 Field A:Float[4,4]

 Function Create:TMatrix()
  Local M:TMatrix = New TMatrix
  Return M
 End Function

End Type

'--------------------------------
'-------------------------------------------------------------------------------------------------

Function VTRANS(a:TV3D Var,M:TMatrix)

 Local b:TV3D=TV3D.Create()
 
 b.x = a.x * M.A[0, 0] + a.y * M.A[1, 0] + a.z * M.A[2, 0]
 b.y = a.x * M.A[0, 1] + a.y * M.A[1, 1] + a.z * M.A[2, 1]
 b.z = a.x * M.A[0, 2] + a.y * M.A[1, 2] + a.z * M.A[2, 2]

 'ByRef
 
 a.x = b.x
 a.y = b.y
 a.z = b.z

 b=Null
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixZero(M:TMatrix Var)
 
 'MR 09.07.2005
 
 Local i, j
 
 For i = 0 To 3
  For j = 0 To 3
   M.A[i, j] = 0.0
  Next
 Next
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCopy(M:TMatrix,MOut:TMatrix Var)
 
 'MR 09.07.2005
 
 Local i, j
 
 For i = 0 To 3
  For j = 0 To 3
   MOut.A[i, j] = M.A[i, j]
  Next
 Next
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCreateIdentity(M:TMatrix Var)

 'MR 11.08.2005

 MatrixZero M

 Local i

 For i = 0 To 3
  M.A[i, i] = 1.0
 Next
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCreateTranslate(a:TV3D,M:TMatrix Var)
 
 'MR 09.07.2005
 
 MatrixCreateIdentity M
 
 M.A[3, 0] = a.x
 M.A[3, 1] = a.y
 M.A[3, 2] = a.z
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCreateAxisRotate(axis:TV3D,Angle:Float,M:TMatrix Var)
 
 Local sqraxis:TV3D=TV3D.Create()
 
 sqraxis.x = sqare(axis.x)
 sqraxis.y = sqare(axis.y)
 sqraxis.z = sqare(axis.z)
 
 Local cosine:Float
 
 cosine = Cos(Angle)
 
 Local sine:Float
 
 sine = Sin(Angle)
 
 Local one_minus_cosine:Float
 
 one_minus_cosine = 1.0 - cosine
 
 MatrixZero M
 
 M.A[0, 0] = sqraxis.x + (1.0 - sqraxis.x) * cosine
 M.A[0, 1] = axis.x * axis.y * one_minus_cosine + axis.z * sine
 M.A[0, 2] = axis.x * axis.z * one_minus_cosine - axis.y * sine
 
 M.A[1, 0] = axis.x * axis.y * one_minus_cosine - axis.z * sine
 M.A[1, 1] = sqraxis.y + (1.0 - sqraxis.y) * cosine
 M.A[1, 2] = axis.y * axis.z * one_minus_cosine + axis.x * sine
 
 M.A[2, 0] = axis.x * axis.z * one_minus_cosine + axis.y * sine
 M.A[2, 1] = axis.y * axis.z * one_minus_cosine - axis.x * sine
 M.A[2, 2] = sqraxis.z + (1.0 - sqraxis.z) * cosine
 
 M.A[3, 3] = 1.0
 
 sqraxis=Null

End Function

'-------------------------------------------------------------------------------------------------

Function MatrixMultiply(M1:TMatrix,M2:TMatrix,MOut:TMatrix Var)
 
 'Multipliziert Matrix 1 & 2
 
 Local i,j
 
 For i = 0 To 3
  For j = 0 To 3
   MOut.A[i, j] = M1.A[i, 0] * M2.A[0, j] + M1.A[i, 1] * M2.A[1, j] + M1.A[i, 2] * M2.A[2, j] + M1.A[i, 3] * M2.A[3, j]
  Next
 Next
 
End Function

'-------------------------------------------------------------------------------------------------

Function Sqare:Float(x:Float)

 'MR 09.07.2005

 Return (x * x)

End Function

'-------------------------------------------------------------------------------------------------

 

Dreamora

BeitragMi, Aug 24, 2005 22:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie ist deine Matrix genau definiert?
A[x,y] oder A[y,x] ?
In ersterem ist deine Multiplikation falsch, da sie dann B * A anstatt A * B berechnet was bei Matrizen nicht das gleiche ist.

Sobald du geantwortet hast kann ich dann auch die Rotation korrigieren, die scheint mir noch recht fehlerbehaftet

edit: Bin jetzt einfach mal davon ausgegangen, ass es A[zeile, spalte] ist und habe VTrans angepasst. Denn entweder VTrans ist falsch oder die Matrixmultiplikation. Und ersteres lässt sich einfacher anpassen.
Code mit optimierung kommt.

So hier ist der Code

Code: [AUSKLAPPEN]

'----------------------------------------------------------------------

Type TV3D
 Field x:Float
 Field y:Float
 Field z:Float
 
 Function Create:TV3D(x:Float=0,y:Float=0,z:Float=0)
  Local T:TV3D=New TV3D
  T.x=x
  T.y=y
  T.z=z
  Return T
 End Function

 Method Set(x:Float,y:Float,z:Float=0)
  self.x=x
  self.y=y
  self.z=z
 End Method
 
End Type

'---------------------------------------------------------------

Type TMatrix
 Field A:Float[4,4]

 Function Create:TMatrix()
  Local M:TMatrix = New TMatrix
  Return M
 End Function

End Type

'--------------------------------
'-------------------------------------------------------------------------------------------------

Function VTRANS(a:TV3D Var,M:TMatrix)

 Local b:TV3D=TV3D.Create()
 
 b.x = a.x * M.A[0, 0] + a.y * M.A[0, 1] + a.z * M.A[0, 2]
 b.y = a.x * M.A[1, 0] + a.y * M.A[1, 1] + a.z * M.A[1, 2]
 b.z = a.x * M.A[2, 0] + a.y * M.A[2, 1] + a.z * M.A[2, 2]

 'ByRef
 
 a.x = b.x
 a.y = b.y
 a.z = b.z

 b=Null
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixZero(M:TMatrix Var)
 
 'MR 09.07.2005
 
 Local i, j
 
 For i = 0 To 3
  For j = 0 To 3
   M.A[i, j] = 0.0
  Next
 Next
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCopy(M:TMatrix,MOut:TMatrix Var)
 
 'MR 09.07.2005
 
 Local i, j
 
 For i = 0 To 3
  For j = 0 To 3
   MOut.A[i, j] = M.A[i, j]
  Next
 Next
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCreateIdentity(M:TMatrix Var)

 'MR 11.08.2005

 MatrixZero M

 Local i

 For i = 0 To 3
  M.A[i, i] = 1.0
 Next
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCreateTranslate(a:TV3D,M:TMatrix Var)
 
 'MR 09.07.2005
 
 MatrixCreateIdentity M
 
 M.A[3, 0] = a.x
 M.A[3, 1] = a.y
 M.A[3, 2] = a.z
 
End Function

'-------------------------------------------------------------------------------------------------

Function MatrixCreateAxisRotate(axis:TV3D,Angle:Float,M:TMatrix Var)
 
 Local normal:TV3D = TV3D.Create()
 Local sqraxis:TV3D=TV3D.Create()
 
 Local squarelength:Float = axis.x + axis.y + axis.z

 ' Normierung des Vektors
 normal.x = axis.x/Sqr(squarelength)
 normal.y = axis.y/Sqr(squarelength)
 normal.z = axis.z/Sqr(squarelength)

 sqraxis.x = sqare(normal.x)
 sqraxis.y = sqare(normal.y)
 sqraxis.z = sqare(normal.z)
 
 Local cosine:Float
 
 cosine = Cos(Angle)
 
 Local sine:Float
 
 sine = Sin(Angle)
 
 Local one_minus_cosine:Float
 
 one_minus_cosine = 1.0 - cosine
 
 MatrixZero M
 
 M.A[0, 0] = sqraxis.x * one_minus_cosine + cosine
 M.A[0, 1] = normal.x * normal.y * one_minus_cosine + normal.z * sine
 M.A[0, 2] = normal.x * normal.z * one_minus_cosine - normal.y * sine
 
 M.A[1, 0] = normal.x * normal.y * one_minus_cosine - normal.z * sine
 M.A[1, 1] = sqraxis.y * (1.0 - cosine) + cosine
 M.A[1, 2] = normal.y * normal.z * one_minus_cosine + normal.x * sine
 
 M.A[2, 0] = normal.x * normal.z * one_minus_cosine + normal.y * sine
 M.A[2, 1] = normal.y * normal.z * one_minus_cosine - normal.x * sine
 M.A[2, 2] = sqraxis.z * (1.0 - cosine) + cosine
 
 M.A[3, 3] = 1.0
 
 sqraxis=Null

End Function

'-------------------------------------------------------------------------------------------------

Function MatrixMultiply(M1:TMatrix,M2:TMatrix,MOut:TMatrix Var)
 
 'Multipliziert Matrix 1 & 2
 'Optimiert auf Transformationsmatrizen von Marc 'Dreamora' Schärer
 
 Local i,j
 
 For i = 0 To 2
  For j = 0 To 2
   MOut.A[i, j] = M1.A[i, 0] * M2.A[0, j] + M1.A[i, 1] * M2.A[1, j] + M1.A[i, 2] * M2.A[2, j]
  Next
 Next

 MOut.A[3, 0] = M1.A[3,0] * M2.A[0,0] + M1.A[3,1] * M2.A[1,0] + M1.A[3,2] * M2.A[2,0] + M2[3,0]
 MOut.A[3, 1] = M1.A[3,0] * M2.A[0,1] + M1.A[3,1] * M2.A[1,1] + M1.A[3,2] * M2.A[2,1] + M2[3,1]
 MOut.A[3, 2] = M1.A[3,0] * M2.A[0,2] + M1.A[3,1] * M2.A[1,2] + M1.A[3,2] * M2.A[2,2] + M2[3,2]

 MOut.A[3, 3] = 1.0
End Function

'-------------------------------------------------------------------------------------------------

Function Sqare:Float(x:Float)

 'MR 09.07.2005

 Return (x * x)

End Function
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Markus2

BeitragMi, Aug 24, 2005 23:14
Antworten mit Zitat
Benutzer-Profile anzeigen
@Dreamora
Tausend Dank für deine Hilfe !
Werde ich Morgen mal ausprobieren .

Also die Rotation klappte ,
die Vectoren haben immer die länge 1 .

Mit dem A*B !=B*A hatte ich auch schon mal ausprobiert
aber Problem blieb das gleiche .

Ich habe bestimmt die Matrix falsch gefüllt oder
die VTrans Funk. stimmte nicht .
 

Dreamora

BeitragMi, Aug 24, 2005 23:22
Antworten mit Zitat
Benutzer-Profile anzeigen
die VTrans war falsch und die Rotationsmatrix komplett falsch

Ich hab die normalisierungsfunktion in die rotation eingebaut, damit du theoretisch um jede mögliche achse rotieren kannst.
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Markus2

BeitragMi, Aug 24, 2005 23:31
Antworten mit Zitat
Benutzer-Profile anzeigen
@Dreamora
also das ließ mir ja jetzt keine Ruhe Smile

Ich habe jetzt nur deine Version von VTrans eingesetzt und es geht nun Shocked nochmals vielen DANK 8)

Diese Vector Funk. sind schon Uralt und die hatte ich mal
aus nem C Quelltext übernommen und klappten bis jetzt .
Auch im Zusammenhang mit OpenGL hatte ich bis jetzt
keine Probleme außer bei der Translation mit der Hirachie .
Ich versuche das mal so zu drehen das ich keine doppelten Funk. habe Confused

Markus2

BeitragMi, Aug 24, 2005 23:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Sonnst sehe ich da gerade keinen Unterschied .
sqraxis.x * one_minus_cosine + cosine
=
sqraxis.x + (1.0 - sqraxis.x) * cosine
???

Muß ich mir morgen mal ausdrucken .
 

Dreamora

BeitragDo, Aug 25, 2005 0:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Jo ok ist das selbe so. Aber mit der anderen variante weniger zu berechnen.
hmm du willst es also für OpenGL nehmen? *sollte man vorher sagen*
Dann pass ichs halt nochmal an ... denn dafür stimmts nun nicht, da OpenGL mit A transporniert arbeitet statt mit A ... *auswirkung vor allem auf die Matrix Multi Optimierung*

Aber erst später dann.

Übrigens: wenn es um "in hierarchy" geht, nutzt der teil hier nur wenig ... da hier der hiearchyteil eigentlich garnet drin is oder?
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Markus2

BeitragDo, Aug 25, 2005 9:14
Antworten mit Zitat
Benutzer-Profile anzeigen
@Dreamora
Also das ist für mein 3D Modul was OpenGL benutzt .
OpenGL hat ja schon eigene Matrix Funk. die ich auch benutze .
Läuft alles soweit prima und als nächstes muß ich mich
an die Collisionserkennung wagen Confused

Mit der Hirachy klappt schon .
Im Prinzip wird ja da nur weiter mit Matrix*Matrix gerechnet .
 

Dreamora

BeitragDo, Aug 25, 2005 9:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Jopp im Prinzip schon. Musst nur einfach pro Entity 2 matrizen speichern. Die lokale Transformation und die durch die hierarchy daraus entstehende Transformation
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group