Code source complet -Collision 3D et réponse

Généralités sur la programmation 3D
Polo
Messages : 612
Inscription : sam. 03/juil./2004 20:14

Message par Polo »

Ben ouais, mais c'est pas facile quand même, faut dire qu'il y a du boulot de réalisé !! Je trouve que tu as sacrément bien bossé, le résultat est très bien !!!
Pour les doubles, je ne sais pas, mais pense que ça ralentira forcément le code, vu que la précision des calculs sera doublement ( :oops: ) plus grande !
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

je ne peux pas me pencher sur votre truc (actuellement) mais j'avais deux liens pour vous :

http://www.freevbcode.com/ShowCode.asp?ID=3506
http://www.gamespp.com/algorithms/collisiondetection/
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

oui j'ai vu la démo ODE et c'est du lâcher de balles !
C'est tout ce qu'on peut faire pour l'instant , enfin si c'est possible de faire autre chose je n'ai pas trouvé comment :?

Pour les tuts , je viens de jeter un coup d'oeil rapide , il y en a un , c'est que le code en VB , pas de commentaire , je ne sais pas ce que fait ce code exactement , qu'est-ce qu'il teste , est-ce qu'il intègre la réponse à une collision ? je n'ai pas tout regardé , mais ça me semble bien succinct pour tout prendre en compte.
Et l'autre tut , il faudra que je regarde plus en détail plus tard , en regardant vite fait , je n'ai pas vu d'infos nouvelles par rapport aux tuts que j'avais utilisés.Mais parfois il suffit d'un tout petit rien pour faire la différence ,alors faudra quand même que je l'épluche à fond , des fois que ce petit rien se trouve dans ce tut :)
Dernière modification par comtois le mer. 15/févr./2006 12:25, modifié 1 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.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

SI on arrive à déplacer la balle, pourquoi n'arrive ton pas à déplacer un perso ?
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Progi1984 a écrit :SI on arrive à déplacer la balle, pourquoi n'arrive ton pas à déplacer un perso ?
tu arrives à la déplacer ? vraiment ? et à la diriger ? et contrôler les réponses aux collisions ? c'est à dire choisir une collision glissante ou un rebond ?
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.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Ouh là, faudra que je modifie un peu plus l'exemple lol
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Progi1984 a écrit :Ouh là, faudra que je modifie un peu plus l'exemple lol
si tu trouves comment faire, je suis curieux de voir ça :P
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.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Il ne faut pas vendre la peau de l'ours avant de l'avoir tué
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Tiens au fait, des tutos en Blitz3D sur l'utilisation d'ODE, ca peut tjrs etre utile :) http://www.blitz3dfr.com/phpfrench/e107 ... php?fid=44


ODE & Purebasic :
http://forums.purebasic.com/english/vie ... 08f9a0af04
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Puisque Progi1984 le demandait , voici une première version de la lib CAR_Collision3D.

L'archive fait un peu plus de 2 Mo ( j'ai remis l'ensemble des meshs réalisés avec DeleD)

http://perso.wanadoo.fr/comtois/sources/Collision3D.zip

Il y a exe pour tester , désormais on peut modifier quelques paramètres (Gravité , vitesse ,taille de l'entity) via le fichier ini. Et aussi changer la map à afficher toujours en modifiant le fichier ini.

Avec la lib , le code source se résume à ça :

Code : Tout sélectionner

;Comtois le 21/02/06
;PB4.0 beta 3
;Je me suis grandement inspiré du tutoriel de Fauerby http://www.peroxide.dk
 
#Focale = 38
Structure Parametres
   AngleX.f   
   AngleY.f   
   AngleZ.f     
EndStructure

;-Initialisation
If ExamineDesktops()
  ScreenWidth  = DesktopWidth(0)
  ScreenHeight = DesktopHeight(0)
  ScreenDepth  = DesktopDepth(0)
EndIf
  
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 , "Demo 3D" ) = 0
  MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
  End
EndIf

 Add3DArchive("Data\"        , #PB_3DArchive_FileSystem)  
 Add3DArchive("Data\skybox.zip", #PB_3DArchive_Zip)
 Parse3DScripts()

;-Informations de l'entity
InfosNinja.Car_Collision
;-Information Monde 3D
World3D.Car_WorldCollision
;-Entity
LoadPreference("Collision3D.ini",@World3D,@InfosNinja)
CreateListeTriangles(@InfosNinja,@World3D)
WorldMesh = LoadMesh(#PB_Any, World3D\FichierMesh)
CreateEntity(#PB_Any, MeshID(WorldMesh), 0) 
;-SkyBox
If World3D\FichierSkyBox
  SkyBox(World3D\FichierSkyBox)
EndIf

;-Camera
CreateCamera(0,0,0,100,100)
Camera.Parametres
With InfosNinja
  CameraLocate(0,\PositionDansR3\x, \PositionDansR3\y + \RayonEllipsoide\y , \PositionDansR3\z)
  CameraLookAt(0,\PositionDansR3\x + M3D_Cos(0) * 80, \PositionDansR3\y + \RayonEllipsoide\y ,\PositionDansR3\z - M3D_Sin(0) * 80)
EndWith

Define.f MouseX,MouseY,PasX,PasZ,Fov
Fov = #Focale

;/
;-La boucle principale
;/

Repeat
  If ExamineMouse()
    MouseX = -(MouseDeltaX()/10) * InfosNinja\Vitesse/2
   	MouseY = -(MouseDeltaY()/10) * InfosNinja\Vitesse/2
	  
  	If MouseButton(1) 
	    If InfosNinja\VitesseDansR3\y<#Epsilon
        InfosNinja\VitesseDansR3\y = InfosNinja\Vitesse * 2
      Else
        InfosNinja\VitesseDansR3\y *1.1
      EndIf  
    EndIf

    
    If MouseButton(2)
      Fov=M3D_CurveValue(Fov,5,50)
    Else
      Fov=M3D_CurveValue(Fov,#Focale,50)
    EndIf  
  EndIf  
  Camera\AngleX = M3D_WrapValue( Camera\AngleX + MouseX)
  RotateCamera(0,MouseX,0,0) 
  If MouseY > 0 And Camera\AngleY < 75
    Camera\AngleY + MouseY 
    RotateCamera(0,0,MouseY,0) 
  ElseIf MouseY < 0 And Camera\AngleY > -75
    Camera\AngleY + MouseY 
    RotateCamera(0,0,MouseY,0) 
  EndIf	
  If ExamineKeyboard()
    If KeyboardPushed(#PB_Key_PageUp)
      Fov + 0.1
    EndIf
    If KeyboardPushed(#PB_Key_PageDown)
      Fov - 0.1
    EndIf   	

 	  ;Touches du joueur
  
  	If KeyboardPushed(#PB_Key_Left)
      InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX+90) * InfosNinja\Vitesse
  		InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX+90) * InfosNinja\Vitesse
    ElseIf KeyboardPushed(#PB_Key_Right)
    	InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX-90) * InfosNinja\Vitesse
  		InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX-90) * InfosNinja\Vitesse
    EndIf
    If KeyboardPushed(#PB_Key_Up)
      InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX) * InfosNinja\Vitesse
  		InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX) * InfosNinja\Vitesse
    ElseIf KeyboardPushed(#PB_Key_Down)
      InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX) * -InfosNinja\Vitesse
 			InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX) * -InfosNinja\Vitesse
    EndIf
  EndIf 
  
 	GestionDeplacement1(@InfosNinja,@World3D)
	Cx.f = M3D_CurveValue(CameraX(0),InfosNinja\PositionDansR3\x,200)
	Cy.f = M3D_CurveValue(CameraY(0),InfosNinja\PositionDansR3\y+48,200) 
	Cz.f = M3D_CurveValue(CameraZ(0),InfosNinja\PositionDansR3\z,200)
  CameraLocate(0,Cx, Cy, Cz)
  CameraFOV(0,fov*0.0174533)
  RenderWorld()
  
  StartDrawing(ScreenOutput())
    DrawText(0,0,StrF(Engine3DFrameRate(#PB_Engine3D_Current),0))
  StopDrawing()
  
  InfosNinja\VitesseDansR3\x = 0.0
	InfosNinja\VitesseDansR3\z = 0.0
	
  If InfosNinja\VitesseDansR3\y > 0
    InfosNinja\VitesseDansR3\y + World3D\Gravite\y 
  ElseIf InfosNinja\VitesseDansR3\y < 1
    InfosNinja\VitesseDansR3\y = 0
  EndIf   
  FlipBuffers()
   
Until KeyboardPushed(#PB_Key_Escape)
Voila , vous pouvez charger n'importe quel niveau maintenant.
Bien sûr , vous aurez besoin de générer une liste de triangles , pour l'instant j'utilise ce code :

Code : Tout sélectionner

;Comtois 21/02/06
;PB4.0 Beta 3

Source$="D:\Ogre\OgreCommandLineTools-1.0.6\WaterWorld.xml"               ; <<<< Fichier du mesh dans le format Xml
Destination$="D:\Ogre\OgreCommandLineTools-1.0.6\WaterWorldTriangles.HD"  ; <<<< Fichier contenant la liste des triangles 

Structure Face
  v1.l
  v2.l
  v3.l
EndStructure
Structure Point3D
	x.f
	y.f
	z.f
EndStructure
Structure Vecteur
	x.f
 	y.f
 	z.f
EndStructure

Structure Triangle 
	P1.Point3D
 	P2.Point3D
 	P3.Point3D
	Constante.f
 	Normale.Vecteur 
EndStructure


NewList Face.Face()
Global NewList ListTriangle.Triangle()
Define.f MiniX,MiniY,MiniZ,MaxiX,MaxiY,MaxiZ

Procedure.s StringFieldPerso(T$,Index)
  Champ=0
  Deb=0
  Chaine$=""
  For i=1 To Len(T$)
    Car$=Mid(T$,i,1)
    If Car$=Chr(34)
      If Deb=0
        Deb=1
        Champ + 1
        Continue
      Else 
        Deb=0
      EndIf
    EndIf  
    If Champ=Index And Deb 
      Chaine$=Chaine$+Car$
    EndIf  
  Next i
  ProcedureReturn Chaine$
EndProcedure

OpenConsole()
SubMesh = 0

If OpenFile(0,Source$)
  
  PrintN("Ouverture du fichier Xml : " + Source$)
  
  While Eof(0)=0
    
    Ligne$=ReadString(0)
    If FindString(Ligne$,"<faces count=",1)
      Pos=FindString(Ligne$,"count=",1)
      Pos + 7
      NbFace=Val(Mid(Ligne$,Pos,Len(Ligne$)-Pos-1))
      SubMesh + 1
      PrintN("SubMesh No : " + Str(SubMesh))
      PrintN("Nombre de triangles : " + Str(NbFace))
      
      ;Lecture des Faces
      ClearList(Face())
      For i=1 To NbFace
        Ligne$=ReadString(0)
        AddElement(Face())
        Face()\v1=Val(StringFieldPerso(Ligne$,1))
        Face()\v2=Val(StringFieldPerso(Ligne$,2))
        Face()\v3=Val(StringFieldPerso(Ligne$,3))
      Next i  
    EndIf
    
    ;Cherche les vertices
    If FindString(Ligne$,"<geometry vertexcount=",1)
      Pos=FindString(Ligne$,"count=",1)
      Pos + 7
      NbVertex=Val(Mid(Ligne$,Pos,Len(Ligne$)-Pos-1))
      PrintN("Nombre de sommets : " + Str(NbVertex))
      Dim Vertex.Vecteur(NbVertex)
      Dim Normale.Vecteur(NbVertex)
    EndIf  
    
    If FindString(Ligne$,"<vertexbuffer",1)  
      Index=0
    EndIf
    
    ;Lecture des vertex
    If FindString(Ligne$,"<position",1)
      Vertex(Index)\x=ValF(StringFieldPerso(Ligne$,1))
      Vertex(Index)\y=ValF(StringFieldPerso(Ligne$,2))
      Vertex(Index)\z=ValF(StringFieldPerso(Ligne$,3))
      If Vertex(Index)\x < MiniX 
        MiniX = Vertex(Index)\x 
      ElseIf Vertex(Index)\x > MaxiX   
        MaxiX = Vertex(Index)\x 
      EndIf
      If Vertex(Index)\y < MiniY 
        MiniY = Vertex(Index)\y
      ElseIf Vertex(Index)\y > MaxiY 
        MaxiY = Vertex(Index)\y
      EndIf
      If Vertex(Index)\z < MiniZ
        MiniZ = Vertex(Index)\z
      ElseIf Vertex(Index)\z > MaxiZ  
        MaxiZ = Vertex(Index)\z
      EndIf      
    EndIf  
    ;Lecture des normales
    If FindString(Ligne$,"<normal",1)
      Normale(Index)\x=ValF(StringFieldPerso(Ligne$,1))
      Normale(Index)\y=ValF(StringFieldPerso(Ligne$,2))
      Normale(Index)\z=ValF(StringFieldPerso(Ligne$,3))
      Index + 1
    EndIf 
         
    ;On peut enregistrer ce submesh 
    If FindString(Ligne$,"</vertexbuffer>",1) 
       ForEach Face()
        AddElement(ListTriangle())
        ;v1
        ListTriangle()\P1\x=Vertex(Face()\v1)\x 
        ListTriangle()\P1\y=Vertex(Face()\v1)\y 
        ListTriangle()\P1\z=Vertex(Face()\v1)\z 
        ;v2
        ListTriangle()\P2\x=Vertex(Face()\v2)\x 
        ListTriangle()\P2\y=Vertex(Face()\v2)\y 
        ListTriangle()\P2\z=Vertex(Face()\v2)\z 
        ;v3
        ListTriangle()\P3\x=Vertex(Face()\v3)\x 
        ListTriangle()\P3\y=Vertex(Face()\v3)\y 
        ListTriangle()\P3\z=Vertex(Face()\v3)\z 
        ListTriangle()\Normale\x=(Normale(Face()\v1)\x + Normale(Face()\v2)\x +Normale(Face()\v3)\x)/3
        ListTriangle()\Normale\y=(Normale(Face()\v1)\y + Normale(Face()\v2)\y +Normale(Face()\v3)\y)/3
        ListTriangle()\Normale\z=(Normale(Face()\v1)\z + Normale(Face()\v2)\z +Normale(Face()\v3)\z)/3 
      Next
    EndIf    
  Wend  
  CloseFile(0)
  PrintN("Total triangles : " + Str(CountList(ListTriangle())))
EndIf


;Génère un fichier contenant la liste des triangles 
If CreateFile(0,Destination$)
  PrintN("Creation du fichier triangle : " + Destination$)
  WriteLong(0,CountList(ListTriangle()))
  ForEach ListTriangle()
    WriteData(0,@ListTriangle(),SizeOf(Triangle))
  Next
  CloseFile(0)
  PrintN("Operation terminee")
  PrintN("Pressez la touche [Entree] pour quitter")
EndIf
PrintN("MiniX = " + StrF(MiniX,3))
PrintN("MaxiX = " + StrF(MaxiX,3))
PrintN("MiniY = " + StrF(MiniY,3))
PrintN("MaxiY = " + StrF(MaxiY,3))
PrintN("MiniZ = " + StrF(MiniZ,3))
PrintN("MaxiZ = " + StrF(MaxiZ,3))
Input()
CloseConsole()
End
Si un courageux veut l'améliorer en faisant une petite appli window avec des OpenFileRequester , et autres Requester , ça serait cool :)

On pourrait charger un mesh directement , et lancer la conversion en xml , et calculer la liste des triangles, et l'enregistrer dans le répertoire choisi , bref un petit utilitaire assez facile à réaliser.
pour convertir je me suis fait un simple code

Code : Tout sélectionner

Nom$="temple"
Source$=Nom$+".mesh"
Destination$=Nom$+".xml"
RunProgram("OgreXMLConverter.exe",Source$ + " " + Destination$,"")
ça serait mieux avec un requester :)
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.
Anonyme

Message par Anonyme »

Bon , je savais pas trop quoi faire, alors voilà un "effet blur" salement codé(il est 4h20 du mat). mais il me rapelle les moment ou je prennais une flashbang dans Counter, ou un tir d'artillerie dans Call of duty :D



Les déclarations :

Code : Tout sélectionner

InitSprite3D()
Global Dim DelayBlur.l(20)
Global Dim Alpha.l(20)
Declare BlurScreen()

La procedure :

Code : Tout sélectionner

Procedure BlurScreen()
Shared DelayBlur.l,DelaybetweenD.l,EndAlpha.l


If DelaybetweenD<ElapsedMilliseconds()
DelaybetweenD=ElapsedMilliseconds()+25
For i = 1 To 15


If DelayBlur(i)<ElapsedMilliseconds()
DelayBlur(i)=ElapsedMilliseconds()+25*15
 GrabSprite(i,0,0,1024,768,#PB_Sprite_Texture)
   CreateSprite3D(i,i)
    Alpha(i)=255/5
   Goto Next_
EndIf


Next i
EndIf
Next_:


Start3D()

For i = 1 To 15

If EndAlpha<ElapsedMilliseconds()
EndAlpha=ElapsedMilliseconds()+25
For e = 1 To 15
Alpha(e)-1
Next 
EndIf

If IsSprite3D(i)
DisplaySprite3D(i,0,0,Alpha(i))
EndIf

Next 
Stop3D()

EndProcedure
Bien sur , avant le flipbuffers() mettre BlurScreen() dans la boucle principale.
@+
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Sympa l'effet , c'est vrai que pour agrémenter un jeu , c'est intéressant.

Mais tu aurais pu tenir compte de ces variables

Code : Tout sélectionner

  ScreenWidth  = DesktopWidth(0)
  ScreenHeight = DesktopHeight(0)
  ScreenDepth  = DesktopDepth(0) 
Mon écran est en 1280x1024 , ça faisait bizarre au début , avant que je change ton code :)
Mais bon , coder ça à 4h30 faut pas trop en demander non plus :lol:

Merci pour le code, il pourra me servir si je fais un jeu un jour.ou dans une autre démo.
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.
Anonyme

Message par Anonyme »

J'étais crevé, c'est pour cela que j'ai coder vite fait.
Lorsque la v4 sera officielement sortie je pense me lancer un peu plus dans les effets 3D/2D du style lensFlare, reflection...
Cela peut etre intéressant.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

et voila le code source de la lib CAR_Collision3D
Comme d'hab ,si quelqu'un améliore la chose ,ça serait sympa de nous montrer comment :)

Code : Tout sélectionner

;Comtois le 21/02/06

#Epsilon=0.0001

Macro CopieVecteur(V,V1)
  V\x=V1\x
  V\y=V1\y
  V\z=V1\z
EndMacro 
Macro AdditionVecteur(V,V1,V2)
  V\x=V1\x+V2\x
  V\y=V1\y+V2\y
  V\z=V1\z+V2\z
EndMacro 
Macro SoustractionVecteur(V,V1,V2)
  V\x=V1\x-V2\x
  V\y=V1\y-V2\y
  V\z=V1\z-V2\z
EndMacro 
Macro DivisionVecteur(V,V1,V2)
  V\x=V1\x/V2\x
  V\y=V1\y/V2\y
  V\z=V1\z/V2\z
EndMacro 
Macro MultiplicationVecteur(V,V1,V2)
  V\x=V1\x*V2\x
  V\y=V1\y*V2\y
  V\z=V1\z*V2\z
EndMacro 
;- Les structures
Structure Parametres
   AngleX.f   
   AngleY.f   
   AngleZ.f     
EndStructure
Structure Vecteur
	x.f
 	y.f
 	z.f
EndStructure
Structure Triangle 
	P1.Vecteur
 	P2.Vecteur
 	P3.Vecteur
	Constante.f
 	Normale.Vecteur 
EndStructure
Structure s_Collision 
	RayonEllipsoide.vecteur ;  Rayon de l'ellipsoide
 	;Informations sur le déplacement dans le monde R3
 	VitesseDansR3.Vecteur
 	PositionDansR3.Vecteur
 	Vitesse.f
	;Changement de Base vectorielle, BaseE = Base de l'ellipsoide
 	VitesseDansBaseE.Vecteur
 	VitesseDansBaseENormee.Vecteur
 	PointOrigine.Vecteur
 	;Informations collisions
 	CollisionDetectee.l
 	DistanceLaPlusCourte.f
 	PointIntersection.Vecteur	 
EndStructure
Structure Plan
	Constante.f
 	Origine.Vecteur
 	Normale.Vecteur
EndStructure
Structure s_WorldCollision
  FichierTriangles.s
  FichierMesh.s
  FichierSkyBox.s
  NombreRebouclage.l  
  RebouclageMaxi.l
  DistanceTresFaible.f 
  Gravite.Vecteur
  *ListeTriangles.Triangle
  NbTriangles.l
EndStructure
Structure s_Reponse
  PositionFinale.Vecteur
  PositionInitiale.Vecteur
  Vitesse.Vecteur
  *ListeTriangles.Triangle
EndStructure

;-Les procédures
Procedure SavePreferences(Fichier$)
  If CreatePreferences(Fichier$)
    PreferenceGroup("FICHIERS")
    WritePreferenceString("Fichier triangles","CastleTriangles.HD")
    WritePreferenceString("Fichier mesh","Castle.mesh")
    WritePreferenceString("Fichier SkyBox","Stevecube.jpg")
    PreferenceGroup("GRAVITE")
    WritePreferenceFloat("X",0.0)
    WritePreferenceFloat("Y",-9.0)
    WritePreferenceFloat("Z",0.0)
    PreferenceGroup("COLLISION")
    WritePreferenceLong("Nombre de rebouclage", 5)
    WritePreferenceFloat("Distance très faible",0.005)
    PreferenceGroup("ENTITY")
    WritePreferenceFloat("Vitesse",9.0)
    WritePreferenceFloat("Largeur",20)
    WritePreferenceFloat("Hauteur",70)
    WritePreferenceFloat("Profondeur",20)
    WritePreferenceFloat("Position X",250.0)
    WritePreferenceFloat("Position Y",1250.0)
    WritePreferenceFloat("Position Z",300.0)
    ClosePreferences()
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False 
EndProcedure
ProcedureDLL LoadPreference(Fichier$,*World3D.s_WorldCollision,*Entity.s_Collision)
  If OpenPreferences(Fichier$)
    PreferenceGroup("FICHIERS")
    *World3D\FichierTriangles=ReadPreferenceString("Fichier triangles","TempleTriangles.HD")
    *World3D\FichierMesh=ReadPreferenceString("Fichier mesh","Temple.mesh")
    *World3D\FichierSkyBox=ReadPreferenceString("Fichier SkyBox","")
    PreferenceGroup("GRAVITE")
    *World3D\Gravite\x=ReadPreferenceFloat("X",0.0)
    *World3D\Gravite\y=ReadPreferenceFloat("Y",-9)
    *World3D\Gravite\z=ReadPreferenceFloat("Z",0.0)
    PreferenceGroup("COLLISION")
    *World3D\RebouclageMaxi=ReadPreferenceLong("Nombre de rebouclage", 5)
    *World3D\DistanceTresFaible=ReadPreferenceFloat("Distance très faible",0.005)
    PreferenceGroup("ENTITY")
    *Entity\Vitesse=ReadPreferenceFloat("Vitesse",9.0)
    *Entity\RayonEllipsoide\x=ReadPreferenceFloat("Largeur",25.0)
    *Entity\RayonEllipsoide\y=ReadPreferenceFloat("Hauteur",70.0)
    *Entity\RayonEllipsoide\z=ReadPreferenceFloat("Profondeur",25.0)
    *Entity\PositionDansR3\x=ReadPreferenceFloat("Position X",250.0)
    *Entity\PositionDansR3\y=ReadPreferenceFloat("Position Y",125.0)
    *Entity\PositionDansR3\z=ReadPreferenceFloat("Position Z",300.0)
    ClosePreferences()
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False 
EndProcedure
Procedure.f ProduitScalaire(*V1.Vecteur, *V2.Vecteur)
	ProcedureReturn *V1\x * *V2\x + *V1\y * *V2\y + *V1\z * *V2\z 
EndProcedure
Procedure ProduitVectoriel(*N.Vecteur,*V1.Vecteur, *V2.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 Normalise(*N.Vecteur)
   Norme.f=Sqr(*N\x * *N\x + *N\y * *N\y + *N\z * *N\z)
   If Norme = 0.0
      *N\x = 0.0
      *N\y = 0.0
      *N\z = 0.0
   Else
    	*N\x / Norme
      *N\y / Norme
      *N\z / Norme
    EndIf   
EndProcedure
Procedure LongueurVecteur(*V.Vecteur,LongV.f)
	Norme.f=Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
 	*V\x * LongV / Norme
 	*V\y * LongV / Norme
 	*V\z * LongV / Norme
EndProcedure
Procedure.f Longueur(*V.Vecteur)
	ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z) 
EndProcedure
Procedure.b TestPointDansTriangle1(*P.Vecteur, *A.Vecteur, *B.Vecteur, *C.Vecteur)
	Protected  PA.Vecteur,PB.Vecteur,PC.Vecteur,Somme.Vecteur
	PA\x=*A\x-*P\x
	PA\y=*A\y-*P\y
	PA\z=*A\z-*P\z
	Normalise(@PA)
	PB\x=*B\x-*P\x
	PB\y=*B\y-*P\y
	PB\z=*B\z-*P\z
	Normalise(@PB)
	PC\x=*C\x-*P\x
	PC\y=*C\y-*P\y
	PC\z=*C\z-*P\z
	Normalise(@PC)
	Somme\x=PA\x+PB\x+PC\x
	Somme\y=PA\y+PB\y+PC\y
	Somme\z=PA\z+PB\z+PC\z
	;on calcule la taille du vecteur Somme
	If Longueur(Somme) > 1 
		ProcedureReturn #False
	EndIf
	ProcedureReturn #True
EndProcedure
Procedure.f NormeAuCarre(*V.Vecteur)
	ProcedureReturn *V\x * *V\x + *V\y * *V\y + *V\z * *V\z 
EndProcedure
Procedure.b ChercheLaPlusPetiteSolution(a.f, b.f, c.f, maxR.f,*Solution.Float)
	;Cherche les solutions d'une équation de cette forme : At²+Bt+C=0
 	;http://fr.wikipedia.org/wiki/%C3%89quation_du_second_degr%C3%A9 (bas de la page "Gain de précision")
	 	
	;Calcul le déterminant
 	Determinant.f = b * b - 4.0 * a * c
 	;Si le déterminant est inférieur ou égal à zéro , il n'y a pas d'intersection significative.
 	If Determinant < 0.0 : ProcedureReturn #False : EndIf

	If a=0.0
		t1.f=-c/b
		t2.f=0.0
	Else
	 	;Calcul les deux solutions 
	 	If b<0.0
			q.f=0.5 * (-b - Sqr(Determinant)) 
		Else
			q.f=0.5 * (-b + Sqr(Determinant)) 
		EndIf
		t1.f = q / a
 		t2.f = c / q
	EndIf
	
 	;Renvoie la solution la plus petite si elle est valide
 	If t1 > 0  And t1 < maxR 
  		*Solution\f = t1
  		ProcedureReturn #True
 	EndIf
 	If t2 > 0  And t2 < maxR
  		*Solution\f = t2
  		ProcedureReturn #True
 	EndIf
 	;Pas de solution
 	ProcedureReturn #False
EndProcedure
Procedure TestCollision(*Sphere.s_Collision,*World3D.s_WorldCollision)
	Protected PlanTriangle.Plan
	Protected a.f,b.f,c.f,NouveauT.f,NormeAreteAuCarre.f
	Protected Sphere_p1.Vecteur,	p1_Sphere.Vecteur
	Protected Sphere_p2.Vecteur,	p2_Sphere.Vecteur	
	Protected Sphere_p3.Vecteur,	p3_Sphere.Vecteur
 	Protected Arete.Vecteur, PointCollision.Vecteur,PointIntersectionSurLePlan.Vecteur 

  *Ptr.Triangle=*World3D\ListeTriangles
	For i = 1 To *World3D\NbTriangles
	  *Ptr + SizeOf(Triangle)
	 	;A revoir , c'est pas utile de tout recopier , je pourrais utiliser directement la liste chainée ?
		CopieVecteur(PlanTriangle\Normale, *Ptr\normale)
	  CopieVecteur(PlanTriangle\Origine, *Ptr\P1) 
		PlanTriangle\Constante=*Ptr\Constante  	
	
		;Le produit scalaire <=0 si on se trouve face au triangle 
		If ProduitScalaire(@PlanTriangle\Normale, *Sphere\VitesseDansBaseENormee)>=0 
			;Inverse la normale ( C'est provisoire , en attendant de faire un éditeur correct qui oriente la normale dans le bon sens)
	  		PlanTriangle\Normale\x * -1
	  		PlanTriangle\Normale\y * -1
	  		PlanTriangle\Normale\z * -1
	  		PlanTriangle\Constante * -1
	 	EndIf
		
	  	;Initialise t0,t1	
		  t0.f=0.0 
	  	t1.f=0.0 
		
		;Initialise un drapeau   
	   SphereCoupeLePlan.l = #False
	   
	   ;Calcul la distance de la sphère au plan du triangle (d=N.S0+Cp : http://homeomath.imingo.net/displan.htm)
	   DistanceSpherePlan.f=ProduitScalaire(*Sphere\PointOrigine,@PlanTriangle\normale) + PlanTriangle\Constante
	   
	   ;Calcul le produit scalaire Normale du plan avec le vecteur vitesse
	   ;Permet de déterminer si la sphère se déplace parallèlement au plan 
	   PScalaireNormaleVitesse.f = ProduitScalaire(@PlanTriangle\normale, *Sphere\VitesseDansBaseE)
	
	   ;Si la sphère se déplace parallèlement au plan
	   ;If PScalaireNormaleVitesse>-#Epsilon And PScalaireNormaleVitesse<#Epsilon
 	   If PScalaireNormaleVitesse=0.0
   	   ;Il n'y a pas de collision si la distance de la Sphère au Plan est supérieure au rayon de la sphère
	   	If Abs(DistanceSpherePlan) > 1.0
	    		;La sphère ne coupe pas le plan , il n'y a pas de collision 
			   Continue 
	   	Else 
	    		;La sphère coupe le plan.elle est en collision dans l'intervalle [0..1]
	    		SphereCoupeLePlan = #True
	    		t0 = 0.0
	    		t1 = 1.0
	   	EndIf
		   
	  	Else 
		  
	   	;Calcul l'intervalle dans lequel la sphère est en collision
	   	t0=(-1.0-DistanceSpherePlan)/PScalaireNormaleVitesse
	   	t1=( 1.0-DistanceSpherePlan)/PScalaireNormaleVitesse
	   	;Swap si nécessaire
	   	If t0 > t1
	   	    Swap t0,t1
	   	EndIf
	   	;Pas de collision si les deux résultats sont hors de l'intervalle [0..1]
	   	If t0 > 1.0 Or t1 < 0.0
			   Continue 
	   	EndIf
	   	;Recadre dans l'intervalle [0,1]
	   	If t0 < 0.0 : t0 = 0.0 : EndIf
	   	If t1 > 1.0 : t1 = 1.0 : EndIf
		   
	   EndIf
	   
	   ;Maintenant on connait l'intervalle dans lequel il est possible qu'une collision se produise ,
	   ; mais on ne sait pas encore où.
	  
	   TriangleEnCollision.l = #False
	   t.f = 1.0
	   
	   ;Test si la collision est dans le triangle 
	   If SphereCoupeLePlan=#False
		   ;Position de la sphère à t0 - la Normale du plan 
	   	PointIntersectionSurLePlan\x=(*Sphere\PointOrigine\x + t0 * *Sphere\VitesseDansBaseE\x) - PlanTriangle\Normale\x
	   	PointIntersectionSurLePlan\y=(*Sphere\PointOrigine\y + t0 * *Sphere\VitesseDansBaseE\y) - PlanTriangle\Normale\y
	   	PointIntersectionSurLePlan\z=(*Sphere\PointOrigine\z + t0 * *Sphere\VitesseDansBaseE\z) - PlanTriangle\Normale\z
	     	;Test si le point d'intersection se trouve dans le triangle
		   If (TestPointDansTriangle1(@PointIntersectionSurLePlan,*Ptr\p1,*Ptr\p2,*Ptr\p3))
	    		TriangleEnCollision = #True
			   ;Mémorise t et Le point en collision le plus proche  
	    		t = t0
	    		CopieVecteur(PointCollision, PointIntersectionSurLePlan)
	   	EndIf
	  	EndIf
	
		;S'il n'y a pas de collision à l'intérieur du triangle , il faut tester les sommets et les arêtes 
		  
	  	If TriangleEnCollision = #False 
	  	
		   NormeVitesseAuCarre.f = NormeAuCarre(*Sphere\VitesseDansBaseE)
	
	   	;P1
	   	SoustractionVecteur(Sphere_p1, *Sphere\PointOrigine, *Ptr\p1)
	   	SoustractionVecteur(p1_Sphere, *Ptr\p1, *Sphere\PointOrigine)
		   b = 2.0 * ProduitScalaire(*Sphere\VitesseDansBaseE,@Sphere_p1)
	   	c = NormeAuCarre(@p1_Sphere) - 1.0
	   	If ChercheLaPlusPetiteSolution(NormeVitesseAuCarre,b,c, t, @NouveauT) 
	    		t = NouveauT
	    		TriangleEnCollision = #True
	    		CopieVecteur(PointCollision, *Ptr\p1)
	   	EndIf
		   
	   	;p1 -> p2:
	   	SoustractionVecteur(Arete, *Ptr\p2, *Ptr\p1)
	   	NormeAreteAuCarre.f = NormeAuCarre(@Arete)
	   	PScalaireAreteVitesse.f = ProduitScalaire(@Arete,*Sphere\VitesseDansBaseE)
	   	PScalaireAreteP_Sphere.f = ProduitScalaire(@Arete,@p1_Sphere)
	   	;Calcule les paramètres de l'équation
	   	a = NormeAreteAuCarre*-NormeVitesseAuCarre + PScalaireAreteVitesse*PScalaireAreteVitesse
	   	b = NormeAreteAuCarre*(2.0 * ProduitScalaire(*Sphere\VitesseDansBaseE,@p1_Sphere))-2.0*PScalaireAreteVitesse*PScalaireAreteP_Sphere
	   	c = NormeAreteAuCarre*(1-NormeAuCarre(@p1_Sphere))+PScalaireAreteP_Sphere*PScalaireAreteP_Sphere
	   	;Cherche si une intersection de la Sphere avec la ligne passant par l'arête existe
	   	If ChercheLaPlusPetiteSolution(a,b,c, t, @NouveauT)
	    		;Il faut vérifier que le point trouvé se trouve bien sur l'arete
	    		f.f=(PScalaireAreteVitesse*NouveauT-PScalaireAreteP_Sphere)/NormeAreteAuCarre
	    		If f >= 0.0 And f <= 1.0
	     			t = NouveauT
	     			TriangleEnCollision = #True
	     			AdditionVecteur(PointCollision, *Ptr\p1, f * Arete)
	    		EndIf
	   	EndIf
	   
	   	;P2
	   	SoustractionVecteur(Sphere_p2, *Sphere\PointOrigine, *Ptr\p2)
	   	SousTractionVecteur(p2_Sphere, *Ptr\p2, *Sphere\PointOrigine)
	    b = 2.0 * ProduitScalaire(*Sphere\VitesseDansBaseE,@Sphere_p2)
	   	c = NormeAuCarre(@p2_Sphere) - 1.0
	   	If ChercheLaPlusPetiteSolution(NormeVitesseAuCarre,b,c, t, @NouveauT)
	    		t = NouveauT
	    		TriangleEnCollision = #True
	    		CopieVecteur(PointCollision, *Ptr\p2)
	   	EndIf
		   
	   	;p2 -> p3:
	   	SoustractionVecteur(Arete,*Ptr\p3,*Ptr\p2)
	   	NormeAreteAuCarre = NormeAuCarre(@Arete)
	   	PScalaireAreteVitesse = ProduitScalaire(@Arete,*Sphere\VitesseDansBaseE)
	   	PScalaireAreteP_Sphere = ProduitScalaire(@Arete,@p2_Sphere)
	   	a = NormeAreteAuCarre*-NormeVitesseAuCarre + PScalaireAreteVitesse*PScalaireAreteVitesse
	   	b = NormeAreteAuCarre*(2.0 * ProduitScalaire(*Sphere\VitesseDansBaseE,@p2_Sphere))-2.0*PScalaireAreteVitesse*PScalaireAreteP_Sphere
	   	c = NormeAreteAuCarre*(1-NormeAuCarre(@p2_Sphere))+PScalaireAreteP_Sphere*PScalaireAreteP_Sphere
	   	;Cherche si une intersection de la Sphere avec la ligne passant par l'arête existe
	   	If ChercheLaPlusPetiteSolution(a,b,c, t, @NouveauT)
	    		;Il faut vérifier que le point trouvé se trouve bien sur l'arete
		     	f.f=(PScalaireAreteVitesse*NouveauT-PScalaireAreteP_Sphere)/NormeAreteAuCarre
	    		If f >= 0.0 And f <= 1.0
	     			t = NouveauT
	     			TriangleEnCollision = #True
	     			AdditionVecteur(PointCollision, *Ptr\p2, f * Arete)
	    		EndIf
	   	EndIf
	
	   	;P3
	   	SoustractionVecteur(Sphere_p3,*Sphere\PointOrigine,*Ptr\p3)
	   	SoustractionVecteur(p3_Sphere,*Ptr\p3,*Sphere\PointOrigine)
	   	b = 2.0 * ProduitScalaire(*Sphere\VitesseDansBaseE,@Sphere_p3)
	   	c = NormeAuCarre(@p3_Sphere) - 1.0
	   	If ChercheLaPlusPetiteSolution(NormeVitesseAuCarre,b,c, t, @NouveauT)
	    		t = NouveauT
	    		TriangleEnCollision = #True
	    		CopieVecteur(PointCollision, *Ptr\p3)
	   	EndIf
	   
	   	;p3 -> p1:
	   	SoustractionVecteur(Arete, *Ptr\p1, *Ptr\p3)
	   	NormeAreteAuCarre = NormeAuCarre(@Arete)
	   	PScalaireAreteVitesse = ProduitScalaire(@Arete,*Sphere\VitesseDansBaseE)
	   	PScalaireAreteP_Sphere = ProduitScalaire(@Arete,@p3_Sphere)
	   	a = NormeAreteAuCarre*-NormeVitesseAuCarre +PScalaireAreteVitesse*PScalaireAreteVitesse
	   	b = NormeAreteAuCarre*(2.0 * ProduitScalaire(*Sphere\VitesseDansBaseE,@p3_Sphere))-2.0*PScalaireAreteVitesse*PScalaireAreteP_Sphere
	   	c = NormeAreteAuCarre*(1-NormeAuCarre(@p3_Sphere))+PScalaireAreteP_Sphere*PScalaireAreteP_Sphere
	   	;Cherche si une intersection de la Sphere avec la ligne passant par l'arête existe
	   	If ChercheLaPlusPetiteSolution(a,b,c, t, @NouveauT)
	    		;Il faut vérifier que le point trouvé se trouve bien sur l'arete
	    		f.f=(PScalaireAreteVitesse*NouveauT-PScalaireAreteP_Sphere)/NormeAreteAuCarre
	    		If f >= 0.0 And f <= 1.0
	     			t = NouveauT
	     			TriangleEnCollision = #True
	     			AdditionVecteur(PointCollision, *Ptr\p3, f * Arete)
	    		EndIf
	   	EndIf
	  	EndIf
	
	  	;Stock le résultat
	 	If TriangleEnCollision = #True 
	   	;Calcul la distance que la sphère peut parcourir jusqu'au point en collision
	   	DistancePointCollision.f = t * Longueur(*Sphere\VitesseDansBaseE)
		   ;Si c'est le premier triangle en collision ou le plus près 
	   	If *Sphere\CollisionDetectee = #False Or DistancePointCollision < *Sphere\DistanceLaPlusCourte 
	    		;Informations nécessaires pour le calcul du glissement
	    		*Sphere\DistanceLaPlusCourte = DistancePointCollision       ; Pour sélectionner le triangle le plus proche
	    		CopieVecteur(*Sphere\PointIntersection, PointCollision)
	    		*Sphere\CollisionDetectee = #True
	   	EndIf
		EndIf
	Next
EndProcedure
Procedure ReponseCollision(*Reponse.s_Reponse,*World3D.s_WorldCollision)
 	Protected PlanDeGlissement.Plan, Entity.s_Collision
	Protected PointDestination.Vecteur, NouveauPointOrigine.Vecteur
	Protected V.Vecteur, NouveauPointDestination.Vecteur, NouvelleVitesse.Vecteur
	  
	;Limite le rebouclage 
  If (*World3D\NombreRebouclage>*World3D\RebouclageMaxi)
    CopieVecteur(*Reponse\PositionFinale, *Reponse\PositionInitiale)
  	ProcedureReturn 
 	EndIf 
 	
	;Stocke les informations nécessaires au test de collision 
 	CopieVecteur(Entity\VitesseDansBaseE, *Reponse\Vitesse)
 	CopieVecteur(Entity\VitesseDansBaseENormee, *Reponse\Vitesse)
 	Normalise(@Entity\VitesseDansBaseENormee)
 	CopieVecteur(Entity\PointOrigine, *Reponse\PositionInitiale)
 	Entity\CollisionDetectee = #False
 	
	;Test les triangles , s'il y a collision , retourne le point d'intersection avec le triangle.
	;Pour améliorer la vitesse , il faudrait sélectionner uniquement les triangles susceptibles d'être en collision
	;Voir pour ajouter un octree , ou peut-être un quadtree pour commencer.
	TestCollision(@Entity,*World3D)
	 
 	;Il n'y a pas de collision, on peut se déplacer normalement
 	If Entity\CollisionDetectee = #False
  		AdditionVecteur(*Reponse\PositionFinale, *Reponse\PositionInitiale, *Reponse\Vitesse)
  		ProcedureReturn 
 	EndIf
 
 	;Calcul le point de destination ( comme s'il n'y avait pas de collision)
 	AdditionVecteur(PointDestination, *Reponse\PositionInitiale, *Reponse\Vitesse)
 
 	CopieVecteur(NouveauPointOrigine, *Reponse\PositionInitiale)
 	
	;On se replace un peu avant le point de d'intersection calculé dans TestCollision()
 	If Entity\DistanceLaPlusCourte > *World3D\DistanceTresFaible
  		V\x = *Reponse\Vitesse\x
  		V\y = *Reponse\Vitesse\y
  		V\z = *Reponse\Vitesse\z
  		LongueurVecteur(@V, Entity\DistanceLaPlusCourte - *World3D\DistanceTresFaible)
  		NouveauPointOrigine\x + V\x
  		NouveauPointOrigine\y + V\y
  		NouveauPointOrigine\z + V\z
		    		
      ;Et on déplace aussi le point d'intersection de façon à ne pas être en collision sur le plan de glissement
   	  Normalise(@V)
  		Entity\PointIntersection\x - *World3D\DistanceTresFaible * V\x 
  		Entity\PointIntersection\y - *World3D\DistanceTresFaible * V\y 
  		Entity\PointIntersection\z - *World3D\DistanceTresFaible * V\z 
	EndIf
	
	;Determine le plan de glissement
	CopieVecteur(PlanDeGlissement\Origine, Entity\PointIntersection)
 	SoustractionVecteur(PlanDeGlissement\Normale, NouveauPointOrigine, Entity\PointIntersection)
	Normalise(@PlanDeGlissement\Normale)
	PlanDeGlissement\Constante = -(PlanDeGlissement\Normale\x*PlanDeGlissement\Origine\x+PlanDeGlissement\Normale\y*PlanDeGlissement\Origine\y+PlanDeGlissement\Normale\z*PlanDeGlissement\Origine\z)

	;Nouveau point de destination
	Longueur1.f=ProduitScalaire(@Pointdestination,@PlanDeGlissement\normale) + PlanDeGlissement\Constante
	SoustractionVecteur(NouveauPointDestination, PointDestination, Longueur1 * PlanDeGlissement\Normale)
  
	;Calcul la nouvelle vitesse (le long du plan de glissement)
  SoustractionVecteur(NouvelleVitesse, NouveauPointDestination, Entity\PointIntersection)
 
 	;Inutile de reboucler si la nouvelle vitesse est faible
 	If Longueur(@NouvelleVitesse) <= *World3D\DistanceTresFaible
  		CopieVecteur(*Reponse\PositionFinale, NouveauPointOrigine)
  		ProcedureReturn 
 	EndIf
	
 	*World3D\NombreRebouclage + 1
	;A voir si je garde la structure 
	*Reponse\PositionInitiale\x = NouveauPointOrigine\x
	*Reponse\PositionInitiale\y = NouveauPointOrigine\y
	*Reponse\PositionInitiale\z = NouveauPointOrigine\z
	*Reponse\Vitesse\x = NouvelleVitesse\x 
	*Reponse\Vitesse\y = NouvelleVitesse\y 
	*Reponse\Vitesse\z = NouvelleVitesse\z
 	
	 ReponseCollision(*Reponse,*World3D)
EndProcedure
ProcedureDLL GestionDeplacement1(*Entity.s_Collision,*World3D.s_WorldCollision)
	Protected PositionDansBaseE.Vecteur,	VitesseDansBaseE.Vecteur, PositionFinale.Vecteur
	
	;Calcul la position et la vitesse dans la base de l'Ellipsoide
	DivisionVecteur(PositionDansBaseE, *Entity\PositionDansR3, *Entity\RayonEllipsoide)
 	DivisionVecteur(VitesseDansBaseE , *Entity\VitesseDansR3 , *Entity\RayonEllipsoide)
 	
	;Gestion du déplacement
	*World3D\NombreRebouclage = 0
	Reponse.s_Reponse
	CopieVecteur(Reponse\PositionFinale ,PositionFinale)
	CopieVecteur(Reponse\PositionInitiale, PositionDansBaseE)
	CopieVecteur(Reponse\Vitesse,VitesseDansBaseE) 
	;Reponse\ListeTriangles=*Entity\ListeTriangles
	ReponseCollision(@Reponse,*World3D)
 
 	;Gestion de la gravité
  DivisionVecteur(VitesseDansBaseE, *World3D\gravite, *Entity\RayonEllipsoide)
  *World3D\NombreRebouclage = 0
  CopieVecteur(Reponse\PositionInitiale,Reponse\PositionFinale)
  CopieVecteur(Reponse\Vitesse,VitesseDansBaseE) 
  ReponseCollision(@Reponse,*World3D)

 	;Conversion de la position finale dans R3
 	MultiplicationVecteur(*Entity\PositionDansR3, Reponse\PositionFinale, *Entity\RayonEllipsoide)
EndProcedure
ProcedureDLL CreateListeTriangles(*Entity.s_Collision,*World3D.s_WorldCollision)
  Protected p2_p1.Vecteur,	p3_p1.Vecteur
  ;Génère un fichier contenant la liste des triangles
  If ReadFile(0,*World3D\FichierTriangles)
    *World3D\NbTriangles=ReadLong(0) 
    *World3D\ListeTriangles=AllocateMemory(SizeOf(Triangle) * *World3D\NbTriangles)
    *Ptr.Triangle=*World3D\ListeTriangles
    While Eof(0)=0
      ReadData(0,*Ptr,SizeOf(Triangle))
      *Ptr\P1\x / *Entity\RayonEllipsoide\x
      *Ptr\P1\y / *Entity\RayonEllipsoide\y
      *Ptr\P1\z / *Entity\RayonEllipsoide\z
      *Ptr\P2\x / *Entity\RayonEllipsoide\x
      *Ptr\P2\y / *Entity\RayonEllipsoide\y
      *Ptr\P2\z / *Entity\RayonEllipsoide\z
      *Ptr\P3\x / *Entity\RayonEllipsoide\x
      *Ptr\P3\y / *Entity\RayonEllipsoide\y
      *Ptr\P3\z / *Entity\RayonEllipsoide\z   
           
      ;Calcul le plan 
	    p2_p1\x = *Ptr\P2\x - *Ptr\P1\x
	    p2_p1\y = *Ptr\P2\y - *Ptr\P1\y
	    p2_p1\z = *Ptr\P2\z - *Ptr\P1\z
	    p3_p1\x = *Ptr\P3\x - *Ptr\P1\x
	    p3_p1\y = *Ptr\P3\y - *Ptr\P1\y
	    p3_p1\z = *Ptr\P3\z - *Ptr\P1\z

	    ProduitVectoriel(*Ptr\Normale,@p2_p1,@p3_p1)
	    Normalise(*Ptr\Normale)
	    *Ptr\Constante = -(*Ptr\Normale\x * *Ptr\P1\x + *Ptr\Normale\y * *Ptr\P1\y + *Ptr\Normale\z * *Ptr\P1\z)
      *Ptr + SizeOf(Triangle)
    Wend
    CloseFile(0) 
  EndIf	

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.
Répondre