Physque pour Dreamotion3D

Généralités sur la programmation 3D
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Merci super cool, je pense qu'avec tous cela je devrais pouvoir pondre un systeme
de rotation fiable et digne de ce nom... et digne d'un moteur3D qui tient la route
Force et sagesse...
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

tmyke a écrit :Merci pour vos conseil et lien. Je mate cela et je vois comment m'en sortir.
La j'ai fait un petit code simple. J'ai un cube sur lequel j'applique une rotation
sur les 3 axes, et je récupère les angles a partir de la matrice de transformation
pour les appliquer a un second cube. En théorie, je devrais obtenir les memes
rotations. Force est d'avouer que pour l'instant ce n'est pas le cas.
Alors je travaille mon truc...
Je présume que tu passe par le produit matricielle pour touver la matrice concaténée des 3 rotations. Si tu utilise les Quaternions pour les calculs de rotation, tu va être en mesure de créer une matrice de rotation plus précise en faisant moins d'opérations mathématiques. Et tu sais très bien qu'un moteur 3D, ça en fait des calculs par secondes.

Sur ce, bonne chance !

A+
Guimauve
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Le probleme est que je passe deja par les Quaternions, donc mon soucis est
de trouver l'incompatibilité descendante par rapport au calcul montant.
Force et sagesse...
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

A tes souhaits !
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Merci Progi :wink:

sinon, j'ai par exemple mis en pratique les calculs que l'on trouve dans le lien

http://jeux.developpez.com/faq/matquat/ ... ations#Q37

et la aussi, les angles transmis ne sont pas récupéres correctement...

donc pas si simple la chose, mais je continue a creusr.. :twisted:
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

euh, le fait que tu sois en trièdre inverse, ça n'a rien à voir ?
Peut-être que l'exemple est donné pour un repère avec un trièdre direct ?

ça change quelque chose dans les calculs ?
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

j'ai voulu afficher la matrice de la caisse en reprenant ton exemple
c'est bizarre cette valeur 3 dans mat\_42 non ?

A part ça j'ai voulu essayer et j'obtiens les bons angles si je ne fais que des rotations en x ou / et z, ou en y seul, si je mets les 3 ensembles le résultat n'est pas bon.

Code : Tout sélectionner

; Fichiers Include
IncludePath "..\Include\"
IncludeFile "d3dx9.pbi"
IncludeFile "dreamotion3d.pbi"
IncludeFile "PhysX.pbi"


; Globales
Global anglex.f, angley.f, flagXDown.w
Global mox.f, omx.f, moy.l, omy.l
Global angle_y.f,angle_x.f, angle_z.f

Global *camera.CEntity
Global Dim *roue.CEntity(4)
Global Dim *axis.CEntity(4)
Global *font.CFont
Global *caisse
Global *joint.NxJoint
Global *joint2.NxJoint
Global mat.D3DXMATRIX

Macro NEW_X(x, Angle, Distance) 
  ((x) + Cos((Angle) * 0.0174533) * (Distance))
EndMacro

Macro NEW_Z(z, Angle, Distance)
  ((z) - Sin((Angle) * 0.0174533) * (Distance))
EndMacro

;- Declaration des procédures
Declare.f CurveValue(actuelle.f, Cible.f, P.f) 
Declare GestionCamera()

; Initialisation des différents modules
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
End
EndIf

; Initialise la fenêtre graphique
DM_Graphics3D(800, 600, 32, 0, 1)
; Charge une font
*font = DM_LoadFont("Arial",8 , 1)
DM_SetColorText (*font, 198,198,198,255)
DM_AmbiantLight(150, 150, 150)
SetCurrentDirectory("medias/")

;---------------------------------
; INIT DU MOTEUR PHYSIQUE
;---------------------------------
NX_Init(*DM_d3dDev9)

;--------------------------------------------------------------
; PETITE LIGHT HISTOIRE DE ...
;--------------------------------------------------------------
*light = DM_CreateLight(3, #Null)

;--------------------------------------------------------------
; set ground
;--------------------------------------------------------------
*ter = DM_LoadEntity("land3.x", #Null, #False)
DM_TranslateEntity(*ter, 0,20,0)
NX_CreateStaticElement(*ter,10, 2)

*ter = DM_CreateSphere(4)
DM_ScaleMesh(*ter, 30,30,30)
DM_TranslateEntity(*ter, 0,-35,100)
NX_CreateStaticElement(*ter,10, 2)
*brush = DM_GetBrush(*ter)
DM_LoadTexture( DM_GetTexture(*brush), "grille1.bmp")

*caisse = DM_CreateCube()
DM_ScaleMesh(*caisse, 4, 2,8)
DM_TranslateEntity(*caisse, 0,3,0)
NX_CreatePhysicBox(*caisse, 0,0,0, 5000.0,0)


For i = 0 To 3
*roue(i) = DM_CreateCylinder(16)
DM_ScaleMesh(*roue(i), 2,2,0.25)
DM_RotateMesh(*roue(i), 0,90,0)
Next
DM_TranslateEntity(*roue(0), 6,0,7) : NX_CreatePhysicMesh(*roue(0), 400,2) : NX_EntitySetContact(*roue(0), *caisse, 0)
DM_TranslateEntity(*roue(1), 6,0,-7): NX_CreatePhysicMesh(*roue(1), 400,2) : NX_EntitySetContact(*roue(1), *caisse, 0)
DM_TranslateEntity(*roue(2), -6,0,7): NX_CreatePhysicMesh(*roue(2), 400,2) : NX_EntitySetContact(*roue(2), *caisse, 0)
DM_TranslateEntity(*roue(3), -6,0,-7): NX_CreatePhysicMesh(*roue(3), 400,2) : NX_EntitySetContact(*roue(3), *caisse, 0)


For i = 0 To 3
*axis(i) = DM_CreateSphere(8)
DM_ScaleMesh(*axis(i), 0.45,0.45, 0.45)
Next
DM_TranslateEntity(*axis(0), 4,0,7) : NX_CreatePhysicSphere(*axis(0), 0,400,0)
NX_EntitySetContact(*axis(0), *caisse, 0)
NX_EntitySetContact(*axis(0), *roue(0), 0)
DM_TranslateEntity(*axis(1), 4,0,-7): NX_CreatePhysicSphere(*axis(1), 0,400,0)
NX_EntitySetContact(*axis(1), *caisse, 0)
NX_EntitySetContact(*axis(1), *roue(1), 0)
DM_TranslateEntity(*axis(2), -4,0,7): NX_CreatePhysicSphere(*axis(2), 0,400,0)
NX_EntitySetContact(*axis(2), *caisse, 0)
NX_EntitySetContact(*axis(2), *roue(2), 0)
DM_TranslateEntity(*axis(3), -4,0,-7): NX_CreatePhysicSphere(*axis(3), 0,400,0)
NX_EntitySetContact(*axis(3), *caisse, 0)
NX_EntitySetContact(*axis(3), *roue(3), 0)

;--------------------------------------------------------------
; create joints
;--------------------------------------------------------------
;
*joint = NX_CreateRevoluteJointM(*roue(0), *axis(0) , 6,0,7, 1,0,0)
*joint = NX_CreatePrismaticJoint(*axis(0), *caisse , 5,0,7, 0,1,0)
NX_CreateSpring(*axis(0), *caisse, 4,0,7 , 0.1)

*joint = NX_CreateRevoluteJointM(*roue(2), *axis(2) , -6,0,7, 1,0,0)
*joint = NX_CreatePrismaticJoint(*axis(2), *caisse , -5,0,7, 0,1,0)
NX_CreateSpring(*axis(2), *caisse, -4,0,7 , 0.1)

*joint = NX_CreateRevoluteJointM(*roue(1), *axis(1) , 6,0,-7, 1,0,0)
*joint = NX_CreatePrismaticJoint(*axis(1), *caisse , 5,0,-7, 0,1,0)
NX_CreateSpring(*axis(1), *caisse, 4,0,-7 , 0.1)

*joint = NX_CreateRevoluteJointM(*roue(3), *axis(3) , -6,0,-7, 1,0,0)
*joint = NX_CreatePrismaticJoint(*axis(3), *caisse , -5,0,-7, 0,1,0)
NX_CreateSpring(*axis(3), *caisse, -4,0,-7 , 0.1)


;---------------------------------------
; Gestion des caméras
; ---------------------------------------
*camera = DM_CreateCamera(#Null)
DM_MoveEntity(*camera, -9,25, 37)
DM_TurnEntity(*camera, 30,170, 0)
DM_CameraClsColor(*camera, 25, 25, 25)
; ---------------------------------------
; Boucle principale
; ---------------------------------------

Procedure.f atan2(y.d,x.d)
;atan2 procedure by Paul Dixon
;http://www.powerbasic.com/support/forums/Forum4/HTML/009180.html
;adapted to PureBasic by Jack
! fld qword [p.v_y] ;load y
! fld qword [p.v_x] ;load x
! fpatan ;get atan(y/x), put result in ST1. then pop stack to leave result in ST0
! ftst ;test ST0 (that's the top of stack) against zero
! fstsw ax ;put result of test into AX
! sahf ;get the FPU flags into the CPU flags
! jae @@skip ; if above or equal then skip the add 2*pi code
! fldpi ;get pi
! fadd st1,st0 ;add pi to result
! faddp st1,st0 ;and again, for 2pi, then pop the now unneeded pi from st0
! @@skip:
ProcedureReturn
EndProcedure
Procedure.f WrapValue(angle.f); <- wraps a value into [0,360) fringe
  ;Psychophanta : http://purebasic.fr/english/viewtopic.php?t=18635 
  !fild dword[@f] ; <- now i have 360 into st0
  !fld dword[p.v_angle]
  !fprem
  !fadd st1,st0
  !fldz
  !fcomip st1
  !fcmovnbe st0,st1
  !fstp st1
  ProcedureReturn
  !@@:dd 360
EndProcedure
Procedure CalculAngle()
  DM_EntityWorld(*Caisse, @mat)
  ; 0  1  2  3
  ; 4  5  6  7
  ; 8  9 10 11 
  ;12 13 14 15
  Define.f c, trx, try, RADIANS
  RADIANS = 57.29578
  angle_y.f =  ASin(mat\_31);           /* Calcul de l'Angle Y */
  C         =  Cos(angle_y);
  angle_y  * RADIANS ;   *  RADIANS;

If (Abs(C) > 0.005)    ;            /* Gimbal lock ? */

    trx      =  mat\_33 / C;           /* Non, donc calcul de l'angle X */
    try      = -mat\_32 / C;

    angle_x  = atan2(try, trx) * RADIANS;

    trx      =  mat\_11 / C;            /* Calcul de l'angle Z */
    try      = -mat\_21 / C;

    angle_z  = atan2(try, trx) * RADIANS;

Else        ;                           /* Gimbal lock  */

    angle_x  = 0;                      /* Angle X à 0 */

    trx      = mat\_22;                 /* Calcul de l'angle Z */
    try      = mat\_12;

    angle_z  = atan2(try, trx) * RADIANS;
EndIf

angle_x = WrapValue(angle_x);  /* Modulo ;) */
angle_y = WrapValue(angle_y);
angle_z = WrapValue(angle_z);
EndProcedure

Repeat

ExamineKeyboard()
ExamineMouse()
ShowCursor_(1)
If KeyboardReleased(#PB_Key_Escape) Or WindowEvent()=#PB_Event_CloseWindow
Quit=1
EndIf


If KeyboardPushed(#PB_Key_Up)
NX_EntitySetAngularMomentum(*roue(0), 5000,0,0)
NX_EntitySetAngularMomentum(*roue(2), 5000,0,0)
EndIf
If KeyboardPushed(#PB_Key_Down)
NX_EntityAddForceAtLocalPos(*caisse, 0,0,50000, 0,2,0)
EndIf

; ---------------
; Rendu
; ---------------
; mise a jour de la physique
NX_Update()
GestionCamera()
CalculAngle()
NX_RotateEntity(*Caisse,67,0,36)
DM_BeginScene()
DM_RenderWorld()
DM_DrawText(*font,0,0,StrF(angle_x,1) + " " + StrF(angle_y,1) + " " + StrF(angle_z,1))
DM_DrawText(*font,0,20,StrF(mat\_11,1) + " " + StrF(mat\_21,1) + " " + StrF(mat\_31,1) + " " + StrF(mat\_41,1))
DM_DrawText(*font,0,40,StrF(mat\_12,1) + " " + StrF(mat\_22,1) + " " + StrF(mat\_32,1) + " " + StrF(mat\_42,1))
DM_DrawText(*font,0,60,StrF(mat\_13,1) + " " + StrF(mat\_23,1) + " " + StrF(mat\_33,1) + " " + StrF(mat\_43,1))
DM_DrawText(*font,0,80,StrF(mat\_14,1) + " " + StrF(mat\_24,1) + " " + StrF(mat\_34,1) + " " + StrF(mat\_44,1))

DM_EndScene()

Until Quit=1
NX_Exit()
DM_ClearGraphics()
End


Procedure.f CurveValue(actuelle.f, Cible.f, P.f) 
	;Calcule une valeur progressive allant de la valeur actuelle à la valeur cible 
  	Define.f Delta
  	Delta = Cible - actuelle 
  	If P > 1000.0 : P = 1000.0 : EndIf 
  	ProcedureReturn  (actuelle + ( Delta * P / 1000.0)) 
EndProcedure 

Procedure GestionCamera()
  Define.f Px, Py, Pz, Pv 
  Define.f x,y,z
  Static AngleCamera.f
  Pv = 25
  AngleCamera = CurveValue(AngleCamera, DM_EntityYaw(*Caisse) + 90, Pv) 
  Px = CurveValue(DM_EntityX(*Camera), NEW_X(DM_Entityx(*Caisse), AngleCamera, 50), Pv)
  Py = CurveValue(DM_EntityY(*Camera), DM_EntityY(*Caisse) + 20, Pv)
  Pz = CurveValue(DM_EntityZ(*Camera), NEW_Z(DM_EntityZ(*Caisse), AngleCamera, 50), Pv)
     
  DM_PositionEntity(*Camera, Px, Py, Pz)
  DM_PointEntity(*Camera, *Caisse)    
EndProcedure
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Tu en est au meme point que moi. En fait cela foire dès qu'il y a combinaison des angles
qui rentrent en compte. Si je reste sur un angle a la fois, la cela fonctonne bien.
Pour ce qui est du repere, cela pourrait en effet etre une solution, mais dans les tests
généraux, comme celui du lien fourni plus haut, j'ai fait des essais sur des calculs
simple, sans réellement l'intégré dans DM3D. J'ai créé une matrice simple comme
spécifié dans le tuto, puis dans la foulé j'ai récupéré les angles sur cette meme
matrice, et la c'est toujours pareil, cela ne fonctionne pas non plus.
En fait j'ai fait plusieurs sites ou on explique super bien comment produire
une matrice de rotation par plusieurs méthodes, puis en suite de récupérer les elements, dont
les angles de rotation. Quand tu lis les tuto, cela parait limpide, et clair, seulement
quand tu met en pratique, cela ne fonctionne pas...

Maintenant je fais certainement un truc qui faut pas a un moment donné, car
dans bon nombre d'appli cela fonctionne, donc il y a forcement un hic quelque part.
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

ok alors je viens de faire un exemple en utilisant les fonctions de Dx pour calculer mes matrices de rotation , et là ça semble fonctionner correctement.
J'ai pas trop tester, mais les premiers résultats sont corrects.

[EDIT]
Ok , c'est pas bon si je mets

Code : Tout sélectionner

D3DXMatrixRotationX(@matx, #PI/2)
D3DXMatrixRotationY(@maty, #PI/2)
D3DXMatrixRotationz(@matz, #PI/3)
Pis je ne suis pas sur de faire les multiplications dans le bon ordre :oops:
[EDIT2]

j'ai remplacé les multiplications par

Code : Tout sélectionner

D3DXMatrixRotationYawPitchRoll.l(@mat, #PI/4, #PI/4, 0)
mais c'est pas mieux

Code : Tout sélectionner

;Comtois le 22/11/06
; Fichiers Include
IncludePath "..\Include\"
IncludeFile "d3dx9.pbi"


Global mat.D3DXMATRIX,mati.D3DXMATRIX,matx.D3DXMATRIX,maty.D3DXMATRIX,matz.D3DXMATRIX
Global angle_y.f,angle_x.f, angle_z.f

Procedure.f atan2(y.d,x.d)
;atan2 procedure by Paul Dixon
;http://www.powerbasic.com/support/forums/Forum4/HTML/009180.html
;adapted to PureBasic by Jack
! fld qword [p.v_y] ;load y
! fld qword [p.v_x] ;load x
! fpatan ;get atan(y/x), put result in ST1. then pop stack to leave result in ST0
! ftst ;test ST0 (that's the top of stack) against zero
! fstsw ax ;put result of test into AX
! sahf ;get the FPU flags into the CPU flags
! jae @@skip ; if above or equal then skip the add 2*pi code
! fldpi ;get pi
! fadd st1,st0 ;add pi to result
! faddp st1,st0 ;and again, for 2pi, then pop the now unneeded pi from st0
! @@skip:
ProcedureReturn
EndProcedure
Procedure.f WrapValue(angle.f); <- wraps a value into [0,360) fringe
  ;Psychophanta : http://purebasic.fr/english/viewtopic.php?t=18635 
  !fild dword[@f] ; <- now i have 360 into st0
  !fld dword[p.v_angle]
  !fprem
  !fadd st1,st0
  !fldz
  !fcomip st1
  !fcmovnbe st0,st1
  !fstp st1
  ProcedureReturn
  !@@:dd 360
EndProcedure
Procedure CalculAngle()
  ; 0  1  2  3
  ; 4  5  6  7
  ; 8  9 10 11 
  ;12 13 14 15
  Define.f c, trx, try, RADIANS
  RADIANS = 57.29578
  angle_y.f =  ASin(mat\_31);           /* Calcul de l'Angle Y */
  C         =  Cos(angle_y);
  angle_y  * RADIANS ;   *  RADIANS;

If (Abs(C) > 0.0005)    ;            /* Gimbal lock ? */

    trx      =  mat\_33 / C;           /* Non, donc calcul de l'angle X */
    try      = -mat\_32 / C;

    angle_x  = atan2(try, trx) * RADIANS;

    trx      =  mat\_11 / C;            /* Calcul de l'angle Z */
    try      = -mat\_21 / C;

    angle_z  = atan2(try, trx) * RADIANS;

Else        ;                           /* Gimbal lock  */

    angle_x  = 0;                      /* Angle X à 0 */

    trx      = mat\_22;                 /* Calcul de l'angle Z */
    try      = mat\_12;

    angle_z  = atan2(try, trx) * RADIANS;
EndIf

angle_x = WrapValue(angle_x);  /* Modulo ;) */
angle_y = WrapValue(angle_y);
angle_z = WrapValue(angle_z);
EndProcedure

;D3DXMatrixRotationX(@matx, #PI/2)
;D3DXMatrixRotationY(@maty, #PI/2)
;D3DXMatrixRotationz(@matz, #PI/3)
;D3DXMatrixMultiply(@mati, @matx, @maty)
;D3DXMatrixMultiply(@mat, @mati, @matz)
D3DXMatrixRotationYawPitchRoll.l(@mat, #PI/4, #PI/4, 0)
CalculAngle()

Debug StrF(angle_x,1) + " " + StrF(angle_y,1) + " " + StrF(angle_z,1)
Debug StrF(mat\_11,1) + " " + StrF(mat\_21,1) + " " +StrF(mat\_31,1) + " " +StrF(mat\_41,1) 
Debug StrF(mat\_12,1) + " " + StrF(mat\_22,1) + " " +StrF(mat\_32,1) + " " +StrF(mat\_42,1) 
Debug StrF(mat\_13,1) + " " + StrF(mat\_23,1) + " " +StrF(mat\_33,1) + " " +StrF(mat\_43,1) 
Debug StrF(mat\_14,1) + " " + StrF(mat\_24,1) + " " +StrF(mat\_34,1) + " " +StrF(mat\_44,1) 
Dernière modification par comtois le mer. 22/nov./2006 21:33, modifié 3 fois.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

OK, j'atudie cela et je met a l'épreuve...
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

bon je vais étudier ce siteplus tard, là je vais me coucher :)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

j'ai bien dormi !

et je crois que j'ai trouvé la solution, à mettre à l'épreuve, je n'ai fait que quelques tests.

Bon je vais me chercher des croissants :)

[EDIT]
Gloups !
Si je mets tous les angles à 90° ça merdouille, mais bon c'est avec cette solution que j'obtiens les meilleurs résultats.

Faudra que je relise ça plus tard
rotation matrix to euler-angles conversion
Several implementations of this have been published which give wrong answers in cases when there is more than one solution (e.g. Shoemake, Euler Angle Conversion, in Graphics Gems IV).

For definiteness, let's consider heading/pitch/roll Euler angles (or yaw/pitch/roll if you like). The subtlety occurs when the pitch is 90 degrees (or close to it): in this case any heading value could alternatively be expressed as roll, and vice-versa. So, if you are asked to decompose a rotation (matrix) in which the pitch is 90 degrees, you can choose the heading arbitrarily and then choose the roll in terms of it (or vice-versa).

Notice that in this case there is one degree of freedom in your answer, but not two! So if you have determined that the pitch is 90 degrees (or sufficiently close), you can't just throw your hands up in the air and return arbitrary numbers (e.g. zero) for both heading and roll; in general, you won't get a representation of the original matrix, which would be a bad bug in your implementation. You can return an arbitrary number for either heading or roll, but then that determines the other.

A good robust way do do this is to start by choosing the heading (or roll) using the atan2 function as usual. Note that if the pitch is 90 degrees or close to it, then you will be taking the atan2 of two numbers very close (or equal) to zero, which is unstable of course, but the worst atan2 can do is return a random angle, which is fine, and even appropriate, in this case. The next step is to create a rotation matrix representing the inverse of the heading (or roll) you have chosen, and multiply it by the original matrix on the appropriate side, effectively factoring out your chosen heading (or roll). Now you are left with a simpler matrix, from which you can robustly extract the remaining two euler angles, and when you compose them all together you are guaranteed to get back the original matrix.

Code : Tout sélectionner

;Comtois 23/11/06
; Fichiers Include
IncludePath "..\Include\"
IncludeFile "d3dx9.pbi"


Global mat.D3DXMATRIX
Global angle_y.f,angle_x.f, angle_z.f
Global x.f, y.f, z.f


Procedure.f atan2(y.d,x.d)
;atan2 procedure by Paul Dixon
;http://www.powerbasic.com/support/forums/Forum4/HTML/009180.html
;adapted to PureBasic by Jack
! fld qword [p.v_y] ;load y
! fld qword [p.v_x] ;load x
! fpatan ;get atan(y/x), put result in ST1. then pop stack to leave result in ST0
! ftst ;test ST0 (that's the top of stack) against zero
! fstsw ax ;put result of test into AX
! sahf ;get the FPU flags into the CPU flags
! jae @@skip ; if above or equal then skip the add 2*pi code
! fldpi ;get pi
! fadd st1,st0 ;add pi to result
! faddp st1,st0 ;and again, for 2pi, then pop the now unneeded pi from st0
! @@skip:
ProcedureReturn
EndProcedure
Procedure.f WrapValue(angle.f); <- wraps a value into [0,360) fringe
  ;Psychophanta : http://purebasic.fr/english/viewtopic.php?t=18635 
  !fild dword[@f] ; <- now i have 360 into st0
  !fld dword[p.v_angle]
  !fprem
  !fadd st1,st0
  !fldz
  !fcomip st1
  !fcmovnbe st0,st1
  !fstp st1
  ProcedureReturn
  !@@:dd 360
EndProcedure
Procedure DecomposeRollPitchYawZXYMatrix()

; http://blogs.msdn.com/MikePelton/archive/2004/10/29/249501.aspx
   angle_x = ASin(-mat\_32) 
   
   test = Cos(angle_x)
   
   angle_x * 57.29578
   
   threshold.f = 0.001; // Hardcoded constant - burn him, he's a witch

   If(test > threshold) 

      angle_z = Atan2(mat\_12, mat\_22) * 57.29578

      angle_y = Atan2(mat\_31, mat\_33) * 57.29578

   Else 

      zRoll = Atan2(-mat\_21, mat\_11) * 57.29578

      angle_y = 0.0

   EndIf

EndProcedure

x =  45 * 0.01745
y =  90 * 0.01745
z =  60 * 0.01745

D3DXMatrixRotationYawPitchRoll(@mat, y, x, z)
DecomposeRollPitchYawZXYMatrix()

Debug StrF(angle_x,1) + " " + StrF(angle_y,1) + " " + StrF(angle_z,1)
Debug "----"
Debug StrF(mat\_11,1) + " " + StrF(mat\_21,1) + " " +StrF(mat\_31,1) + " " +StrF(mat\_41,1) 
Debug StrF(mat\_12,1) + " " + StrF(mat\_22,1) + " " +StrF(mat\_32,1) + " " +StrF(mat\_42,1) 
Debug StrF(mat\_13,1) + " " + StrF(mat\_23,1) + " " +StrF(mat\_33,1) + " " +StrF(mat\_43,1) 
Debug StrF(mat\_14,1) + " " + StrF(mat\_24,1) + " " +StrF(mat\_34,1) + " " +StrF(mat\_44,1) 
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Message par tmyke »

Merci Comtois je vais faire pareil, je vais étudier de près, je me lève seulement
et en suite je vais au boulot. Donc ce soir dès que je rentre, je te tiens au courant
Force et sagesse...
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Comtois, tout juste 6h de sommeil et il écrit un moteur 3d lol

Il dort une journée, et il nous écrit un OS :p
Répondre