C'est exceptionnel, je me lève à 7h en généralProgi1984 a écrit :Comtois, tout juste 6h de sommeil et il écrit un moteur 3d lol
Physque pour Dreamotion3D
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.
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
Désolé, je suis rentré dans la nuit.
J'ai donc essayé tes codes, la encore, cela ne semble pas fonctionner.
Dnas certains cas, on récupère bien les bon angles , mais dès que
l'on mixe trois angles avec des valeurs asser élevés, patatraque, c'est
plus bon.
je me donne encore jusqu'a la fin du WE pour ariver a regler la chose
J'ai donc essayé tes codes, la encore, cela ne semble pas fonctionner.
Dnas certains cas, on récupère bien les bon angles , mais dès que
l'on mixe trois angles avec des valeurs asser élevés, patatraque, c'est
plus bon.
je me donne encore jusqu'a la fin du WE pour ariver a regler la chose
Force et sagesse...
Pour améliorer les calculs , il y a la variable test à déclarer en flottant , j'ai oublié.
En fait le choix du quadrant est arbitraire, pour un sinus donné on a deux angles possibles et donc deux cos différents, faudrait voir s'il y a moyen d'extraire le cos dans la matrice pour vérifier dans quel quadrant on se situe.
voir aussi la discussion sur ce forum
Par contre , quand on utilise que le moteur graphique, les angles sont corrects ou pas ? je n'ai pas vérifié, je les utilise et je n'ai pas rencontré de problème pour l'instant.
Comment tu les calcules ces angles ? manifestement pas à partir de la matrice
Code : Tout sélectionner
Procedure DecomposeRollPitchYawZXYMatrix()
;http://blogs.msdn.com/MikePelton/archive/2004/10/29/249501.aspx
;http://www.developpez.net/forums/showthread.php?t=160276&page=2
angle_x = ASin(-mat\_32)
test.f = Cos(angle_x)
angle_x * #RadDeg
threshold.f = 0.001; // Hardcoded constant - burn him, he's a witch
If(test <> threshold)
angle_z = Atan2(mat\_12, mat\_22) * #RadDeg
angle_y = Atan2(mat\_31, mat\_33) * #RadDeg
Else
angle_z = Atan2(-mat\_21, mat\_11) * #RadDeg
angle_y = 0.0
EndIf
EndProcedureEn fait le choix du quadrant est arbitraire, pour un sinus donné on a deux angles possibles et donc deux cos différents, faudrait voir s'il y a moyen d'extraire le cos dans la matrice pour vérifier dans quel quadrant on se situe.
voir aussi la discussion sur ce forum
Par contre , quand on utilise que le moteur graphique, les angles sont corrects ou pas ? je n'ai pas vérifié, je les utilise et je n'ai pas rencontré de problème pour l'instant.
Comment tu les calcules ces angles ? manifestement pas à partir de la matrice
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.
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
A l'heure actuelle, quand avec DM3D tu demande un rotation standart (DM_RotateEntity) le code executé est le suivant:
Au niveau du moteur, cela fonctionne très bien et de plus c'est plutot optimisé
en therme de temps de calcul.
Le problème viens dès que tu veux récupérer les angles à partir de la matrice...
En attendant, je vais voir sur le forum dont tu donnes le lien.
Code : Tout sélectionner
//--------------------------------------------------------------------------------------
// fonction de Rotation
//--------------------------------------------------------------------------------------
CEntity::Rotate(float x, float y, float z)
{
D3DXQUATERNION cSc =D3DXQUATERNION(0.0,0.0,0.0,0.0);
D3DXQUATERNION cQuat;
rotation = D3DXVECTOR3(x,y,z);
D3DXQuaternionRotationYawPitchRoll( &cQuat, rotation.x, rotation.y, rotation.z);
D3DXMatrixTransformation( &mat_Scene, ¢re, &cSc, &scale, ¢re, &cQuat, &translate);
}
en therme de temps de calcul.
Le problème viens dès que tu veux récupérer les angles à partir de la matrice...
En attendant, je vais voir sur le forum dont tu donnes le lien.
Force et sagesse...
voila le fameux lien que je n'avais pas réussi à faire fonctionner jusqu'à présent Matrice de passage et angles d'euler
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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
je m'étais dit qu'en déduisant le cos(x) de la matrice , et en ayant déjà en dispo le sin(x) , ça permettrait de déterminer à coup sûr dans quel quadrant se situe l'angle en x , ben non , même pas !!
Je tombe sur une racine carrée , du coup , deux quadrants sont possibles !
J'ai pas cherché pour les autres cos et sin, mais je m'attends à tomber aussi sur des racines carrées qui n'aideront pas plus !
Je tombe sur une racine carrée , du coup , deux quadrants sont possibles !
Code : Tout sélectionner
Sqr(((mat\_22*mat\_33)-(mat\_12*mat\_32*mat\_31))/mat\_11)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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
j'ai fouillé dans les sources d'ogre
je n'ai pas encore regardé dans le détail , mais ... // WARNING. Not a unique solution. ... Je le crains
je n'ai pas encore regardé dans le détail , mais ... // WARNING. Not a unique solution. ... Je le crains
Code : Tout sélectionner
//-----------------------------------------------------------------------
bool Matrix3::ToEulerAnglesXYZ (float& rfYAngle, float& rfPAngle,
float& rfRAngle) const
{
// rot = cy*cz -cy*sz sy
// cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx
// -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy
rfPAngle = Math::getSingleton().ASin(m[0][2]);
if ( rfPAngle < Math::HALF_PI )
{
if ( rfPAngle > -Math::HALF_PI )
{
rfYAngle = Math::getSingleton().ATan2(-m[1][2],m[2][2]);
rfRAngle = Math::getSingleton().ATan2(-m[0][1],m[0][0]);
return true;
}
else
{
// WARNING. Not a unique solution.
float fRmY = Math::getSingleton().ATan2(m[1][0],m[1][1]);
rfRAngle = 0.0; // any angle works
rfYAngle = rfRAngle - fRmY;
return false;
}
}
else
{
// WARNING. Not a unique solution.
float fRpY = Math::getSingleton().ATan2(m[1][0],m[1][1]);
rfRAngle = 0.0; // any angle works
rfYAngle = fRpY - rfRAngle;
return false;
}
}
//-----------------------------------------------------------------------
bool Matrix3::ToEulerAnglesXZY (float& rfYAngle, float& rfPAngle,
float& rfRAngle) const
{
// rot = cy*cz -sz cz*sy
// sx*sy+cx*cy*sz cx*cz -cy*sx+cx*sy*sz
// -cx*sy+cy*sx*sz cz*sx cx*cy+sx*sy*sz
rfPAngle = Math::getSingleton().ASin(-m[0][1]);
if ( rfPAngle < Math::HALF_PI )
{
if ( rfPAngle > -Math::HALF_PI )
{
rfYAngle = Math::getSingleton().ATan2(m[2][1],m[1][1]);
rfRAngle = Math::getSingleton().ATan2(m[0][2],m[0][0]);
return true;
}
else
{
// WARNING. Not a unique solution.
float fRmY = Math::getSingleton().ATan2(-m[2][0],m[2][2]);
rfRAngle = 0.0; // any angle works
rfYAngle = rfRAngle - fRmY;
return false;
}
}
else
{
// WARNING. Not a unique solution.
float fRpY = Math::getSingleton().ATan2(-m[2][0],m[2][2]);
rfRAngle = 0.0; // any angle works
rfYAngle = fRpY - rfRAngle;
return false;
}
}
//-----------------------------------------------------------------------
bool Matrix3::ToEulerAnglesYXZ (float& rfYAngle, float& rfPAngle,
float& rfRAngle) const
{
// rot = cy*cz+sx*sy*sz cz*sx*sy-cy*sz cx*sy
// cx*sz cx*cz -sx
// -cz*sy+cy*sx*sz cy*cz*sx+sy*sz cx*cy
rfPAngle = Math::getSingleton().ASin(-m[1][2]);
if ( rfPAngle < Math::HALF_PI )
{
if ( rfPAngle > -Math::HALF_PI )
{
rfYAngle = Math::getSingleton().ATan2(m[0][2],m[2][2]);
rfRAngle = Math::getSingleton().ATan2(m[1][0],m[1][1]);
return true;
}
else
{
// WARNING. Not a unique solution.
float fRmY = Math::getSingleton().ATan2(-m[0][1],m[0][0]);
rfRAngle = 0.0; // any angle works
rfYAngle = rfRAngle - fRmY;
return false;
}
}
else
{
// WARNING. Not a unique solution.
float fRpY = Math::getSingleton().ATan2(-m[0][1],m[0][0]);
rfRAngle = 0.0; // any angle works
rfYAngle = fRpY - rfRAngle;
return false;
}
}
//-----------------------------------------------------------------------
bool Matrix3::ToEulerAnglesYZX (float& rfYAngle, float& rfPAngle,
float& rfRAngle) const
{
// rot = cy*cz sx*sy-cx*cy*sz cx*sy+cy*sx*sz
// sz cx*cz -cz*sx
// -cz*sy cy*sx+cx*sy*sz cx*cy-sx*sy*sz
rfPAngle = Math::getSingleton().ASin(m[1][0]);
if ( rfPAngle < Math::HALF_PI )
{
if ( rfPAngle > -Math::HALF_PI )
{
rfYAngle = Math::getSingleton().ATan2(-m[2][0],m[0][0]);
rfRAngle = Math::getSingleton().ATan2(-m[1][2],m[1][1]);
return true;
}
else
{
// WARNING. Not a unique solution.
float fRmY = Math::getSingleton().ATan2(m[2][1],m[2][2]);
rfRAngle = 0.0; // any angle works
rfYAngle = rfRAngle - fRmY;
return false;
}
}
else
{
// WARNING. Not a unique solution.
float fRpY = Math::getSingleton().ATan2(m[2][1],m[2][2]);
rfRAngle = 0.0; // any angle works
rfYAngle = fRpY - rfRAngle;
return false;
}
}
//-----------------------------------------------------------------------
bool Matrix3::ToEulerAnglesZXY (float& rfYAngle, float& rfPAngle,
float& rfRAngle) const
{
// rot = cy*cz-sx*sy*sz -cx*sz cz*sy+cy*sx*sz
// cz*sx*sy+cy*sz cx*cz -cy*cz*sx+sy*sz
// -cx*sy sx cx*cy
rfPAngle = Math::getSingleton().ASin(m[2][1]);
if ( rfPAngle < Math::HALF_PI )
{
if ( rfPAngle > -Math::HALF_PI )
{
rfYAngle = Math::getSingleton().ATan2(-m[0][1],m[1][1]);
rfRAngle = Math::getSingleton().ATan2(-m[2][0],m[2][2]);
return true;
}
else
{
// WARNING. Not a unique solution.
float fRmY = Math::getSingleton().ATan2(m[0][2],m[0][0]);
rfRAngle = 0.0; // any angle works
rfYAngle = rfRAngle - fRmY;
return false;
}
}
else
{
// WARNING. Not a unique solution.
float fRpY = Math::getSingleton().ATan2(m[0][2],m[0][0]);
rfRAngle = 0.0; // any angle works
rfYAngle = fRpY - rfRAngle;
return false;
}
}
//-----------------------------------------------------------------------
bool Matrix3::ToEulerAnglesZYX (float& rfYAngle, float& rfPAngle,
float& rfRAngle) const
{
// rot = cy*cz cz*sx*sy-cx*sz cx*cz*sy+sx*sz
// cy*sz cx*cz+sx*sy*sz -cz*sx+cx*sy*sz
// -sy cy*sx cx*cy
rfPAngle = Math::getSingleton().ASin(-m[2][0]);
if ( rfPAngle < Math::HALF_PI )
{
if ( rfPAngle > -Math::HALF_PI )
{
rfYAngle = Math::getSingleton().ATan2(m[1][0],m[0][0]);
rfRAngle = Math::getSingleton().ATan2(m[2][1],m[2][2]);
return true;
}
else
{
// WARNING. Not a unique solution.
float fRmY = Math::getSingleton().ATan2(-m[0][1],m[0][2]);
rfRAngle = 0.0; // any angle works
rfYAngle = rfRAngle - fRmY;
return false;
}
}
else
{
// WARNING. Not a unique solution.
float fRpY = Math::getSingleton().ATan2(-m[0][1],m[0][2]);
rfRAngle = 0.0; // any angle works
rfYAngle = fRpY - rfRAngle;
return false;
}
}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.
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
Oui, j'ai fais pareil, y compris dans le code du 'torque engine', en fait
il ne semble pas y avoir de solution 'unique'. J'ai poste sur 'developpez.net'
pour savoir si quelqu'un a une amorce de solution par rapport au FAQ du meme site...
En espérant une amorce de solution...
Sinon je continue a chercher en attendant
il ne semble pas y avoir de solution 'unique'. J'ai poste sur 'developpez.net'
pour savoir si quelqu'un a une amorce de solution par rapport au FAQ du meme site...
En espérant une amorce de solution...
Sinon je continue a chercher en attendant
Force et sagesse...
Je suis en train de lire ça
http://www.ogre3d.org/wiki/index.php/Qu ... ion_Primer
et en faisant une recherche sur angle euler sur le forum d'ogre , on trouve pas mal de lien , reste à voir s'il y a la bonne info dans tout ça !
http://www.ogre3d.org/wiki/index.php/Qu ... ion_Primer
et en faisant une recherche sur angle euler sur le forum d'ogre , on trouve pas mal de lien , reste à voir s'il y a la bonne info dans tout ça !
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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
en passant par le quaternion j'obtiens l'angle x, reste à trouver le reste 
Code : Tout sélectionner
; Fichiers Include
IncludePath "..\Include\"
IncludeFile "d3dx9.pbi"
#RadDeg = 180.0 / #PI
#DegRad = #PI / 180.0
#HALF_PI = #PI /2.0
x.f = 95 * #DegRad
y.f = 65 * #DegRad
z.f = 34 * #DegRad
D3DXQuaternionRotationYawPitchRoll( @cQuat.D3DXQUATERNION, x, y, z)
Debug StrF(cQuat\x,1) + " " + StrF(cQuat\y,1) + " " +StrF(cQuat\z,1) + " " +StrF(cQuat\w,1)
Debug "Angle x = " + StrF(2 * ACos(cQuat\w) * #RadDeg,3)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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
j'avais repris ton exemple pour la rotation avec un quaternion , mais tu n'as pas inversé le y et le x ?
YawPitchRoll c'est YXZ non ?
YawPitchRoll c'est YXZ non ?
Code : Tout sélectionner
; Fichiers Include
IncludePath "..\Include\"
IncludeFile "d3dx9.pbi"
#RadDeg = 180.0 / #PI
#DegRad = #PI / 180.0
#HALF_PI = #PI / 2.0
x.f = 50 * #DegRad
y.f = -57 * #DegRad
z.f = 94 * #DegRad
D3DXQuaternionRotationYawPitchRoll( @cQuat.D3DXQUATERNION, y, x, z)
Debug StrF(cQuat\x,3) + " " + StrF(cQuat\y,3) + " " +StrF(cQuat\z,3) + " " +StrF(cQuat\w,3)
Debug "Angle y = " + StrF(2 * ACos(cQuat\w) * #RadDeg, 3)
Debug "Angle y = " + StrF(2 * ASin(cQuat\y) * #RadDeg, 3)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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Parce que le moteur physique ne connait que la matrice pour agir sur les entitys, et c'est cette matrice qu'il faut interpréter pour retrouver les angles.djes a écrit :Question bête. Pourquoi ne pas définir trois axes par objets, et tourner ensuite l'objet par rapport à ceux-ci. Ainsi, la combinaison rotation des axes+rotation de l'objet serait reproductible (enfin je pense).
bon j'ai fini par télécharger l'ensemble des sources d'ogre, je n'avais jusqu'ici que la version édulcorée adaptée à purebasic.
Voila à quoi ressemble les fonctions qui donnent les angles.
ça ne fonctionne pas chez moi, mais c'est intéressant de se plonger dedans
Faut que je regarde la fonction GetOrientation()
Code : Tout sélectionner
Radian Quaternion::getRoll(void) const
{
return Radian(Math::ATan2(2*(x*y + w*z), w*w + x*x - y*y - z*z));
}
//-----------------------------------------------------------------------
Radian Quaternion::getPitch(void) const
{
return Radian(Math::ATan2(2*(y*z + w*x), w*w - x*x - y*y + z*z));
}
//-----------------------------------------------------------------------
Radian Quaternion::getYaw(void) const
{
return Radian(Math::ASin(-2*(x*z - w*y)));
}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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
je ne sais pas si ça va servir , mais j'ai appris plein de trucs au passage 
Faudra vérifier dans le fichier d3dx9math.pbi il me semble que j'ai corrigé une déclaration , c'était des pointeurs avant je crois ?
Faudra vérifier dans le fichier d3dx9math.pbi il me semble que j'ai corrigé une déclaration , c'était des pointeurs avant je crois ?
Code : Tout sélectionner
D3DXQuaternionRotationYawPitchRoll.l(*pOut.D3DXQUATERNION, Yaw.f, Pitch.f, Roll.f)Code : Tout sélectionner
; Fichiers Include
IncludePath "..\Include\"
IncludeFile "d3dx9.pbi"
Declare.f getRoll(*cQuat.D3DXQUATERNION)
Declare.f getPitch(*cQuat.D3DXQUATERNION)
Declare.f getYaw(*cQuat.D3DXQUATERNION)
Declare.f atan2(y.d,x.d)
Define.D3DXQUATERNION Pitch, Yaw, Roll, pout
Define.D3DXMATRIX mat
#RadDeg = 180.0 / #PI
#DegRad = #PI / 180.0
#HALF_PI = #PI / 2.0
;- Saisir les angles ici
x.f = 65 * #DegRad
y.f = -67 * #DegRad
z.f = 93 * #DegRad
;Rotation axe par axe
D3DXQuaternionRotationYawPitchRoll(Pitch, 0, x, 0)
D3DXQuaternionRotationYawPitchRoll(Yaw , y, 0, 0)
D3DXQuaternionRotationYawPitchRoll(Roll , 0, 0, z)
;Affiche le résultat
Debug StrF(getPitch(Pitch) * #RadDeg, 2)
Debug StrF(getYaw(Yaw) * #RadDeg, 2)
Debug StrF(getRoll(Roll) * #RadDeg, 2)
Debug "---"
;Un quaternion regroupant toutes les rotations
D3DXQuaternionMultiply.l(@pOut, @Pitch, @Yaw)
D3DXQuaternionMultiply.l(@pOut, @pOut, @Roll)
;Affiche le résultat
Debug StrF(getPitch(@pOut) * #RadDeg, 2)
Debug StrF(getYaw(@pOut) * #RadDeg, 2)
Debug StrF(getRoll(@pOut) * #RadDeg, 2)
Debug "---"
; ;Matrice de rotation
; D3DXMatrixRotationYawPitchRoll(@mat, y, x, z)
; ;Repasse par le quaternion pour voir
; D3DXQuaternionRotationMatrix.l(@pOut, @mat)
; Debug getPitch(@pOut) * #RadDeg
; Debug getYaw(@pOut) * #RadDeg
; Debug getRoll(@pOut) * #RadDeg
; Debug "---"
End
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 getRoll(*cQuat.D3DXQUATERNION)
ProcedureReturn ATan2(2*(*cQuat\x * *cQuat\y + *cQuat\w * *cQuat\z), *cQuat\w * *cQuat\w + *cQuat\x * *cQuat\x - *cQuat\y * *cQuat\y - *cQuat\z * *cQuat\z)
EndProcedure
Procedure.f getPitch(*cQuat.D3DXQUATERNION)
ProcedureReturn ATan2(2*(*cQuat\y * *cQuat\z + *cQuat\w * *cQuat\x), *cQuat\w * *cQuat\w - *cQuat\x * *cQuat\x - *cQuat\y * *cQuat\y + *cQuat\z * *cQuat\z)
EndProcedure
Procedure.f getYaw(*cQuat.D3DXQUATERNION)
ProcedureReturn ASin(-2*(*cQuat\x * *cQuat\z - *cQuat\w * *cQuat\y))
EndProcedurehttp://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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.