Page 1 sur 2

Calcul D'angle , inclinaison en 3D.

Publié : dim. 06/juin/2004 12:36
par comtois
alors voila , j'ai un objet ( par la suite ,ça sera un véhicule ), et j'aimerais lui faire suivre les contours d'un terrain , pour cela je me suis inspiré d'un code existant ( j'ai mis l'extrait qui est utile dans le source qui suit >dans la procedure Suivicube() qui se trouve dans le fichier Fonctions3D.pbi).
Et je n'y arrive pas , je vais encore chercher ,car je crois qu'il faut que je tienne compte de l'angleX pour calculer les deux autres angles .
Pour me faire une idée de ce qui se passe j'ai ajouté la modification des angles Y et Z avec le pavé numérique ,ça me permet de relever les valeurs d'angles et les inclinaisons calculées , j'essaierai d'en déduire quelque chose :?

Si quelqu'un a une idée sur la meilleure façon de procéder , je suis preneur .

J'ai mis des angles peut-être un peu trop fort dans l'exemple qui suit ?

bref , voila le code , je l'ai découpé en 4 fichiers .

Le programme Principal qui appelle les 3 fichiers suivants :
XIncludeFile "include.pbi"
XIncludeFile "fonctions3D.pbi"
XIncludeFile "initialisation.pbi"
Voici le programme principal ( appelez le comme vous voulez )

Code : Tout sélectionner

;Comtois => 7 Juin 2004
XIncludeFile "include.pbi"
XIncludeFile "fonctions3D.pbi"
XIncludeFile "initialisation.pbi"
Speed=3
Repeat
  If ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Left)
      Joueur\AngleX = WrapValue( Joueur\AngleX + 1 )
      RotateEntity(0,1 , 0, 0 )
    ElseIf KeyboardPushed(#PB_Key_Right)
      Joueur\AngleX = WrapValue( Joueur\AngleX - 1 )
      RotateEntity(0, -1 , 0, 0 )
    EndIf
    If KeyboardPushed(#PB_Key_Up)
      Pas = Speed
    ElseIf KeyboardPushed(#PB_Key_Down)
      Pas = -Speed
    Else
      Pas=0
    EndIf
    If KeyboardPushed(#PB_Key_Pad4)
      Joueur\AngleY + 0.1 : RotateEntity(0,0,0.1,0)
    EndIf
    If KeyboardPushed(#PB_Key_Pad1)
      Joueur\AngleY - 0.1 : RotateEntity(0,0,-0.1,0)
    EndIf  
    If KeyboardPushed(#PB_Key_Pad5)
      Joueur\AngleZ + 0.1 : RotateEntity(0,0,0,0.1)
    EndIf
    If KeyboardPushed(#PB_Key_Pad2)
      Joueur\AngleZ - 0.1 : RotateEntity(0,0,0,-0.1)
    EndIf 
    If KeyboardReleased(#PB_Key_F4) : AfficheAide = 1 - AfficheAide : EndIf
  EndIf  
  dx.f=Cos( Joueur\AngleX * 0.0174533) * Pas
  dz.f=-Sin( Joueur\AngleX * 0.0174533) * Pas
  If EntityX(0) + dx > 0 And EntityX(0) + dx < Matrice\Largeur
    If EntityZ(0) + dz > 0 And EntityZ(0) + dz < Matrice\Profondeur
      MoveEntity( 0 , dx , 0, dz )
    EndIf  
  EndIf
  SuiviCube()
  ;h.f=GetHeight(EntityX(0),EntityZ(0))+3
  ;EntityLocate(0,EntityX(0),h,EntityZ(0))
  LightLocate(0,EntityX(0),600,EntityZ(0))
  GestionCamera()
  RenderWorld()
  StartDrawing(ScreenOutput())
    DrawingMode(1)
    FrontColor(255,255,255)
    Locate(10,10)  
    DrawText("AngleX = "+StrF(Joueur\AngleX,2))
    Locate(10,30)  
    DrawText("AngleY = "+StrF(Joueur\AngleY,2))
    Locate(10,50)  
    DrawText("AngleZ = "+StrF(Joueur\AngleZ,2))
    Locate(10,70)  
    DrawText("Largeur = "+StrF(Largeur,2))
    Locate(10,90)  
    DrawText("Longueur = "+StrF(Longueur,2))
    Locate(10,110)  
    DrawText("MoyenneHauteur = "+StrF(MoyenneHauteur,2))
    Locate(10,130)  
    DrawText("HauteurCentre = "+StrF(HauteurCentre,2))
    Locate(10,150)  
    DrawText("Ay = "+StrF(Ay,2))
    Locate(10,170)  
    DrawText("Az = "+StrF(Az,2))
  StopDrawing()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Voici le fichier "Include.PBI"

Code : Tout sélectionner

;Comtois => 7 Juin 2004
;-Constantes
;/ Ecran
#ScreenWidth = 800 
#ScreenHeight = 600
#ScreenDepth = 32
;/ Mesh
Enumeration
  #MeshMatrice
  #MeshCube
EndEnumeration
;-Structures 
Structure Vecteur 
  x.f 
  y.f 
  Z.f 
EndStructure 
Structure Lumiere 
  Couleur.l 
  x.f 
  y.f 
  Z.f 
EndStructure  
Structure Matrice 
  Largeur.f 
  Profondeur.f 
  NbFacetteX.l      
  NbFacetteZ.l      
  FaceVisible.l      ; si = #True on double les triangles pour voir l'entité des deux côtés 
  NbPointX.l 
  NbPointZ.l 
  Nbtriangle.l 
  TailleFacetteX.f   ; Je ne sais pas si je vais garder cette méthode 
  TailleFacetteZ.f   ; Je ne sais pas si je vais garder cette méthode  
  TailleTextureX.l
  TailleTextureZ.l
  PointIDMemory.l 
  TriangleIDMemory.l 
  TextureIDMemory.l 
  NormaleIDMemory.l 
EndStructure 
Structure Vague 
  decaleX.l 
  decaleZ.l 
  Hauteur.l 
  Angle.l 
  Vitesse.l 
EndStructure  
Structure Camera
   AngleX.l       ; angle de la camera 
   AngleY.l
   VitesseRotation.l
   SensRotation.l ; Sens et Vitesse de Rotation 
   Distance.l     ; distance entre la camera et le perso 
   Hauteur.l      ; hauteur de la camera 
   ToucheHaut.l 
   ToucheBas.l
   ToucheAvance.l
   ToucheRecul.l
   ToucheAngleHaut.l
   ToucheAngleBas.l
   Vue.l
EndStructure
Structure Parametres
   AngleX.f         ;  
   AngleY.f         ; 
   AngleZ.f         ;  
   PosX.l           ;position en x sur la map du robot
   PosZ.l           ;position en z sur la map du robot
   Sens.l           ;Vitesse et Sens de Rotation du robot
   Pas.l            ;Valide déplacement    
EndStructure
;{- Variables
Global Matrice.Matrice 
Global Lumiere.Lumiere 
Global Vague.Vague 
Global Camera.Camera
Global Joueur.Parametres
Global Largeur.f,Longueur.f,MoyenneHauteur.f,HauteurCentre.f
Global Ay.f,Az.f
Camera\Hauteur=69 
Camera\Distance=145 
Camera\AngleY = 0
Camera\VitesseRotation = 2
Camera\ToucheHaut=#PB_Key_Pad6
Camera\ToucheBas=#PB_Key_Pad3
Camera\ToucheAvance=#PB_Key_Pad5 
Camera\ToucheRecul=#PB_Key_Pad2 
Camera\ToucheAngleHaut=#PB_Key_Pad4  
Camera\ToucheAngleBas=#PB_Key_Pad1 
Camera\Vue = 1
;{- Matrice
;/Paramètres de la matrice (à renseigner) 
Matrice\Largeur    = 1000 
Matrice\Profondeur = 1000 
Matrice\NbFacetteX = 50
Matrice\NbFacetteZ = 50 
Matrice\FaceVisible = #True ; #True double les triangles pour rendre visible l'autre face de la matrice 
Matrice\TailleTextureX = 512 
Matrice\TailleTextureZ = 512   
;/Quelques informations complémentaires sur la matrice ( Calculées ) 
If Matrice\FaceVisible 
  Matrice\Nbtriangle = 4 
Else 
  Matrice\Nbtriangle = 2 
EndIf  
Matrice\NbPointX = Matrice\NbFacetteX + 1 
Matrice\NbPointZ = Matrice\NbFacetteZ + 1 
Matrice\TailleFacetteX = Matrice\Largeur / Matrice\NbFacetteX 
Matrice\TailleFacetteZ = Matrice\Profondeur / Matrice\NbFacetteZ 
Matrice\PointIDMemory    = AllocateMemory(12 * Matrice\NbPointX * Matrice\NbPointZ) 
Matrice\TriangleIDMemory = AllocateMemory(12 * Matrice\NbFacetteX * Matrice\NbFacetteZ * Matrice\Nbtriangle) 
Matrice\TextureIDMemory  = AllocateMemory(12 * Matrice\NbPointX * Matrice\NbPointZ)  
Matrice\NormaleIDMemory  = AllocateMemory(12 * Matrice\NbPointX * Matrice\NbPointZ)  
Dim Points.Vecteur(Matrice\NbPointX * Matrice\NbPointZ) ; A supprimer en écrivant directement dans la mémoire normales!!
;}
;}
;{- Declare
Declare calculVecteurNorme(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
Declare produitVectoriel(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
Declare Matrice() 
Declare TextureMatrice(x.l,Z.l,Notexture.l) 
Declare NormalesMatrice() 
Declare vagues() 
Declare.f GetHeight(Xp.f,Zp.f)
Declare HauteurPoint(x.l, Z.l, Hauteur.f) 
Declare HauteurFacette(x.l, Z.l, Hauteur.f) 
Declare.f WrapValue(Angle.f) 
Declare.f NewXValue( x.f , Angle.f , NbUnite.f )
Declare.f NewZValue( Z.f , Angle.f , NbUnite.f )
Declare.f EcartAngle( angle1.f , angle2.f ) 
Declare.f CurveAngle( Actuelle.f , Cible.f , P.f )
Declare.f CurveValue( Actuelle.f , Cible.f , P.f )
Declare GestionCamera()
;}       
Voici le fichier "Fonctions3D.PBI"

Code : Tout sélectionner

;Comtois => 7 Juin 2004
;-Matrice
Procedure calculVecteurNorme(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
  x.f = *v2\x - *v1\x 
  y.f = *v2\y - *v1\y 
  Z.f = *v2\Z - *v1\Z 
  d.f = Sqr(x * x + y * y + Z * Z) 
  *n\x =x / d 
  *n\y =y / d 
  *n\Z =Z / d 
  *n\x =x  
  *n\y =y  
  *n\Z =Z   
EndProcedure 
Procedure produitVectoriel(*v1.Vecteur,*v2.Vecteur,*n.Vecteur) 
  *n\x = *v1\y * *v2\Z - *v1\Z * *v2\y 
  *n\y = *v1\Z * *v2\x - *v1\x * *v2\Z 
  *n\Z = *v1\x * *v2\y - *v1\y * *v2\x 
EndProcedure 
Procedure Matrice() 
  Adresse1 = Matrice\PointIDMemory    ; Adresse Points 
  Adresse2 = Matrice\TextureIDMemory  ; Adresse Texture 
  adresse3 = Matrice\TriangleIDMemory ; Adresse triangles 
  Index = 6 * Matrice\Nbtriangle 
  For b = 0 To Matrice\NbFacetteZ 
    bx = b * Matrice\NbPointX 
    bx1 = bx + Matrice\NbPointX 
    For a = 0 To Matrice\NbFacetteX 
      ;/Points 
      PokeF(Adresse1, (a - Matrice\NbFacetteX / 2) * Matrice\TailleFacetteX) 
      PokeF(Adresse1 + 4, 0) 
      PokeF(Adresse1 + 8, (b - Matrice\NbFacetteZ / 2) * Matrice\TailleFacetteZ) 
      Adresse1 + 12 
      ;/Texture 
      PokeF(Adresse2, a / Matrice\NbFacetteX) 
      PokeF(Adresse2 + 4, b / Matrice\NbFacetteZ) 
      Adresse2 + 8 
      ;/Triangles 
      If b < Matrice\NbFacetteZ And a < Matrice\NbFacetteX 
        P1 = a + bx 
        P2 = P1 + 1 
        P3 = a + bx1 
        P4 = P3 + 1 
        PokeL(adresse3, P4 << 16 + P1)          
        PokeL(adresse3 + 4, P1 << 16 + P2) 
        PokeL(adresse3 + 8, P4 << 16 + P3) 
        If Matrice\FaceVisible 
          PokeL(adresse3 + 12, P2 << 16 + P1) 
          PokeL(adresse3 + 16, P4 << 16 + P3) 
          PokeL(adresse3 + 20, P2 << 16 + P3) 
        EndIf 
        adresse3 + Index 
      EndIf  
    Next 
  Next 
EndProcedure
Procedure NormalesMatrice() 
  Vecteur1.Vecteur 
  Vecteur2.Vecteur 
  
  P1.Vecteur ; Point 1 de la Facette 
  P2.Vecteur ; Point 2 de la Facette  
  P3.Vecteur ; Point 3 de la Facette 
  P4.Vecteur ; Point 4 de la Facette 
  
  Normale1.Vecteur ; Normale Triangle 1 de la Facette Points 1,2,3 
  Normale2.Vecteur ; Normale Triangle 2 de la Facette Points 2,4,3 
  
  adresse = Matrice\PointIDMemory + 4 
  AdrNormale = Matrice\NormaleIDMemory 
  
  For Z = 0 To Matrice\NbFacetteZ - 1 
    zx = Z * Matrice\NbPointX 
    zx1 = zx + Matrice\NbPointX 
    For x = 0 To Matrice\NbFacetteX - 1 
      
      NoPoint1 = x + zx 
      P1\x = x 
      P1\y = PeekF(adresse + NoPoint1 * 12) 
      P1\Z = Z 
      NoPoint2 = NoPoint1 + 1 
      P2\x = x + 1 
      P2\y = PeekF(adresse + NoPoint2 * 12) 
      P2\Z = Z 
      NoPoint3 = x + zx1 
      P3\x = x  
      P3\y = PeekF(adresse + NoPoint3 * 12) 
      P3\Z = Z + 1 
      NoPoint4 = NoPoint3 + 1 
      P4\x = x + 1 
      P4\y = PeekF(adresse + NoPoint4 * 12) 
      P4\Z = Z + 1 
      
      calculVecteurNorme(@P1,@P2,@Vecteur1) 
      calculVecteurNorme(@P1,@P4,@Vecteur2) 
      produitVectoriel(@Vecteur2,@Vecteur1,@Normale1) 
      calculVecteurNorme(@P2,@P4,@Vecteur1) 
      calculVecteurNorme(@P2,@P3,@Vecteur2) 
      produitVectoriel(@Vecteur2,@Vecteur1,@Normale2) 
      ;Voir pour faire ces calculs directement dans la mémoire Normales !
      Points(NoPoint1)\x + Normale1\x 
      Points(NoPoint1)\y + Normale1\y 
      Points(NoPoint1)\Z + Normale1\Z 
      Points(NoPoint2)\x + Normale1\x + Normale2\x 
      Points(NoPoint2)\y + Normale1\y + Normale2\y 
      Points(NoPoint2)\Z + Normale1\Z + Normale2\Z 
      Points(NoPoint3)\x + Normale1\x + Normale2\x 
      Points(NoPoint3)\y + Normale1\y + Normale2\y 
      Points(NoPoint3)\Z + Normale1\Z + Normale2\Z 
      Points(NoPoint4)\x + Normale2\x 
      Points(NoPoint4)\y + Normale2\y 
      Points(NoPoint4)\Z + Normale2\Z 
      
    Next x 
  Next Z  
  
  For Z = 0 To Matrice\NbFacetteZ  
    For x = 0 To Matrice\NbFacetteX  
      Distance.f = Sqr(Points(No)\x * Points(No)\x + Points(No)\y * Points(No)\y + Points(No)\Z * Points(No)\Z) 
      Points(No)\x / Distance 
      Points(No)\y / Distance 
      Points(No)\Z / Distance 
      PokeF(AdrNormale    , Points(No)\x) 
      PokeF(AdrNormale + 4, Points(No)\y) 
      PokeF(AdrNormale + 8, Points(No)\Z) 
      No + 1 
      AdrNormale + 12 
    Next x
  Next Z  
  SetMeshData(0, 3, Matrice\NormaleIDMemory , Matrice\NbPointX * Matrice\NbPointZ) 
EndProcedure 
Procedure vagues() 
  If Animation 
    Vague\Angle = (Vague\Angle + Vague\Vitesse) % 360 
  EndIf 
  adresse = Matrice\PointIDMemory + 4 
  For Z = 0 To Matrice\NbFacetteZ 
    For x = 0 To Matrice\NbFacetteX 
      Sommet.f = Sin(0.0174533 * (Vague\Angle + (x * Vague\decaleX) + (Z * Vague\decaleZ))) * Vague\Hauteur 
      PokeF(adresse, Sommet) 
      adresse + 12 
    Next x 
  Next Z 
  SetMeshData(0, 0, Matrice\PointIDMemory, Matrice\NbPointX * Matrice\NbPointZ) 
EndProcedure 
Procedure.f GetHeight(Xp.f,Zp.f)
  ;Si quelqu'un a plus simple pour connaitre la hauteur d'un point je suis preneur :)
  P1.Vecteur
  P2.Vecteur
  P3.Vecteur
  P4.Vecteur
  ;Determine les points du plan 
  x=Int(Xp/Matrice\TailleFacetteX)
  Z=Int(Zp/Matrice\TailleFacetteZ)  
  adresse = Matrice\PointIDMemory 
  zx = Z * Matrice\NbPointX 

  R1 = x + zx
  R2 = R1 + 1
  R3 = x + zx + Matrice\NbPointX
  R4 = R3 + 1 

  adr = adresse + R1 * 12
  P1\x = PeekF(adr) 
  P1\y = PeekF(adr + 4) 
  P1\Z = PeekF(adr + 8) 

  adr = adresse + R2 * 12
  P2\x=PeekF(adr) 
  P2\y=PeekF(adr + 4) 
  P2\Z=PeekF(adr + 8) 

  adr = adresse + R3 * 12
  P3\x=PeekF(adr) 
  P3\y=PeekF(adr + 4) 
  P3\Z=PeekF(adr + 8) 
  
  adr = adresse + R4 * 12
  P4\x=PeekF(adr) 
  P4\y=PeekF(adr + 4) 
  P4\Z=PeekF(adr + 8) 

  Xw.f=(Xp-Matrice\Largeur/2)-P1\x-(Matrice\TailleFacetteX/2)
  Zw.f=(Zp-Matrice\Profondeur/2)-P1\Z-(Matrice\TailleFacetteZ/2)  
  If Zw-Xw<0
    a.f=(Xp-Matrice\Largeur/2)-P1\x
    d.f=P2\x-P1\x
    g.f=P4\x-P1\x
    e.f=P2\y-P1\y
    h.f=P4\y-P1\y
    c.f=(Zp-Matrice\Profondeur/2)-P1\Z
    f.f=P2\Z-P1\Z
    i.f=P4\Z-P1\Z
    y.f = (((c*e*g)-(c*d*h)+(a*f*h)-(a*e*i))/(f*g-d*i))+P1\y
  Else
    a.f=(Xp-Matrice\Largeur/2)-P1\x
    d.f=P3\x-P1\x
    g.f=P4\x-P1\x
    e.f=P3\y-P1\y
    h.f=P4\y-P1\y
    c.f=(Zp-Matrice\Profondeur/2)-P1\Z
    f.f=P3\Z-P1\Z
    i.f=P4\Z-P1\Z
    y.f = (((c*e*g)-(c*d*h)+(a*f*h)-(a*e*i))/(f*g-d*i))+P1\y
  EndIf  
  ProcedureReturn y
EndProcedure
Procedure HauteurPoint(x.l, Z.l, Hauteur.f) 
  ;élève un point x,z de la matrice à la hauteur "Hauteur" 
  If x > -1 And x <= Matrice\NbFacetteX And Z > -1 And Z <= Matrice\NbFacetteZ And Matrice\PointIDMemory 
    adresse = Matrice\PointIDMemory + 4 
    adresse = adresse + (x + (Z * Matrice\NbPointX )) * 12 
    PokeF(adresse, Hauteur) 
    SetMeshData(0, 0, Matrice\PointIDMemory, Matrice\NbPointX * Matrice\NbPointZ) 
    ProcedureReturn #True 
  Else 
    ProcedureReturn #False 
  EndIf  
EndProcedure 
Procedure HauteurFacette(x.l, Z.l, Hauteur.f) 
  ;élève une facette de la matrice
  If x > 0 And x <= Matrice\NbFacetteX And Z > 0 And Z <= Matrice\NbFacetteZ And Matrice\PointIDMemory
    adresse = Matrice\PointIDMemory + 4 
    adresse + (x + (Z * Matrice\NbPointX )) * 12 
    PokeF(adresse, Hauteur) 
    adresse - 12 
    PokeF(adresse, Hauteur) 
    adresse  - (Matrice\NbFacetteX + 1) * 12 
    PokeF(adresse, Hauteur) 
    adresse + 12 
    PokeF(adresse, Hauteur) 
    SetMeshData(0, 0, Matrice\PointIDMemory, Matrice\NbPointX * Matrice\NbPointZ) 
    ProcedureReturn #True 
  Else 
    ProcedureReturn #False 
  EndIf  
EndProcedure 
;-3D
Procedure.f WrapValue(Angle.f) 
   Angle/360 
   Angle-Int(Angle) 
   If Angle<0 
      ProcedureReturn (Angle+1)*360 
   Else 
      ProcedureReturn Angle*360 
    EndIf 
  EndProcedure 
Procedure.f NewXValue( x.f , Angle.f , NbUnite.f )
   ;à utiliser conjointement avec NewZvalue pour calculer une position de <NbUnite> dans la direction <angle> 
   Valeur.f = x + Cos(Angle * 0.0174533) * NbUnite
   ProcedureReturn Valeur
EndProcedure
Procedure.f NewZValue( Z.f , Angle.f , NbUnite.f )
   ;à utiliser conjointement avec NewXvalue pour calculer une position de <NbUnite> dans la direction <angle> 
   Valeur.f = Z - Sin(Angle * 0.0174533) * NbUnite
   ProcedureReturn Valeur
EndProcedure
Procedure.f EcartAngle( angle1.f , angle2.f ) 
   Delta.f=angle2-angle1 
   If Delta>180 
      ProcedureReturn Delta-360 
   ElseIf Delta<=-180 
      ProcedureReturn Delta+360 
   Else 
      ProcedureReturn Delta 
   EndIf    
EndProcedure  
Procedure.f CurveAngle( Actuelle.f , Cible.f , P.f )
   ;Calcule un angle progressif allant de la valeur actuelle à la valeur cible
   Delta.f = EcartAngle( Actuelle , Cible ) 
   If P > 1000 : P = 1000 : EndIf
   Valeur.f = Actuelle + ( Delta * P / 1000 )
   ProcedureReturn WrapValue( Valeur ) 
EndProcedure
Procedure.f CurveValue( Actuelle.f , Cible.f , P.f )
   ;Calcule une valeur progressive allant de la valeur actuelle à la valeur cible
   Delta.f = Cible - Actuelle
   If P > 1000 : P = 1000 : EndIf
   Valeur.f = Actuelle + Round(( Delta * P / 1000 ),1)
   ProcedureReturn Valeur
EndProcedure
Procedure GestionCamera()
  PosXCamera.f = NewXValue(EntityX(0) , Joueur\AngleX + 180 , Camera\Distance)
  PosZCamera.f = NewZValue(EntityZ(0) , Joueur\AngleX + 180 , Camera\Distance) 
  PosYCamera.f = EntityY(0) + Camera\Hauteur
  CameraLocate(0 , PosXCamera , PosYCamera , PosZCamera)
  CameraLookAt(0 , EntityX(0) , EntityY(0) + Camera\AngleY , EntityZ(0))      
EndProcedure
Procedure SuiviCube()
  ;Calcule les coordonnées des 4 coins du cube
  ;Les entitys permettent de vérifier que le calcul des coins est correct
  ;Distance du centre à chaque coin ( l'objet est carré )
  DistanceCoin.f=Sqr(32*32+32*32)/2
  ;Coin Avant Gauche
  AngleCoin.f=WrapValue(Joueur\AngleX+45)
  AvantGaucheX.f=NewXValue(EntityX(0),AngleCoin,DistanceCoin) 
  AvantGaucheZ.f=NewZValue(EntityZ(0),AngleCoin,DistanceCoin)
  EntityLocate(2,AvantGaucheX,EntityY(0),AvantGaucheZ)
  ;Coin Avant Droit
  AngleCoin=WrapValue(Joueur\AngleX-45)
  AvantDroitX.f=NewXValue(EntityX(0),AngleCoin,DistanceCoin)
  AvantDroitZ.f=NewZValue(EntityZ(0),AngleCoin,DistanceCoin)
  EntityLocate(3,AvantDroitX,EntityY(0),AvantDroitZ)
  ;Coin Arrière Gauche
  AngleCoin=WrapValue(Joueur\AngleX+135)
  ArriereGaucheX.f=NewXValue(EntityX(0),AngleCoin,DistanceCoin)
  ArriereGaucheZ.f=NewZValue(EntityZ(0),AngleCoin,DistanceCoin)
  EntityLocate(4,ArriereGaucheX,EntityY(0),ArriereGaucheZ)
  ;Coin Arrière Droit
  AngleCoin=WrapValue(Joueur\AngleX-135)
  ArriereDroitX.f=NewXValue(EntityX(0),AngleCoin,DistanceCoin)
  ArriereDroitZ.f=NewZValue(EntityZ(0),AngleCoin,DistanceCoin)
  EntityLocate(5,ArriereDroitX,EntityY(0),ArriereDroitZ)
  
  ;Hauteur des coins 
  AvantGaucheH.f=GetHeight(AvantGaucheX,AvantGaucheZ)
  AvantDroitH.f=GetHeight(AvantDroitX,AvantDroitZ)
  ArriereGaucheH.f=GetHeight(ArriereGaucheX,ArriereGaucheZ)
  ArriereDroitH.f=GetHeight(ArriereDroitX,ArriereDroitZ)
  ;écarts Largeur / Longueur devrait permettre de calculer l'angle d'inclinaison !
  Largeur=((AvantGaucheH-AvantDroitH)+(ArriereGaucheH-ArriereDroitH))/2.0
  Longueur=((AvantGaucheH-ArriereGaucheH)+(AvantDroitH-ArriereDroitH))/2.0
  
  ;Corrige la hauteur ( 3 c'est la moitié de l'épaisseur de l'objet)
  HauteurCentre.f=GetHeight(EntityX(0),EntityZ(0)) + 3
  MoyenneHauteur.f=(AvantGaucheH+AvantDroitH+ArriereGaucheH+ArriereDroitH)/4.0
  If MoyenneHauteur>HauteurCentre 
    h.f=MoyenneHauteur
  Else
    h.f=HauteurCentre
  EndIf
  EntityLocate(0,EntityX(0),h,EntityZ(0))
  ;Voir comment Joueur\AngleX doit intervenir dans ces calculs ?
  Ay1.f=ASin(Largeur/Sqr(32*32+Largeur*Largeur))*57.29578
  Az1.f=ASin(Longueur/Sqr(32*32+Longueur*Longueur))*57.29578
  Ay=EcartAngle(Joueur\AngleY,Ay1)
  Az=EcartAngle(Joueur\AngleZ,Az1)
  RotateEntity(0,0,Ay,Az)
  Joueur\AngleY=Ay1
  Joueur\AngleZ=Az1  
EndProcedure  


Et enfin le dernier fichier "Initialisation.PBI"

Code : Tout sélectionner

;Comtois => 7 Juin 2004
;{- Initialisation
If InitEngine3D() = 0
   MessageRequester( "Erreur" , "Impossible d'initialiser la 3D , vérifiez la présence de engine3D.dll" , 0 )
   End
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or InitSound() = 0
   MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 )
   End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "Démo PlateForme" ) = 0
   MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
   End
EndIf
;}
;{- Dessine la matrice
Matrice()
For a=1 To Matrice\NbFacetteX 
  HauteurFacette(a,1,40)
  HauteurFacette(a,Matrice\NbFacetteZ,40)
  If a>4 And a<=Matrice\NbFacetteX-4
    HauteurFacette(a,5,-40)
    HauteurFacette(a,Matrice\NbFacetteZ-4,-40)
  EndIf  
Next a  
For b=1 To Matrice\NbFacetteZ 
  HauteurFacette(1,b,40)
  HauteurFacette(Matrice\NbFacetteX,b,40)
  If b>4 And b<=Matrice\NbFacetteZ-4
    HauteurFacette(5,b,-40)
    HauteurFacette(Matrice\NbFacetteX-4,b,-40)
  EndIf  
Next b 
For b=Matrice\NbFacetteZ/2 - 10 To Matrice\NbFacetteZ/2 + 11
  For a=Matrice\NbFacetteX/2 - 10 To Matrice\NbFacetteX/2 + 11
    Cond1 = a>=Matrice\NbFacetteX/2 - 7 And a<=Matrice\NbFacetteX/2 - 1
    Cond2 = a>=Matrice\NbFacetteX/2 + 3 And a<=Matrice\NbFacetteX/2 + 9 
    Cond3 = b>=Matrice\NbFacetteZ/2 - 7 And b<=Matrice\NbFacetteZ/2 - 1
    cond4 = b>=Matrice\NbFacetteZ/2 + 3 And b<=Matrice\NbFacetteZ/2 + 9 
    If (Cond1 Or Cond2) And (Cond3 Or cond4)
      HauteurFacette(a,b,40)
    Else
      HauteurFacette(a,b,80) 
    EndIf  
  Next a
Next b
NormalesMatrice()
;}
;{- Mesh
;/Mesh 
CreateMesh(#MeshMatrice) 
SetMeshData(#MeshMatrice, 0, Matrice\PointIDMemory   , Matrice\NbPointX * Matrice\NbPointZ) 
SetMeshData(#MeshMatrice, 1, Matrice\TriangleIDMemory, Matrice\NbFacetteX * Matrice\NbFacetteZ * Matrice\Nbtriangle) 
SetMeshData(#MeshMatrice, 2, Matrice\TextureIDMemory , Matrice\NbPointX * Matrice\NbPointZ)  
SetMeshData(#MeshMatrice, 3, Matrice\NormaleIDMemory , Matrice\NbPointX * Matrice\NbPointZ)  
CreateMesh(#MeshCube) ;Cube 
SetMeshData(#MeshCube,#PB_Mesh_Vertices     , ?CubePoints       , 16)
SetMeshData(#MeshCube,#PB_Mesh_Triangles    , ?CubeTriangles    , 12)
SetMeshData(#MeshCube,#PB_Mesh_UVCoordinates, ?CubeTextures     , 16)
SetMeshData(#MeshCube,#PB_Mesh_Normals      , ?CubeNormales     , 16)
;}
;{- Textures
CreateTexture(1,128, 128) 
StartDrawing(TextureOutput(1))
Box(0,0,TextureWidth(1),TextureHeight(1),RGB(200,100,220))
StopDrawing()  
CreateTexture(2,128, 128) 
StartDrawing(TextureOutput(2))
Box(0,0,TextureWidth(2),TextureHeight(2),RGB(100,200,130))
StopDrawing() 
CreateTexture(3,128, 128) 
StartDrawing(TextureOutput(3))
Box(0,0,TextureWidth(2),TextureHeight(2),RGB(255,100,100))
StopDrawing()  
CreateTexture(0, Matrice\TailleTextureX, Matrice\TailleTextureZ) 
StartDrawing(TextureOutput(0)) 
Box(0,0,TextureWidth(0)/2,TextureHeight(0)/2,RGB(0,200,0))
Box(TextureWidth(0)/2,0,TextureWidth(0)/2,TextureHeight(0)/2,RGB(0,0,200))
Box(0,TextureHeight(0)/2,TextureWidth(0)/2,TextureHeight(0)/2,RGB(200,0,0))
Box(TextureWidth(0)/2,TextureHeight(0)/2,TextureWidth(0)/2,TextureHeight(0)/2,RGB(200,200,0))
While bb.f<=TextureHeight(0)
  While aa.f<=TextureWidth(0)
    LineXY(aa,0,aa,TextureHeight(0),RGB(255,255,200))
    LineXY(0,bb,TextureWidth(0),bb,RGB(255,255,200))
    aa + Matrice\TailleTextureX / Matrice\NbFacetteX
  Wend
  bb + Matrice\TailleTextureZ / Matrice\NbFacetteZ
  aa = 0
Wend 
StopDrawing()  
;}
;{- Material
For a = 0 To 3
  CreateMaterial(a, TextureID( a))
Next a
MaterialShadingMode(0, #PB_Material_Gouraud) 

MaterialAmbientColor(0, RGB(225,125,125)) 
MaterialDiffuseColor(0, RGB(255,255,255)) 
MaterialSpecularColor(0,RGB(255,255,255)) 
;}
;{- Entity
;Joueur
CreateEntity(0,MeshID(#MeshCube),MaterialID(1))
ScaleEntity(0,32,6,32)
EntityLocate(0,500,3,500)
Joueur\AngleX = 0
RotateEntity(0,Joueur\AngleX,0,0)
;Sol
CreateEntity(1,MeshID(#MeshMatrice),MaterialID(0))
EntityLocate(1,Matrice\Largeur/2,0,Matrice\Profondeur/2)
;visualise les coins du cube
tr=6
CreateEntity(2,MeshID(#MeshCube),MaterialID(2))
ScaleEntity(2,tr,tr,tr)
CreateEntity(3,MeshID(#MeshCube),MaterialID(2))
ScaleEntity(3,tr,tr,tr)
CreateEntity(4,MeshID(#MeshCube),MaterialID(3))
ScaleEntity(4,tr,tr,tr)
CreateEntity(5,MeshID(#MeshCube),MaterialID(3))
ScaleEntity(5,tr,tr,tr)
;}
;{- Camera
CreateCamera(0, 0, 0 , 100 , 100)
CameraLocate(0,0,200,0)
;}
;{- Light
AmbientColor(RGB(160,160,160)) 
CreateLight(0,RGB(155,155,155))
LightLocate(0 , Matrice\Largeur,600,Matrice\Profondeur/2)
;}   
;{- Datas Cube
DataSection
;/Cube
CubePoints:
Data.f -0.5,-0.5,-0.5
Data.f -0.5,-0.5,0.5
Data.f 0.5,-0.5,0.5
Data.f 0.5,-0.5,-0.5

Data.f -0.5,0.5,-0.5
Data.f -0.5,0.5,0.5
Data.f 0.5,0.5,0.5
Data.f 0.5,0.5,-0.5

Data.f -0.5,-0.5,-0.5
Data.f -0.5,-0.5,0.5
Data.f 0.5,-0.5,0.5
Data.f 0.5,-0.5,-0.5

Data.f -0.5,0.5,-0.5
Data.f -0.5,0.5,0.5
Data.f 0.5,0.5,0.5
Data.f 0.5,0.5,-0.5
CubeNormales:
Data.f -5,0,-5
Data.f -5,0,5
Data.f 5,0,5
Data.f 5,0,-5
Data.f -5,0,-5
Data.f -5,0,5
Data.f 5,0,5
Data.f 5,0,-5

Data.f 0,-10,0
Data.f 0,-10,0
Data.f 0,-10,0
Data.f 0,-10,0
Data.f 0,10,0
Data.f 0,10,0
Data.f 0,10,0
Data.f 0,10,0

CubeTriangles:
Data.w 0,4,7
Data.w 0,7,3
Data.w 1,5,4
Data.w 1,4,0
Data.w 2,6,5
Data.w 2,5,1
Data.w 3,7,6
Data.w 3,6,2
Data.w 9,8,11
Data.w 9,11,10
Data.w 12,13,14
Data.w 12,14,15
CubeTextures:
;original
Data.f 0,1
Data.f 1,1
Data.f 0,1
Data.f 1,1

Data.f 0,0
Data.f 1,0
Data.f 0,0
Data.f 1,0

Data.f 0,0
Data.f 1,0
Data.f 1,1
Data.f 0,1

Data.f 0,0
Data.f 1,0
Data.f 1,1
Data.f 0,1
EndDataSection
;}

Publié : dim. 06/juin/2004 12:50
par comtois
Pour s'affranchir des erreurs éventuelles que j'aurais pu commettre sur le calcul de la hauteur d'un point ( GetHeight() de mon cru )
Il est possible de reconduire l'exemple en utilisant cette fois ci un terrain,on peut ainsi espérer que le calcul de la hauteur sera plus fiable que le mien :)
Bien que je n'ai pas constaté d"erreur , ça pourrait être intéressant de faire des essais avec deux configurations différentes , un terrain et ma matrice.

Je vais voir pour adapter l'exemple du terrain qui se trouve dans Examples/Source en y ajoutant le cube .

ça fera un listing plus court déjà :)

Publié : dim. 06/juin/2004 13:37
par Backup
heu !!

esce normale que dans l'exemple donne la voiture ne s'incline pas du tout !
sauf si on utilise les touches du pave numerique ! ????

j'avais fait un truc comme ça en dark (+simple le dark pour ça !!)

ou je relevai la hauteur du terrain sous chaque roue !! et la voiture s'inclinait naturelement !
:)

Publié : dim. 06/juin/2004 13:40
par comtois
oui c'est normal parce que mes calculs d'angles sont mauvais et que ça donne n'importe quoi :? donc je ne les ai pas intégré .

Si tu pouvais m'expliquer comment tu fais , ça m'intéresse beaucoup .

Pour relever la hauteur du terrain sous chaque roue , ça c'est fait , il reste à calculer l'angle !

Et j'ai mis des touches pour modifier les angles pour me faire une idée des valeurs qu'il faudrait que j'obtienne .

Publié : dim. 06/juin/2004 16:10
par Backup
ouula ! y faut que je recherche ça !!
:D

Publié : dim. 06/juin/2004 16:14
par comtois
j'ai fait un petit dessin pour m'aider

Image

le cube est présenté en vue de face , ou arriere , peu importe
on voit les roues gauche et droite ( donc la largeur )

si la roue gauche doit se trouver à 200 et la roue droite à 100 de haut
ça fait un écart de 200-100=100 entre les roues

ça donne le triangle rectangle que l'on voit sur la figure
j'ai besoin de connaitre l'angle d'inclinaison A .
Je connais le côté opposé c'est l"écart des hauteurs soit 100
Je connais l'hypoténuse , c'est la largeur du cube .
L'angle est donc A=Asin(100/Largeur)
et dans le sens de la longueur , l'angle sera A=Asin(écartdeshauteursdanslesensdelalongueur/longueurducube)

Alors déjà , est-ce que ce raisonnement vous parait juste ?

Avec ça je devrais être heureux ? eh ben non .
Parce qu'il n'est pas possible de donner un angle en absolu avec purebasic donc ça oblige de faire des calculs supplémentaires ,de mémoriser l'angle dans lequel on se trouve ,calculer l'écart etc...
Mais pire , mes calculs se font par rapport aux repères 3D de la matrice , mais si j'ai bien compris ( si je me plante , merci de me détromper ,c'est pour ça que je poste , je suis perdu :? ) ,le rotateEntity() se fait par rapport aux repères de l'entity , il faut donc passer de l'un à l'autre ?

Je mesure un angle dans un système , et je dois l'appliquer dans un autre système :?

Euh , c'est plus très clair pour moi , si quelqu'un peut m'aiguiller ... ou me donner la solution :)

Publié : dim. 06/juin/2004 16:17
par comtois
Dobro a écrit :ouula ! y faut que je recherche ça !!
:D
Ah oui , ça m'aiderait bien :)

Et puis je me sens moins seul sur ce coup là , je me suis déjà assez embêté pour le calcul des hauteurs :lol:

Publié : dim. 06/juin/2004 20:10
par comtois
Voila une version avec le code "Terrain" qui se trouve dans Examples/Sources , légèrement modifié pour y faire apparaitre le cube et le commander avec les touches de la même façon que dans le code ci-dessus.

Le but du jeu , c'est de suivre les contours du terrain avec le cube :)

il suffit de copier ce code dans le répertoire Examples/Sources pour tester.

Code : Tout sélectionner

#CameraSpeed = 5
#MeshCube = 0
Speed=3
Structure Camera
  AngleX.f      
  Distance.f      
  Hauteur.f    
EndStructure
Structure Parametres
  AngleX.f           
  AngleY.f          
  AngleZ.f         
  Pas.l            
EndStructure
Global Joueur.Parametres
Global Camera.Camera
Camera\Hauteur=70 
Camera\Distance=145 

Declare GestionCamera()
Declare.f WrapValue(Angle.f) 

IncludeFile "Screen3DRequester.pb"

DefType.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  Add3DArchive("Data\"          , #PB_3DArchive_FileSystem)
  Add3DArchive("Data\Skybox.zip", #PB_3DArchive_Zip)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    ;-Mesh
    CreateMesh(#MeshCube) ;Cube 
    SetMeshData(#MeshCube,#PB_Mesh_Vertices     , ?CubePoints       , 16)
    SetMeshData(#MeshCube,#PB_Mesh_Triangles    , ?CubeTriangles    , 12)
    SetMeshData(#MeshCube,#PB_Mesh_UVCoordinates, ?CubeTextures     , 16)
    SetMeshData(#MeshCube,#PB_Mesh_Normals      , ?CubeNormales     , 16)
    ;- Textures
    CreateTexture(2,128, 128) 
    StartDrawing(TextureOutput(2))
    Box(0,0,TextureWidth(2),TextureHeight(2),RGB(20,100,220))
    StopDrawing()  
    CreateTexture(3,128, 128) 
    StartDrawing(TextureOutput(3))
    Box(0,0,TextureWidth(3),TextureHeight(3),RGB(255,100,100))
    StopDrawing()  
    ;- Material
    CreateMaterial  (0, LoadTexture(0, "Terrain_Texture.jpg"))
    AddMaterialLayer(0, LoadTexture(1, "Terrain_Detail.jpg"), 1)
    CreateMaterial(2, TextureID( 2))
    CreateMaterial(3, TextureID( 3))  
    ;-Terrain 
    CreateTerrain("Terrain.png", MaterialID(0), 4, 0.6, 4, 4)
    ;- Entity - faire createterrain avant sinon l'entity n'apparait !!!
    ;Joueur
    CreateEntity(10,MeshID(#MeshCube),MaterialID(2))
    ScaleEntity(10,32,6,32)
    EntityLocate(10, 128, 25, 128)
    Joueur\AngleX = 0
    ;-Camera
    CreateCamera(0, 0, 0, 100, 100)
    CameraLocate(0, 128, 25, 128)
    ;-Ciel
    SkyDome("Clouds.jpg",10)
    ;-Lumière
    AmbientColor(RGB(155,155,155))
    CreateLight(0,RGB(255,255,255),128, 400, 128)
    Repeat
      Screen3DEvents()
            
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Left)
          Joueur\AngleX = WrapValue( Joueur\AngleX + 1 )
          RotateEntity(10,1 , 0, 0 )
        ElseIf KeyboardPushed(#PB_Key_Right)
          Joueur\AngleX = WrapValue( Joueur\AngleX - 1 )
          RotateEntity(10, -1 , 0, 0 )
        EndIf
        If KeyboardPushed(#PB_Key_Up)
          Pas = #CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          Pas = -#CameraSpeed
        Else
          Pas=0
        EndIf
      EndIf
     
      Height.f = TerrainHeight(EntityX(10), EntityZ(10))
      dx.f=Cos( Joueur\AngleX * 0.0174533) * Pas
      dz.f=-Sin( Joueur\AngleX * 0.0174533) * Pas
      MoveEntity( 10 , dx , 0, dz )
      EntityLocate(10,EntityX(10),Height+3,EntityZ(10))
      GestionCamera()
      RenderWorld()
      Screen3DStats()
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End
;-Procedures
Procedure.f WrapValue(Angle.f) 
  Angle/360 
  Angle-Int(Angle) 
  If Angle<0 
    ProcedureReturn (Angle+1)*360 
  Else 
    ProcedureReturn Angle*360 
  EndIf 
EndProcedure 
Procedure.f NewXValue( x.f , Angle.f , NbUnite.f )
  ;à utiliser conjointement avec NewZvalue pour calculer une position de <NbUnite> dans la direction <angle> 
  Valeur.f = x + Cos(Angle * 0.0174533) * NbUnite
  ProcedureReturn Valeur
EndProcedure
Procedure.f NewZValue( Z.f , Angle.f , NbUnite.f )
  ;à utiliser conjointement avec NewXvalue pour calculer une position de <NbUnite> dans la direction <angle> 
  Valeur.f = Z - Sin(Angle * 0.0174533) * NbUnite
  ProcedureReturn Valeur
EndProcedure
Procedure GestionCamera()
  PosXCamera.f = NewXValue(EntityX(10) , Joueur\AngleX + 180 , Camera\Distance)
  PosZCamera.f = NewZValue(EntityZ(10) , Joueur\AngleX + 180 , Camera\Distance) 
  PosYCamera.f = EntityY(10) + Camera\Hauteur
  CameraLocate(0 , PosXCamera , PosYCamera , PosZCamera)
  CameraLookAt(0 , EntityX(10) , EntityY(10) , EntityZ(10))      
EndProcedure
;-Datas
DataSection
CubePoints:
Data.f -0.5,-0.5,-0.5
Data.f -0.5,-0.5,0.5
Data.f 0.5,-0.5,0.5
Data.f 0.5,-0.5,-0.5
Data.f -0.5,0.5,-0.5
Data.f -0.5,0.5,0.5
Data.f 0.5,0.5,0.5
Data.f 0.5,0.5,-0.5
Data.f -0.5,-0.5,-0.5
Data.f -0.5,-0.5,0.5
Data.f 0.5,-0.5,0.5
Data.f 0.5,-0.5,-0.5
Data.f -0.5,0.5,-0.5
Data.f -0.5,0.5,0.5
Data.f 0.5,0.5,0.5
Data.f 0.5,0.5,-0.5
CubeNormales:
Data.f -5,0,-5
Data.f -5,0,5
Data.f 5,0,5
Data.f 5,0,-5
Data.f -5,0,-5
Data.f -5,0,5
Data.f 5,0,5
Data.f 5,0,-5
Data.f 0,-10,0
Data.f 0,-10,0
Data.f 0,-10,0
Data.f 0,-10,0
Data.f 0,10,0
Data.f 0,10,0
Data.f 0,10,0
Data.f 0,10,0
CubeTriangles:
Data.w 0,4,7
Data.w 0,7,3
Data.w 1,5,4
Data.w 1,4,0
Data.w 2,6,5
Data.w 2,5,1
Data.w 3,7,6
Data.w 3,6,2
Data.w 9,8,11
Data.w 9,11,10
Data.w 12,13,14
Data.w 12,14,15
CubeTextures:
;original
Data.f 0,1
Data.f 1,1
Data.f 0,1
Data.f 1,1
Data.f 0,0
Data.f 1,0
Data.f 0,0
Data.f 1,0
Data.f 0,0
Data.f 1,0
Data.f 1,1
Data.f 0,1
Data.f 0,0
Data.f 1,0
Data.f 1,1
Data.f 0,1
EndDataSection

Publié : dim. 06/juin/2004 20:49
par Backup
en fait j'avais fait une fonction pour explorer un monde chargé !!!! !!!!!!
si le parametre "voiture est mis a 1
la camera penchai dans les pentes !!!

mais tu sais en Dark il y a plein de commande pour la 3D
(j'ai completement oublié lz Dark) !! :D

Code : Tout sélectionner

function explorateur(voiture,posx,posy,posz,vuetete)



if func=1: rem si la fonction a deja ete lancee alors
   goto suite :rem ca sert a rien de refabriquer l'explorateur !
endif
func=1
rem fabrique l'explorateur
make object cube 8888,60
set object 8888,1,1,1,1,1,1
set object collision to boxes 8888
set object collision on 8888
rem pose l'explorateur au bon endroit !!
xposcam=posx
yposcam=posy
zposcam=posz
rem on continue !!
suite:
rem positionne la camera et l'objet



altitude=get ground height(1,xposcam,zposcam) :altitude2=altitude
position camera xposcam,yposcam+altitude,zposcam
position object 8888,xposcam,yposcam,zposcam

rem debut de la boucle



rem affiche les coordonees de la camera (seulement pour determiner le depart de l'explo)
rem set cursor 0,10
rem print xposcam;" ";yposcam;" ";zposcam





if vuetete=1
   rem recupere les valeur de la boule de souris pour tourner la tete
   xcam=wrapvalue(xcam+mousemovey())
   ycam=wrapvalue(ycam+mousemovex())
   zcam=wrapvalue(zcam+mousemovez())
endif

remstart
   la variable avancecam et reculecam servent a determiner si la collision a lieu en
   marche avant ou arriere de cette facon on replace la camera et l'objet au bon endroit
   La variable "touche" dit si il y a collision !!
   l'explorateur sous entend camera + objet 8888 qui sert au test de collision !!

remend

rem test le clavier pour la rotation de l'explorateur
   if leftkey()
      ycam=ycam-5
   endif

   if rightkey()
      ycam=ycam+5
   endif
rem et tourne la camera en fonction
rem   rotate camera wrapvalue(xcam),wrapvalue(ycam),wrapvalue(zcam)
rem   set object to camera orientation 8888

rem test leclavier pour l'avance ou le recul de l'explorateur
   if upkey() and touche=0
      move camera 10
      avancecam=1:reculecam=0
      altitude2=altitude
   endif

   if touche=1 and avancecam=1
      move camera 0
   rem   position camera xposcam,yposcam+altitude,zposcam-10
      xposcam=camera position x()
      yposcam=camera position y()
      zposcam=camera position z()
      position object 8888,xposcam,yposcam+altitude,zposcam-10
      touche =0
      avancecam=0
   endif

if downkey() and touche= 0
      move camera -10
      reculecam=1:avancecam=0
      altitude2=altitude
   endif

   if touche=1 and reculecam=1
      move camera 0
rem      position camera
      xposcam=camera position x()
      yposcam=camera position y()
      zposcam=camera position z()
      position object 8888,xposcam,yposcam+altitude,zposcam+10
      touche =0
      reculecam=0
   endif


rem recupere les nouvelles coordonees de la camera
xposcam=camera position x()
zposcam=camera position z()

rem recupere l'altitude de la matrice a l'endroit de la camera
   altitude=get ground height(1,xposcam,zposcam): rem num de matric,x,y
   xagauche=newxvalue(xposcam,-90,1)
   xadroite=newxvalue(xposcam,90,1)

   altitudegauche=get ground height(1,xagauche,zposcam)
   altitudedroite=get ground height(1,xadroite,zposcam)


rem xcam2= camera angle x()

rem ici si actif penche la camera en fonction du sol (pour une voiture par ex)
rem ************* marche avant ************
if voiture=1

   difference=(altitude-altitude2)
   vitesseroulis=3
   rem si le sol monte !!!
   if int(difference)>=4 and avancecam=1
      xcam2#=camera angle x()
      xcam3=curveangle(-30,xcam2#,vitesseroulis)
   endif

   if int(difference)=3 and avancecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(-20,xcam2#,vitesseroulis)
   endif
   if int(difference)=2 and avancecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(-15,xcam2#,vitesseroulis)
   endif
   if int(difference)=1 and avancecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(-4,xcam2#,vitesseroulis)
   endif
   rem si le sol descend !!
   if int(difference)<=-4 and avancecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(30,xcam2#,vitesseroulis)
   endif

   if int(difference)=-3 and avancecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(20,xcam2#,vitesseroulis)
   endif
   if int(difference)=-2 and avancecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(15,xcam2#,vitesseroulis)
   endif
   if int(difference)=-1 and avancecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(4,xcam2#,vitesseroulis)
   endif
   rem si le sol est plat
   if int(difference)=0
      xcam2#= camera angle x()
      xcam3=curveangle(0,xcam2#,vitesseroulis)
   endif
   rem ************* Marche arriere ************

   rem si le sol monte !!!
   if int(difference)>=4 and reculecam=1
      xcam2#=camera angle x()
      xcam3=curveangle(30,xcam2#,vitesseroulis)
   endif

   if int(difference)=3 and reculecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(20,xcam2#,vitesseroulis)
   endif
   if int(difference)=2 and reculecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(15,xcam2#,vitesseroulis)
   endif
   if int(difference)=1 and reculecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(4,xcam2#,vitesseroulis)
   endif
   rem si le sol descend !!
   if int(difference)<=-4 and reculecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(-30,xcam2#,vitesseroulis)
   endif

   if int(difference)=-3 and reculecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(-20,xcam2#,vitesseroulis)
   endif
   if int(difference)=-2 and reculecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(-15,xcam2#,vitesseroulis)
   endif
   if int(difference)=-1 and reculecam=1
      xcam2#= camera angle x()
      xcam3=curveangle(-4,xcam2#,vitesseroulis)
   endif

   xcam=xcam3
endif
rem *****************************************************
set cursor 0,20
print "xagauche= ";xagauche;" xadroite= ";xadroite;"altitude";altitude;" xcam3:";xcam3
rem et repositionne la camera en fonction
   position camera xposcam,yposcam+altitude,zposcam
   rotate camera wrapvalue(xcam),wrapvalue(ycam),wrapvalue(zcam)
   position object 8888,xposcam,yposcam+altitude,zposcam
rem affiche le resultat a l'ecran 0
endfunction

:D[/code]

Publié : lun. 07/juin/2004 8:43
par comtois
Je viens de mettre à Jour le code , il y a très peu de modifs mais comme je ne sais plus lesquelles , j'ai tout remis à jour en ajoutant la date au début de chaque source .

Dans cette version , le calcul des angles d'inclinaison est inclu.
ça ne fonctionne pas encore , seulement si l'angleX est un angle droit , soit 0° ,90°,180°,270°. Sinon ça déconne à fond. Je suppose qu'il va falloir que je tienne compte de cet angle dans les calculs :)
mais comment ? :?

Publié : lun. 07/juin/2004 13:24
par Backup
tout ça c'est a cause de cette fonction RotateEntity(#Entity, x, y, z)
parceque :
La rotation est relative à l'angle actuel de l'#Entity.
il faudrai refaire une fonction dont l'angle serai absolu a l'univers !!!
une sorte de giroscope !! :)

Publié : lun. 07/juin/2004 14:50
par comtois
ouaip , ça arrangerait bien mes affaires :)
mais bon , ça doit pouvoir se calculer , mais là j'ai pas trop la tête à ça , et puis les maths et moi :?

Mais je ne lache pas , ça va finir par venir :)


je vais d'abord reprendre entièrement la gestion des matrices , tel que c'est fait actuellement , ça me pose des problèmes pour gérer les textures, je vais essayer autrement.
Il faut aussi que je calcule autrement la postion X et Z , en tenant compte de la pente ,sinon , je n'ai pas un déplacement régulier !

Publié : lun. 07/juin/2004 16:35
par Chris
Comtois a écrit :...mais bon , ça doit pouvoir se calculer , mais là j'ai pas trop la tête à ça , et puis les maths et moi...
8O Tu te moques de qui, là?? :o

Chris :)

Publié : mar. 08/juin/2004 0:22
par Backup
non non !! il a raison !!

il est nul en math !! je lui ai demandé la formule qui donne les chiffres gagnant du loto !! et il sait pas faire !! :D

il ne fait que m'afficher les boule du loto !! :(

Publié : mar. 08/juin/2004 0:31
par Chris
Ah!!! Ben si il est nul en math, je suis comment moi ???

Je suis allé visiter le site qu'il a indiqué pour les surfaces en 3D, j'ai même pas compris le titre de la page :lol:

Chris :)