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 »

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).
comme le dit fort justement Comtois, il prob se situe au niveua du moteur physique, qui ne travaille
qu'avec les matrices. Pour pour récupérer les angles raportés, il faut en passer par la. Dans le
moteur graphique lui meme, tu obtiens les valeurs sans soucis, sauf sur les elements par pivot
qui eux aussi passe par la matrice de repésentation.
comtois a écrit :j'avais repris ton exemple pour la rotation avec un quaternion , mais tu n'as pas
inversé le y et le x ?
Si, mais c'est fait lors de l'appel de la fonction sur la classe 'CEntity', genre
entity->Rotate(y,x,z);

Je n'ai pas de réponse des différent forums ou j'ai posté.
Par je suis sur le code suivant, qui a partir d'un quaternion semble bien fonctionner:

Code : Tout sélectionner

; Fichiers Include
IncludePath "Include"
IncludeFile "d3dx9.pbi"

#RadDeg  = 180.0 / #PI
#DegRad  = #PI   / 180.0

  ;---------------------------------------------
  ; creation d'une matrice a partir d'angle
  ; créés sur un quaternion
  ;---------------------------------------------
  mat.D3DXMATRIX
	cQuat.D3DXQUATERNION
	D3DXQuaternionRotationYawPitchRoll( @cQuat, 35*#DegRad, 10*#DegRad, 90*#DegRad)
  D3DXMatrixTransformation( @mat,	#Null, #Null, #Null, #Null,	@cQuat,	#Null)
  Debug "--quat de départ ----"
  Debug cQuat\x
  Debug cQuat\y
  Debug cQuat\z
  Debug cQuat\w 
  Debug "--------"


  ;------------------------------------------------------
  ; récupération du quaternion a partir de la matrice
  ;------------------------------------------------------
	pOutScale.D3DXVECTOR3
	pOutRotation.D3DXQUATERNION
	pOutTranslation.D3DXVECTOR3
	D3DXMatrixDecompose( @pOutScale,  @pOutRotation, @pOutTranslation, @mat)
  Debug "--quat récupéré ----"
  Debug pOutRotation\x
  Debug pOutRotation\y
  Debug pOutRotation\z
  Debug pOutRotation\w
En créant une matrice a partir d'un quaternion puis en récupérant ce quaternion
a partir de la matrice, cela semble correcte.
j'ai plus qu'a récupérer les angles sur le quaternion


(bien pour le bug sur la fonction 'D3DXQuaternionRotationYawPitchRoll')
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

C'est pas gagné , y'a encore un traitement particulier à faire quand le pitch est proche du 90° :?

http://en.wikipedia.org/wiki/Conversion ... ler_angles
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 »

Moui, la je me prend la tete dessus.
Pourtant le prob est simple, surtout si tu lis certains tuto.
Tu créé un Quaternion a partir de 3 angles, et en suite tu veux a partir de ce Quaternion
récupérer tes trois angles...

3 heures que je suis dessus et j'ai pas avancé de manière très significative pour l'instant...
Force et sagesse...
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 »

Voici un code sur les quaternion qui semble fonctionner.
Je refais un code complet
Quaternion / matrice pour tester tous cela et je poste cela dès que possible...

Code : Tout sélectionner

; Fichiers Include7
IncludePath "Include\"
IncludeFile "d3dx9.pbi"


Declare.f atan2(y.d,x.d)
Declare   QuatToEulerAngles()
Declare   EulerAnglesToQuat(x.f,y.f,z.f)

Global norm.f
Global cQuat.D3DXQUATERNION
Global rkAxis.D3DXVECTOR3
Global pAngle.D3DXVECTOR3

	

anglex.f = 2.1
angley.f = 0.25
anglez.f = 1.85	

  EulerAnglesToQuat(anglex, angley, anglez)

  Debug "--angle injectés ----"
  Debug anglex
  Debug angley
  Debug anglez
  Debug "------"
	
  Debug "--angle récupérés ----"
  QuatToEulerAngles()
  Debug pAngle\x
  Debug pAngle\y
  Debug pAngle\z


  
End

Procedure EulerAnglesToQuat(x.f,y.f,z.f)

    Protected roll.f,pitch.f,yaw.f
    Protected cyaw.f, cpitch.f, croll.f, syaw.f, spitch.f, sroll.f
    Protected cyawcpitch.f, syawspitch.f, cyawspitch.f, syawcpitch.f
    roll = x
    pitch= y
    yaw  = z

    cyaw = Cos(0.5 * yaw)
    cpitch = Cos(0.5 * pitch)
    croll = Cos(0.5 * roll)
    syaw = Sin(0.5 * yaw)
    spitch = Sin(0.5 * pitch)
    sroll = Sin(0.5 * roll)

    cyawcpitch = cyaw*cpitch
    syawspitch = syaw*spitch
    cyawspitch = cyaw*spitch
    syawcpitch = syaw*cpitch


    norm = (cyawcpitch * croll + syawspitch * sroll)
    Debug norm
    cQuat\x = (cyawcpitch * sroll - syawspitch * croll)
    cQuat\y = (cyawspitch * croll + syawcpitch * sroll)
    cQuat\z = (syawcpitch * croll - cyawspitch * sroll)
    cQuat\w = norm
EndProcedure
Procedure QuatToEulerAngles()

    Protected r11.f, r21.f, r31.f, r32.f, r33.f, r12.f, r13.f
    Protected q00.f, q11.f, q22.f, q33.f
    Protected tmp.f
    

    q00 = cQuat\w * cQuat\w
    q11 = cQuat\x * cQuat\x
    q22 = cQuat\y * cQuat\y
    q33 = cQuat\z * cQuat\z

    r11 = q00 + q11 - q22 - q33
    r21 = 2 * (cQuat\x*cQuat\y + cQuat\w*cQuat\z)
    r31 = 2 * (cQuat\x*cQuat\z - cQuat\w*cQuat\y)
    r32 = 2 * (cQuat\y*cQuat\z + cQuat\w*cQuat\x)
    r33 = q00 - q11 - q22 + q33

    tmp = Abs(r31)
    If(tmp > 0.999999)
        r12 = 2 * (cQuat\x*cQuat\y - cQuat\w*cQuat\z)
        r13 = 2 * (cQuat\x*cQuat\z + cQuat\w*cQuat\y)

        pAngle\x = 0.0
        pAngle\y =  (-(Pi/2) * r31/tmp)
        pAngle\z = ATan2(-r12, -r31*r13) 
    Else
        pAngle\x = ATan2(r32, r33)   ;// roll
        pAngle\y = ASin(-r31)        ;// pitch
        pAngle\z = ATan2(r21, r11)   ;// yaw
    EndIf

EndProcedure	
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 
Force et sagesse...
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 »

Voici un code un peu plus complet, avec construction d'un quaternion a partir
de 3 angles, creation de la matrice, recupération de la matrice, récupération des angles.
Plus qu'a voir ce que cela donne en 3D...

Code : Tout sélectionner

; Fichiers Include7
IncludePath "Include\"
IncludeFile "d3dx9.pbi"


Declare.f atan2(y.d,x.d)
Declare   QuatToEulerAngles()
Declare   EulerAnglesToQuat(x.f,y.f,z.f)

Global norm.f
Global cQuat.D3DXQUATERNION
Global rkAxis.D3DXVECTOR3
Global pAngle.D3DXVECTOR3



anglex.f = 2.1
angley.f = 0.25
anglez.f = 1.15	


  ;---------------------------------------------
  ; creation du quaternion de rotation
  ;---------------------------------------------
  EulerAnglesToQuat(anglex, angley, anglez)
  Debug "--angle injectés ----"
  Debug anglex
  Debug angley
  Debug anglez
  Debug "------"

  ;---------------------------------------------
  ; creation d'une matrice a partir d'angle
  ; créés sur un quaternion
  ;---------------------------------------------
  mat.D3DXMATRIX
	D3DXMatrixTransformation( @mat,	#Null, #Null, #Null, #Null,	@cQuat,	#Null)

	
  ;------------------------------------------------------
  ; récupération du quaternion a partir de la matrice
  ;------------------------------------------------------
	cQuat\x=0 : cQuat\y=0 : cQuat\z=0 : cQuat\w=0 ; RAZ de cQuat par securité
	pOutScale.D3DXVECTOR3
	pOutTranslation.D3DXVECTOR3
	D3DXMatrixDecompose( @pOutScale,  @cQuat, @pOutTranslation, @mat)
  QuatToEulerAngles()
  Debug "--angle récupérés ----"
  Debug pAngle\x
  Debug pAngle\y
  Debug pAngle\z
  
End

Procedure EulerAnglesToQuat(x.f,y.f,z.f)

    Protected roll.f,pitch.f,yaw.f
    Protected cyaw.f, cpitch.f, croll.f, syaw.f, spitch.f, sroll.f
    Protected cyawcpitch.f, syawspitch.f, cyawspitch.f, syawcpitch.f
    roll = x
    pitch= y
    yaw  = z

    cyaw = Cos(0.5 * yaw)
    cpitch = Cos(0.5 * pitch)
    croll = Cos(0.5 * roll)
    syaw = Sin(0.5 * yaw)
    spitch = Sin(0.5 * pitch)
    sroll = Sin(0.5 * roll)

    cyawcpitch = cyaw*cpitch
    syawspitch = syaw*spitch
    cyawspitch = cyaw*spitch
    syawcpitch = syaw*cpitch


    norm = (cyawcpitch * croll + syawspitch * sroll)
    cQuat\x = (cyawcpitch * sroll - syawspitch * croll)
    cQuat\y = (cyawspitch * croll + syawcpitch * sroll)
    cQuat\z = (syawcpitch * croll - cyawspitch * sroll)
    cQuat\w = norm
EndProcedure
Procedure QuatToEulerAngles()

    Protected r11.f, r21.f, r31.f, r32.f, r33.f, r12.f, r13.f
    Protected q00.f, q11.f, q22.f, q33.f
    Protected tmp.f
    

    q00 = cQuat\w * cQuat\w
    q11 = cQuat\x * cQuat\x
    q22 = cQuat\y * cQuat\y
    q33 = cQuat\z * cQuat\z

    r11 = q00 + q11 - q22 - q33
    r21 = 2 * (cQuat\x*cQuat\y + cQuat\w*cQuat\z)
    r31 = 2 * (cQuat\x*cQuat\z - cQuat\w*cQuat\y)
    r32 = 2 * (cQuat\y*cQuat\z + cQuat\w*cQuat\x)
    r33 = q00 - q11 - q22 + q33

    tmp = Abs(r31)
    If(tmp > 0.999999)
        r12 = 2 * (cQuat\x*cQuat\y - cQuat\w*cQuat\z)
        r13 = 2 * (cQuat\x*cQuat\z + cQuat\w*cQuat\y)

        pAngle\x = 0.0
        pAngle\y =  (-(Pi/2) * r31/tmp)
        pAngle\z = ATan2(-r12, -r31*r13) 
    Else
        pAngle\x = ATan2(r32, r33)   ;// roll
        pAngle\y = ASin(-r31)        ;// pitch
        pAngle\z = ATan2(r21, r11)   ;// yaw
    EndIf

EndProcedure	
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 
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Fais l'essai avec ça
anglex.f = #PI
angley.f = #PI
anglez.f = #PI

Enfin il y a une piste :)

Sinon dans la fonction QuatToEulerAngles() tu as une variable PI , ça ne serait pas la constante #PI plutôt ?
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 »

Oui pour #PI, erreur de syntaxe.
Sinon, archg, ces satanés angles remarquable, je les @"àè-"&é...

Image
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Note2: The cutoff point for singulaties is set to 0.499 and -0.499 which corresponds to 86.3 degrees, this can be set closer to 90 if required but we have to accept some inaccuracy around the singulaties.
C'est extrait de ce site
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 »

Malgrés tout cela fonctionne plutot bien, j'ai meme réussi a faire un DM_DetachEntity()
qui fonctionne bien. Par contre, la gestion des angles est particulière désormais
J'ai fait un module a part pour que tu testes:

http://www.dreamotion3d.com/PureBasic/modulePB2.zip

Pour la gestion d'un avion par exemple, cela devient space...
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

tmyke a écrit :Malgrés tout cela fonctionne plutot bien, j'ai meme réussi a faire un DM_DetachEntity() qui fonctionne bien.
Cool, je testerai ça plus tard, à moins que la curiosité l'emporte et que j'y jette un oeil ce soir :)

Merci pour tes efforts.
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 »

bon je viens de tester avec mon code le rubick cube. les premières rotations semblent correctes, mais ça merdouille très rapidement, après deux ou trois rotations.

Faudrait que je trouve un code plus simple pour tester, parce qu'après tout je ne sais pas si c'est mon code qui est bogué ou non.

Code : Tout sélectionner

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

Enumeration 
  #Haut
  #Bas
  #Devant
  #Derriere
  #Gauche
  #Droit
  #CentreX
  #CentreY
  #CentreZ
EndEnumeration

Declare CreateCube(x, y, z)
Declare DetacheRotation()
Declare ParentRotation(No)
Declare Rotation(No, S)
Declare MiseAJour(Type, S)


Global *camera.CEntity
Global *font.CFont
Global *brush.CBrush
Global *texture.CTexture
Global *Cube
Global Taille
Define Angle

Global Dim *Pivot(8)
Global Dim *Rubik(2, 2, 2)
Global Dim *TempRubik(2, 2, 2)
;-Initialisation 
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  End
EndIf

;-ouvre un ecran 3D
DM_Graphics3D(800, 600, 32,  1, 1)

;-font
*font = DM_LoadFont("Arial", 8, 1)
DM_SetColorText(*font, 255, 255, 0,255)

;-Texture
*texture = DM_CreateTexture(256,256)
;ré-oriente le buffer de sortie graphique vers notre texture
DM_SetBuffer(*texture)
DM_BeginScene()
  DM_ClsScreen (  0, 0,   0, 255)      ; efface le buffer avec une couleur
  DM_SetColor2D(255, 0,   0, 255)      ; change couleur du trait
  DM_DrawRect  (  1, 1, 254, 254)      ; dessin d'un rectangle 2D
DM_EndScene()
;de nouveau le buffer vers l'ecran
DM_SetBuffer(#Null)

;-Brush
*brush = DM_CreateBrush(Str(*entity))
DM_BrushAmbient(*brush, 255,128,0,255)
DM_BrushDiffuse(*brush, 255,128,0,255)
DM_BrushTexture(*brush, *texture, 0)
; modifie l'état de rendu de la Brush pour voir de tous les cotés
DM_BrushAddRender(*brush, #D3DRS_CULLMODE, #D3DCULL_NONE)

;-Creation rubik cube
Taille = 50
For z = 0 To 2
  For y = 0 To 2
    For x = 0 To 2
      No = CreateCube(x, y, z)
      DM_ScaleEntity(No, Taille - 2, Taille - 2, Taille - 2)
      DM_PositionEntity(No, (x-1) * Taille , (y-1) * Taille , (z-1) * Taille)
      *Rubik(x,y,z) = No
    Next x
  Next y
Next z

;-Pivots
For i = 0 To 8
  *Pivot(i) = DM_CreatePivot()
Next i
Angle = 90
  
;-Light
;DM_AmbiantLight(180, 180, 180)

;-camera
*camera = DM_CreateCamera(#Null)
DM_CameraClsColor(*camera, 0, 0, 85)
DM_PositionEntity(*camera, DM_EntityX(*Rubik(1,1,1)) + 250,DM_EntityY(*Rubik(1,1,1)) + 250, DM_EntityZ(*Rubik(1,1,1)) - 250)
DM_PointEntity(*camera, *Rubik(1,1,1))

;-Boucle principale
Repeat

  ExamineKeyboard()
    
  If KeyboardReleased(#PB_Key_F1)
    Pause = 1 - Pause
  EndIf

  ExamineMouse()
;   If MouseButton(#PB_MouseButton_Left)
;     *Cube = DM_CameraPick(*camera, MouseX(), MouseY())
;     ;Recherche le cube 
;     For x = 0 To 2
;       For y = 0 To 2
;         For z = 0 To 2
;           If *Rubik(x, y, z) = *Cube
;             px = x : py = y : pz = z 
;             Break 3
;           EndIf
;         Next z
;       Next y
;     Next x  
;     ;Calcul le type de rotation en fonction de la position du cube
;     If MouseDeltaX()<>0 Or MouseDeltaY()<>0
;       Dx.f = MouseDeltaX()
;       Dy.F = MouseDeltaY()
;     EndIf
;           
;   EndIf
  
  If Angle < 90
    If pause = 0
    Rotation(Type, Sens)
    Angle + 1
    EndIf
    If Angle = 90
      MiseAjour(Type, Sens)       
    EndIf  
  EndIf

  If Angle = 90
    DetacheRotation()
    Angle = 0
    Type = Random(8)
    ;Type = #CentreZ 
    Repeat
      Sens = 1-Random(2)
    Until Sens <> 0
    ParentRotation(Type)
  EndIf
    
  DM_BeginScene()
    DM_Renderworld()
    DM_DrawText(*font,0,0,StrF(DX,2) + " : " + StrF(dy,2))
    DM_SetColor2D(255, 255, 255, 255)
    DM_DrawOval(MouseX(), MouseY(), 8, 8)
  DM_EndScene()

Until KeyboardPushed(#PB_Key_Escape)
DM_ClearGraphics()
End

Procedure MiseAjour(Type, Sens)
  Define *Temp
  If Type = #Haut Or Type = #Droit Or Type = #Derriere
    h = 2
  ElseIf Type = #CentreX Or Type = #CentreY Or Type = #CentreZ
    h = 1
  ElseIf Type = #Bas Or Type = #Gauche Or type = #Devant
    h = 0
  EndIf  
  
  CopyMemory(*Rubik(), *TempRubik(), SizeOf(Long) * 27)

  If Type = #Haut Or Type = #Bas Or Type = #CentreY 
    If Sens
      
      *Rubik(0, h, 2) = *TempRubik(2, h, 2)  
      *Rubik(1, h, 2) = *TempRubik(2, h, 1)
      *Rubik(2, h, 2) = *TempRubik(2, h, 0)
      
      *Rubik(0, h, 1) = *TempRubik(1, h, 2)  
      *Rubik(1, h, 1) = *TempRubik(1, h, 1)
      *Rubik(2, h, 1) = *TempRubik(1, h, 0)  
      
      *Rubik(0, h, 0) = *TempRubik(0, h, 2)
      *Rubik(1, h, 0) = *TempRubik(0, h, 1)
      *Rubik(2, h, 0) = *TempRubik(0, h, 0)
    Else
      
      *Rubik(0, h, 0) = *TempRubik(0, h, 2)  
      *Rubik(0, h, 1) = *TempRubik(1, h, 2)
      *Rubik(0, h, 2) = *TempRubik(2, h, 2)
      
      *Rubik(1, h, 0) = *TempRubik(0, h, 1)  
      *Rubik(1, h, 1) = *TempRubik(1, h, 1)
      *Rubik(1, h, 2) = *TempRubik(2, h, 1)  
      
      *Rubik(2, h, 0) = *TempRubik(0, h, 0)
      *Rubik(2, h, 1) = *TempRubik(1, h, 0)
      *Rubik(2, h, 2) = *TempRubik(2, h, 0)

    EndIf
  
  ElseIf Type = #Gauche Or Type = #Droit Or Type = #CentreX    
    If Sens
      
      *Rubik(h, 0, 0) = *TempRubik(h, 0, 2)  
      *Rubik(h, 0, 1) = *TempRubik(h, 1, 2)
      *Rubik(h, 0, 2) = *TempRubik(h, 2, 2)
      
      *Rubik(h, 1, 0) = *TempRubik(h, 0, 1)  
      *Rubik(h, 1, 1) = *TempRubik(h, 1, 1)
      *Rubik(h, 1, 2) = *TempRubik(h, 2, 1)  
      
      *Rubik(h, 2, 0) = *TempRubik(h, 0, 0)
      *Rubik(h, 2, 1) = *TempRubik(h, 1, 0)
      *Rubik(h, 2, 2) = *TempRubik(h, 2, 0)

    Else
      
      *Rubik(h, 0, 2) = *TempRubik(h, 2, 2)  
      *Rubik(h, 1, 2) = *TempRubik(h, 2, 1)
      *Rubik(h, 2, 2) = *TempRubik(h, 2, 0)
      
      *Rubik(h, 0, 1) = *TempRubik(h, 1, 2)  
      *Rubik(h, 1, 1) = *TempRubik(h, 1, 1)
      *Rubik(h, 2, 1) = *TempRubik(h, 1, 0)  
      
      *Rubik(h, 0, 0) = *TempRubik(h, 0, 2)
      *Rubik(h, 1, 0) = *TempRubik(h, 0, 1)
      *Rubik(h, 2, 0) = *TempRubik(h, 0, 0)

    EndIf  
  
  Else  
    If Sens
    
      *Rubik(0, 0, h) = *TempRubik(0, 2, h)  
      *Rubik(0, 1, h) = *TempRubik(1, 2, h)
      *Rubik(0, 2, h) = *TempRubik(2, 2, h)
      
      *Rubik(1, 0, h) = *TempRubik(0, 1, h)  
      *Rubik(1, 1, h) = *TempRubik(1, 1, h)
      *Rubik(1, 2, h) = *TempRubik(2, 1, h)  
      
      *Rubik(2, 0, h) = *TempRubik(0, 0, h)
      *Rubik(2, 1, h) = *TempRubik(1, 0, h)
      *Rubik(2, 2, h) = *TempRubik(2, 0, h) 
      
    Else
    
      *Rubik(0, 2, h) = *TempRubik(2, 2, h)  
      *Rubik(1, 2, h) = *TempRubik(2, 1, h)
      *Rubik(2, 2, h) = *TempRubik(2, 0, h)
      
      *Rubik(0, 1, h) = *TempRubik(1, 2, h)  
      *Rubik(1, 1, h) = *TempRubik(1, 1, h)
      *Rubik(2, 1, h) = *TempRubik(1, 0, h)  
      
      *Rubik(0, 0, h) = *TempRubik(0, 2, h)
      *Rubik(1, 0, h) = *TempRubik(0, 1, h)
      *Rubik(2, 0, h) = *TempRubik(0, 0, h)       

    EndIf
    
  EndIf
  
EndProcedure

Procedure DetacheRotation()
  For x = 0 To 2
    For y = 0 To 2 
      For z = 0 To 2
        If DM_GetParent(*Rubik(x, y, z))
          DM_DetachEntity(*Rubik(x, y, z))
        EndIf  
      Next z
    Next y  
  Next x 
EndProcedure
Procedure ParentRotation(No)
  Select No
    Case #Haut 
      For x = 0 To 2
        For z = 0 To 2
          DM_EntityParent(*Rubik(x, 2, z), *Pivot(#Haut))
        Next z
      Next x      
    Case #Bas
      For x = 0 To 2
        For z = 0 To 2
          DM_EntityParent(*Rubik(x, 0, z), *Pivot(#Bas))
        Next z
      Next x  
    Case #Devant
      For x = 0 To 2
        For y = 0 To 2
          DM_EntityParent(*Rubik(x, y, 0), *Pivot(#Devant))
        Next y
      Next x  
    Case #Derriere
      For x = 0 To 2
        For y = 0 To 2
          DM_EntityParent(*Rubik(x, y, 2), *Pivot(#Derriere))
        Next y
      Next x  
    Case #Gauche
      For y = 0 To 2
        For z = 0 To 2
          DM_EntityParent(*Rubik(0, y, z), *Pivot(#Gauche))
        Next z
      Next y  
    Case #Droit
      For y = 0 To 2
        For z = 0 To 2
          DM_EntityParent(*Rubik(2, y, z), *Pivot(#Droit))
        Next z
      Next y   
    Case #CentreX
      For y = 0 To 2
        For z = 0 To 2
          DM_EntityParent(*Rubik(1, y, z), *Pivot(#CentreX))
        Next z
      Next y 
    Case #CentreY 
      For x = 0 To 2
        For z = 0 To 2
          DM_EntityParent(*Rubik(x, 1, z), *Pivot(#CentreY))
        Next z
      Next x  
    Case #CentreZ 
      For x = 0 To 2
        For y = 0 To 2
          DM_EntityParent(*Rubik(x, y, 1), *Pivot(#CentreZ))
        Next y
      Next x               
  EndSelect
EndProcedure
Procedure Rotation(No, S)
  Select No
    Case #Haut 
      DM_TurnEntity(*pivot(#Haut)    , 0, S, 0)
    Case #Bas
      DM_TurnEntity(*pivot(#Bas)     , 0, S, 0)
    Case #Devant
      DM_TurnEntity(*pivot(#Devant)  , 0, 0, S)
    Case #Derriere
      DM_TurnEntity(*pivot(#Derriere), 0, 0, S)
    Case #Gauche
      DM_TurnEntity(*pivot(#Gauche)  , S, 0, 0)
    Case #Droit
      DM_TurnEntity(*pivot(#Droit)   , S, 0, 0)
    Case #CentreX
      DM_TurnEntity(*pivot(#CentreX) , S, 0, 0)
    Case #CentreY 
      DM_TurnEntity(*pivot(#CentreY) , 0, S, 0)
    Case #CentreZ 
      DM_TurnEntity(*pivot(#CentreZ) , 0, 0, S)    
  EndSelect
EndProcedure
Procedure CreateCube(xx, yy, zz)
  Define.CEntity *entity
  DM_EntityFormat(2)
  *entity = DM_CreateMesh(12, 24, 1, #Null)

  Restore Vertex
  For i= 0 To 23
    Read x.f : Read y.f : Read z.f
    Read u.f : Read v.f
    ;Read Rouge : Read Vert : Read bleu
    rouge = 70 : Vert = 60 : Bleu = 80
    ;Couleur dessus
    If yy = 2 And i >=0 And i <=3
      Rouge = 0 : Vert = 0 : bleu = 255
    EndIf
    ;Couleur dessous
    If yy = 0 And i >=4 And i <=7
      Rouge = 255 : Vert = 255 : bleu = 255
    EndIf
    ;Couleur derriere
    If zz = 2 And i >=8 And i <=11
      Rouge = 255 : Vert = 255 : bleu = 0
    EndIf
    ;Couleur devant
    If zz = 0 And i >=12 And i <=15
      Rouge = 255 : Vert = 128 : bleu = 0
    EndIf
    ;Couleur gauche
    If xx = 0 And i >=16 And i <=19
      Rouge = 0 : Vert = 255 : bleu = 0
    EndIf      
    ;Couleur droit
    If xx = 2 And i >=20 And i <=23
      Rouge = 255 : Vert = 0 : bleu = 0
    EndIf  
    ;les coordonnées de vertex
    DM_VertexCoords(*entity, i, x, y, z)
    ;les coordonnées de texture (canal 0)
    DM_VertexTexCoords(*entity, i, 0, u, v)
    DM_VertexTexCoords(*entity, i, 1, u, v)
    ;Couleurs 
    DM_VertexColor(*entity, i, rouge, vert, bleu, 255)    
  Next i
  ;les triangles
  Restore Indice
  For i = 0 To 11
    Read v1.l : Read v2.l : Read v3.l
    DM_VertexTriangle(*entity, i, v1, v2, v3, 0)
  Next i
  ; affecte la brush créee a notre entity
  ;DM_PaintEntity(*entity, *brush, 0)
  ; génératon auto des normales de l'entity créée
  DM_UpdateNormal(*entity)
  ProcedureReturn *entity
EndProcedure
DataSection
Vertex:
; liste des 24 vertex avec leurs coordonnées de textures
;Haut
Data.f -0.5, 0.5, 0.5, 0, 0
Data.f  0.5, 0.5, 0.5, 0, 1
Data.f -0.5, 0.5,-0.5, 1, 0
Data.f  0.5, 0.5,-0.5, 1, 1

;Bas
Data.f -0.5,-0.5, 0.5, 0, 0
Data.f -0.5,-0.5,-0.5, 0, 1
Data.f  0.5,-0.5, 0.5, 1, 0
Data.f  0.5,-0.5,-0.5, 1, 1

;Derrière
Data.f -0.5, 0.5, 0.5, 0, 0
Data.f -0.5,-0.5, 0.5, 0, 1
Data.f  0.5, 0.5, 0.5, 1, 0
Data.f  0.5,-0.5, 0.5, 1, 1

;Devant
Data.f -0.5, 0.5,-0.5, 0, 0
Data.f  0.5, 0.5,-0.5, 0, 1
Data.f -0.5,-0.5,-0.5, 1, 0
Data.f  0.5,-0.5,-0.5, 1, 1

;Gauche
Data.f -0.5, 0.5,-0.5, 0, 0
Data.f -0.5,-0.5,-0.5, 0, 1
Data.f -0.5, 0.5, 0.5, 1, 0
Data.f -0.5,-0.5, 0.5, 1, 1

;Droit
Data.f  0.5, 0.5,-0.5, 0, 0
Data.f  0.5, 0.5, 0.5, 0, 1
Data.f  0.5,-0.5,-0.5, 1, 0
Data.f  0.5,-0.5, 0.5, 1, 1

Indice:
;liste des faces
Data.l  0,  1,  2
Data.l  1,  3,  2
Data.l  4,  5,  6
Data.l  5,  7,  6
Data.l  8,  9, 10
Data.l  9, 11, 10
Data.l 12, 13, 14
Data.l 13, 15, 14
Data.l 16, 17, 18
Data.l 17, 19, 18
Data.l 20, 21, 22
Data.l 21, 23, 22
EndDataSection
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 »

Sinon, pour les pivot et parent + rotations tu as le code dans le pack '16-Pivot+Parent.pb'

cela te permettra de voir ce que je veux dire, surtout l'interraction entre les
angles qui existe maintenant...

sinon voici un petit code pour controler un avion, genre arcade.
Les touche S/X pour accelerer et descelerer, et les touche curseur
pour diriger. Avec l'ancien controle des angle, cela fonctionnais bien,
alors que la faut que je vois le prob...

http://www.dreamotion3d.com/PureBasic/fly.zip

Pour ton code RubisCube, pas d'inquietude, j'ai traité la séparation des entity
mais pas la remise sous parent, ce qui doit occasionner des prob....
Force et sagesse...
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

sympa ton exemple '16-Pivot+Parent.pb' , ça me donne des idées pour le week-end prochain :)
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.
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message par Guimauve »

Je suis tombé sur un site intéressant, c'est en anglais par contre...

http://www.geometrictools.com/

C'est le site d'un livre qui explique comment programmer un moteur 3D

Rendu software, DirectX, OpenGL, la physique, ...

Une partie du moteur OGRE est basé sur les codes de ce site. Si ça peut être utile à quelqu'un.

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 »

très interressant en effet, ce site contient une masse d'information importante,
que ce soit graphique ou physique. Merci...
Force et sagesse...
Répondre