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