Code source complet -Collision 3D et réponse
Tu es le deuxième à me dire ça
Sami a le même problème que toi .
Tu as quoi comme carte graphique ?
et puis , dans l'autre démo tu les avais les murs ? je n'ai rien changé .
Ah si , je sais ce que j'ai changé , avant j'avais un seul mesh pour tous les murs, mais ça ne me permet pas de calculer les textures pour chaque mur, je suis obligé d'avoir un calcul unique ,et donc si on pose un grand mur on obtient une texture floue.
Dans la dernière démo , j'ai créé un mesh pour chaque mur , comme ça je fais en sorte d'avoir une texture proportionnelle à la taille du mur.
mais ça fait beaucoup de mesh et autant d'entity (environ 90) , je ne connais pas les limites des cartes.

Sami a le même problème que toi .
Tu as quoi comme carte graphique ?
et puis , dans l'autre démo tu les avais les murs ? je n'ai rien changé .
Ah si , je sais ce que j'ai changé , avant j'avais un seul mesh pour tous les murs, mais ça ne me permet pas de calculer les textures pour chaque mur, je suis obligé d'avoir un calcul unique ,et donc si on pose un grand mur on obtient une texture floue.
Dans la dernière démo , j'ai créé un mesh pour chaque mur , comme ça je fais en sorte d'avoir une texture proportionnelle à la taille du mur.
mais ça fait beaucoup de mesh et autant d'entity (environ 90) , je ne connais pas les limites des cartes.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
bon voici la première version , je la colle ici , ça me fera une sauvegarde , ça m'embêterait de perdre ce code 
Pour la démo , il y a deux codes, voici le fichier principal , celui qui contient l'ensemble des procédures , l'autre contient les procédures pour construire la map et la boucle principale, c'est moins important.
Voila , tu peux constater que j'ai suivi à la lettre le tut de Fauerby.
Bien entendu si vous trouvez des améliorations ,des erreurs , etc, je suis preneur.

Pour la démo , il y a deux codes, voici le fichier principal , celui qui contient l'ensemble des procédures , l'autre contient les procédures pour construire la map et la boucle principale, c'est moins important.
Voila , tu peux constater que j'ai suivi à la lettre le tut de Fauerby.
Bien entendu si vous trouvez des améliorations ,des erreurs , etc, je suis preneur.
Code : Tout sélectionner
;Comtois - Collision Glissante le 09/12/05
;PB 3.94 avec la beta 1.03 d'ogre
;- Constantes
#Hauteur = 64
#Echelle = 1
#CameraSpeed = 4
#Epsilon=0.0001
; Liste des meshes possibles
#PB_Mesh_Vertex = 1 << 0
#PB_Mesh_Color = 1 << 1
#PB_Mesh_Normal = 1 << 2
#PB_Mesh_UVCoordinate = 1 << 3
;Additionnnal flag To specify the faces
#PB_Mesh_Face = 1 << 4
;- Les structures
Declare MakeMesh(No.l,U,V)
Structure Vertex
px.f
py.f
pz.f
nx.f
ny.f
nz.f
U.f
V.f
EndStructure
Structure Parametres
AngleX.f
AngleY.f
AngleZ.f
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
Origine.Vecteur
Normale.Vecteur
EndStructure
Structure Face
Point.Point3D[4]
EndStructure
Structure Sommet
No.l
X.l
Y.l
EndStructure
Structure Segment
Sommet1.l
x1.l
Y1.l
Sommet2.l
x2.l
Y2.l
Long.l ; Longueur d'un segment ( pour le calcul du chemin le plus court d'un sommet à un autre )
EndStructure
Structure s_Collision
RayonEllipsoide.vecteur ; Rayon de l'ellipsoide
;Informations sur le déplacement dans le monde R3
VitesseDansR3.Vecteur
PositionDansR3.Vecteur
;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
Global NombreDeRebouclage.l
Global Gravite.Vecteur
Global RayonEllipsoide.Vecteur
Global SphereI
Global TirA.Vecteur
NewList ListTriangle.Triangle()
NewList Sommet.Sommet()
NewList Segment.Segment()
Global Camera.Parametres
;-Les procédures
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 > #Epsilon And t1 < maxR
*Solution\f = t1
ProcedureReturn #True
EndIf
If t2 > #Epsilon And t2 < maxR
*Solution\f = t2
ProcedureReturn #True
EndIf
;Pas de solution
ProcedureReturn #False
EndProcedure
Procedure TestCollision(*Sphere.s_Collision)
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
Protected *p1.Vecteur, *p2.Vecteur, *p3.Vecteur
ForEach ListTriangle()
;A revoir , c'est pas utile de tout recopier , je pourrais utiliser directement la liste chainée ?
PlanTriangle\Normale\x=ListTriangle()\normale\x
PlanTriangle\Normale\y=ListTriangle()\normale\y
PlanTriangle\Normale\z=ListTriangle()\normale\z
PlanTriangle\Origine\x=ListTriangle()\Origine\x
PlanTriangle\Origine\y=ListTriangle()\Origine\y
PlanTriangle\Origine\z=ListTriangle()\Origine\z
PlanTriangle\Constante=ListTriangle()\Constante
*p1=ListTriangle()\p1
*p2=ListTriangle()\p2
*p3=ListTriangle()\p3
;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 = 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
temp.f = t1
t1 = t0
t0 = temp
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,*p1,*p2,*p3))
TriangleEnCollision = #True
;Mémorise t et Le point en collision le plus proche
t = t0
PointCollision\x = PointIntersectionSurLePlan\x
PointCollision\y = PointIntersectionSurLePlan\y
PointCollision\z = PointIntersectionSurLePlan\z
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
Sphere_p1\x = *Sphere\PointOrigine\x - *p1\x
Sphere_p1\y = *Sphere\PointOrigine\y - *p1\y
Sphere_p1\z = *Sphere\PointOrigine\z - *p1\z
p1_Sphere\x = *p1\x - *Sphere\PointOrigine\x
p1_Sphere\y = *p1\y - *Sphere\PointOrigine\y
p1_Sphere\z = *p1\z - *Sphere\PointOrigine\z
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
PointCollision\x = *p1\x
PointCollision\y = *p1\y
PointCollision\z = *p1\z
EndIf
;p1 -> p2:
Arete\x = *p2\x-*p1\x
Arete\y = *p2\y-*p1\y
Arete\z = *p2\z-*p1\z
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
PointCollision\x = *p1\x + f * Arete\x
PointCollision\y = *p1\y + f * Arete\y
PointCollision\z = *p1\z + f * Arete\z
EndIf
EndIf
;P2
Sphere_p2\x = *Sphere\PointOrigine\x - *p2\x
Sphere_p2\y = *Sphere\PointOrigine\y - *p2\y
Sphere_p2\z = *Sphere\PointOrigine\z - *p2\z
p2_Sphere\x = *p2\x - *Sphere\PointOrigine\x
p2_Sphere\y = *p2\y - *Sphere\PointOrigine\y
p2_Sphere\z = *p2\z - *Sphere\PointOrigine\z
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
PointCollision\x = *p2\x
PointCollision\y = *p2\y
PointCollision\z = *p2\z
EndIf
;p2 -> p3:
Arete\x = *p3\x-*p2\x
Arete\y = *p3\y-*p2\y
Arete\z = *p3\z-*p2\z
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
PointCollision\x = *p2\x + f * Arete\x
PointCollision\y = *p2\y + f * Arete\y
PointCollision\z = *p2\z + f * Arete\z
EndIf
EndIf
;P3
Sphere_p3\x = *Sphere\PointOrigine\x - *p3\x
Sphere_p3\y = *Sphere\PointOrigine\y - *p3\y
Sphere_p3\z = *Sphere\PointOrigine\z - *p3\z
p3_Sphere\x = *p3\x - *Sphere\PointOrigine\x
p3_Sphere\y = *p3\y - *Sphere\PointOrigine\y
p3_Sphere\z = *p3\z - *Sphere\PointOrigine\z
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
PointCollision\x = *p3\x
PointCollision\y = *p3\y
PointCollision\z = *p3\z
EndIf
;p3 -> p1:
Arete\x = *p1\x-*p3\x
Arete\y = *p1\y-*p3\y
Arete\z = *p1\z-*p3\z
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
PointCollision\x = *p3\x + f * Arete\x
PointCollision\y = *p3\y + f * Arete\y
PointCollision\z = *p3\z + f * Arete\z
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
*Sphere\PointIntersection\x=PointCollision\x
*Sphere\PointIntersection\y=PointCollision\y
*Sphere\PointIntersection\z=PointCollision\z
*Sphere\CollisionDetectee = #True
EndIf
EndIf
Next
EndProcedure
Procedure ReponseCollision(*PositionFinale.Vecteur, *PositionInitiale.Vecteur, *Vitesse.Vecteur)
Protected PlanDeGlissement.Plan, InfosCollision.s_Collision
Protected PointDestination.Vecteur, NouveauPointOrigine.Vecteur
Protected V.Vecteur, NouveauPointDestination.Vecteur, NouvelleVitesse.Vecteur
DistanceTresFaible.f = 0.005
;Limite le rebouclage
If (NombreDeRebouclage>5)
*PositionFinale\x = *PositionInitiale\x
*PositionFinale\y = *PositionInitiale\y
*PositionFinale\z = *PositionInitiale\z
ProcedureReturn
EndIf
;Stocke les informations nécessaires au test de collision
InfosCollision\VitesseDansBaseE\x = *Vitesse\x
InfosCollision\VitesseDansBaseE\y = *Vitesse\y
InfosCollision\VitesseDansBaseE\z = *Vitesse\z
InfosCollision\VitesseDansBaseENormee\x = *Vitesse\x
InfosCollision\VitesseDansBaseENormee\y = *Vitesse\y
InfosCollision\VitesseDansBaseENormee\z = *Vitesse\z
Normalise(@InfosCollision\VitesseDansBaseENormee)
InfosCollision\PointOrigine\x = *PositionInitiale\x
InfosCollision\PointOrigine\y = *PositionInitiale\y
InfosCollision\PointOrigine\z = *PositionInitiale\z
InfosCollision\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(@InfosCollision)
;Il n'y a pas de collision, on peut se déplacer normalement
If InfosCollision\CollisionDetectee = #False
*PositionFinale\x = *PositionInitiale\x + *Vitesse\x
*PositionFinale\y = *PositionInitiale\y + *Vitesse\y
*PositionFinale\z = *PositionInitiale\z + *Vitesse\z
ProcedureReturn
EndIf
;Calcul le point de destination ( comme s'il n'y avait pas de collision)
PointDestination\x = *PositionInitiale\x + *Vitesse\x
PointDestination\y = *PositionInitiale\y + *Vitesse\y
PointDestination\z = *PositionInitiale\z + *Vitesse\z
NouveauPointOrigine\x = *PositionInitiale\x
NouveauPointOrigine\y = *PositionInitiale\y
NouveauPointOrigine\z = *PositionInitiale\z
;On se replace un peu avant le point de d'intersection calculé dans TestCollision()
If InfosCollision\DistanceLaPlusCourte > DistanceTresFaible
V\x = *Vitesse\x
V\y = *Vitesse\y
V\z = *Vitesse\z
LongueurVecteur(@V, InfosCollision\DistanceLaPlusCourte - 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)
InfosCollision\PointIntersection\x - DistanceTresFaible * V\x
InfosCollision\PointIntersection\y - DistanceTresFaible * V\y
InfosCollision\PointIntersection\z - DistanceTresFaible * V\z
EndIf
;Determine le plan de glissement
PlanDeGlissement\Origine\x = InfosCollision\PointIntersection\x
PlanDeGlissement\Origine\y = InfosCollision\PointIntersection\y
PlanDeGlissement\Origine\z = InfosCollision\PointIntersection\z
PlanDeGlissement\Normale\x = NouveauPointOrigine\x - InfosCollision\PointIntersection\x
PlanDeGlissement\Normale\y = NouveauPointOrigine\y - InfosCollision\PointIntersection\y
PlanDeGlissement\Normale\z = NouveauPointOrigine\z - InfosCollision\PointIntersection\z
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
NouveauPointDestination\x = PointDestination\x - Longueur1 * PlanDeGlissement\Normale\x
NouveauPointDestination\y = PointDestination\y - Longueur1 * PlanDeGlissement\Normale\y
NouveauPointDestination\z = PointDestination\z - Longueur1 * PlanDeGlissement\Normale\z
;Calcul la nouvelle vitesse (le long du plan de glissement)
NouvelleVitesse\x = NouveauPointDestination\x - InfosCollision\PointIntersection\x
NouvelleVitesse\y = NouveauPointDestination\y - InfosCollision\PointIntersection\y
NouvelleVitesse\z = NouveauPointDestination\z - InfosCollision\PointIntersection\z
;Inutile de reboucler si la nouvelle vitesse est faible
If Longueur(@NouvelleVitesse) <= DistanceTresFaible
*PositionFinale\x = NouveauPointOrigine\x
*PositionFinale\y = NouveauPointOrigine\y
*PositionFinale\z = NouveauPointOrigine\z
ProcedureReturn
EndIf
NombreDeRebouclage + 1
ReponseCollision(*PositionFinale, @NouveauPointOrigine, @NouvelleVitesse)
EndProcedure
Procedure GestionDeplacement(*InfosCollision.s_Collision)
Protected PositionDansBaseE.Vecteur, VitesseDansBaseE.Vecteur, PositionFinale.Vecteur
;Calcul la position et la vitesse dans la base de l'Ellipsoide
PositionDansBaseE\x = *InfosCollision\PositionDansR3\x / *InfosCollision\RayonEllipsoide\x
PositionDansBaseE\y = *InfosCollision\PositionDansR3\y / *InfosCollision\RayonEllipsoide\y
PositionDansBaseE\z = *InfosCollision\PositionDansR3\z / *InfosCollision\RayonEllipsoide\z
VitesseDansBaseE\x = *InfosCollision\VitesseDansR3\x / *InfosCollision\RayonEllipsoide\x
VitesseDansBaseE\y = *InfosCollision\VitesseDansR3\y / *InfosCollision\RayonEllipsoide\y
VitesseDansBaseE\z = *InfosCollision\VitesseDansR3\z / *InfosCollision\RayonEllipsoide\z
;Gestion du déplacement
NombreDeRebouclage = 0
ReponseCollision(@PositionFinale, @PositionDansBaseE, @VitesseDansBaseE)
;Gestion de la gravité
VitesseDansBaseE\x = gravite\x / *InfosCollision\RayonEllipsoide\x
VitesseDansBaseE\y = gravite\y / *InfosCollision\RayonEllipsoide\y
VitesseDansBaseE\z = gravite\z / *InfosCollision\RayonEllipsoide\z
NombreDeRebouclage = 0
ReponseCollision(@PositionFinale, @PositionFinale, @VitesseDansBaseE)
;Conversion de la position finale dans R3
*InfosCollision\PositionDansR3\x = PositionFinale\x * *InfosCollision\RayonEllipsoide\x
*InfosCollision\PositionDansR3\y = PositionFinale\y * *InfosCollision\RayonEllipsoide\y
*InfosCollision\PositionDansR3\z = PositionFinale\z * *InfosCollision\RayonEllipsoide\z
EndProcedure
Dernière modification par comtois le ven. 09/déc./2005 20:40, modifié 2 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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
et ça c'est le code principal .Je voulais ajouter des cibles à exploser et améliorer la viser de la caméra, mais ça sera pour une autre fois.
J'ai ajouté un plafond dans cette version .
Mettez le fichier que vous voulez à la place de celui-ci
Ceux qui avaient des soucis avec la démo , vous avez tout le code pour voir ce qui cloche chez vous .
Ce qui a changé , c'est dans la procédure MakeEntity
J'ai ça
et avant j'avais ça :
J'ai ajouté un plafond dans cette version .
Mettez le fichier que vous voulez à la place de celui-ci
LoadTexture(9,"Plafond_U5_01.jpg")
Ceux qui avaient des soucis avec la démo , vous avez tout le code pour voir ce qui cloche chez vous .
Ce qui a changé , c'est dans la procédure MakeEntity
J'ai ça
Code : Tout sélectionner
;Ajoute une entity par segment
NoEntity + 1
Delta.f=#Hauteur/1.0
Dx.f=SX/Delta
If Dx<1
dx=1
EndIf
MakeMesh(NoEntity,Dx,SY/Delta)
CreateEntity(NoEntity,MeshID(NoEntity),MaterialID(1+Random(4)))
EntityLocate(NoEntity,PX,#Hauteur/2,PZ)
ScaleEntity(NoEntity,SX,SZ,SY)
RotateEntity(NoEntity, Angle,90,0)
Code : Tout sélectionner
;Ajoute une entity par segment
NoEntity + 1
CreateEntity(NoEntity,MeshID(1),MaterialID(1+Random(4)))
EntityLocate(NoEntity,PX,#Hauteur/2,PZ)
ScaleEntity(NoEntity,SX,SZ,SY)
RotateEntity(NoEntity, Angle,90,0)
Code : Tout sélectionner
;Comtois le 09/12/05
;PB 3.94 et ogre 1.03
;Je me suis grandement inspiré du tutoriel de Fauerby http://www.peroxide.dk
XIncludeFile "VisuMap4DFR.pbi"
;-Initialisation
#ScreenWidth = 800 : #ScreenHeight = 600 : #ScreenDepth = 32
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 PlateForme" ) = 0
MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
End
EndIf
Add3DArchive("Textures" , #PB_3DArchive_FileSystem)
Add3DArchive("Textures\Skybox.zip", #PB_3DArchive_Zip)
;-Mesh
M3D_CreateMesh(0,#M3D_Cube)
M3D_CreateMesh(1,#M3D_Plain)
M3D_CreateMesh(2,#M3D_Sphere)
;- Textures
LoadTexture(1,"Mur_U3_01.jpg")
LoadTexture(2,"Mur_U3_05.jpg")
LoadTexture(3,"Mur_U3_06.jpg")
LoadTexture(4,"Mur_U3_07.jpg")
LoadTexture(5,"Mur_U3_08.jpg")
LoadTexture(6,"Mur_U3_08.jpg")
LoadTexture(7,"Sol_m_01.jpg")
LoadTexture(8,"Sol_U2_01.jpg")
LoadTexture(9,"Plafond_U5_01.jpg")
;- Material
For i = 1 To 9
CreateMaterial(i, TextureID(i))
Next i
;- Camera
CreateCamera(0, 0, 0 , 100 , 100)
CameraFOV(0,45)
AmbientColor(RGB(215,215,215))
;-Les procédures
Procedure Renum()
ForEach Sommet()
No = Sommet()\No
Sommet()\No = ListIndex(Sommet())
ForEach Segment()
If Segment()\Sommet1 = No
Segment()\Sommet1 = Sommet()\No
ElseIf Segment()\Sommet2 = No
Segment()\Sommet2 = Sommet()\No
EndIf
Next
Next
EndProcedure
Procedure Charge()
If ReadFile(0,"Sommets.hd")=0 : End : EndIf
ClearList(Sommet())
While Eof(0)=0
AddElement(Sommet())
Sommet()\No = ReadLong()
Sommet()\X = ReadLong()
Sommet()\Y = ReadLong()
Wend
CloseFile(0)
ReadFile(0,"Segment.hd")
ClearList(Segment())
While Eof(0)=0
AddElement(Segment())
Segment()\Sommet1 = ReadLong()
Segment()\x1 = ReadLong()
Segment()\Y1 = ReadLong()
Segment()\Sommet2 = ReadLong()
Segment()\x2 = ReadLong()
Segment()\Y2 = ReadLong()
x1 = Segment()\x1
Y1 = Segment()\Y1
x2 = Segment()\x2
Y2 = Segment()\Y2
Segment()\Long = Sqr(Pow(x1-x2,2)+Pow(Y1-Y2,2))
Wend
CloseFile(0)
Renum()
EndProcedure
Procedure AffSegment(Aff)
StartDrawing(ScreenOutput())
If aff
ForEach Segment()
LineXY(Segment()\X1,Segment()\Y1,Segment()\X2,Segment()\Y2,RGB(255,255,255))
Next
Circle(CameraX(0),CameraZ(0),RayonEllipsoide\x-1,RGB(55,55,255))
Else
;Le viseur
DrawingMode(4)
Circle(400,300,16,RGB(255,255,255))
Line(395,300,10,0,RGB(255,255,255))
Line(400,295,0,10,RGB(255,255,255))
EndIf
DrawText("FPS : " + Str(Engine3DFrameRate(#PB_Engine3D_Current)))
StopDrawing()
EndProcedure
Procedure MakePlan()
Protected p2_p1.Vecteur, p3_p1.Vecteur
p2_p1\x = ListTriangle()\P2\x - ListTriangle()\P1\x
p2_p1\y = ListTriangle()\P2\y - ListTriangle()\P1\y
p2_p1\z = ListTriangle()\P2\z - ListTriangle()\P1\z
p3_p1\x = ListTriangle()\P3\x - ListTriangle()\P1\x
p3_p1\y = ListTriangle()\P3\y - ListTriangle()\P1\y
p3_p1\z = ListTriangle()\P3\z - ListTriangle()\P1\z
ProduitVectoriel(@ListTriangle()\Normale,@p2_p1,@p3_p1)
Normalise(@ListTriangle()\Normale)
ListTriangle()\Origine\x = ListTriangle()\P1\x
ListTriangle()\Origine\y = ListTriangle()\P1\y
ListTriangle()\Origine\z = ListTriangle()\P1\z
ListTriangle()\Constante = -(ListTriangle()\Normale\x * ListTriangle()\Origine\x + ListTriangle()\Normale\y * ListTriangle()\Origine\y + ListTriangle()\Normale\z * ListTriangle()\Origine\z)
EndProcedure
Procedure MakeTriangles(*Surface.Face)
;Pour chaque plan , on a deux triangles , voici le premier
AddElement(ListTriangle())
ListTriangle()\P1\x=*Surface\Point[0]\x / RayonEllipsoide\x
ListTriangle()\P1\y=*Surface\Point[0]\y / RayonEllipsoide\y
ListTriangle()\P1\z=*Surface\Point[0]\z / RayonEllipsoide\z
ListTriangle()\P2\x=*Surface\Point[2]\x / RayonEllipsoide\x
ListTriangle()\P2\y=*Surface\Point[2]\y / RayonEllipsoide\y
ListTriangle()\P2\z=*Surface\Point[2]\z / RayonEllipsoide\z
ListTriangle()\P3\x=*Surface\Point[3]\x / RayonEllipsoide\x
ListTriangle()\P3\y=*Surface\Point[3]\y / RayonEllipsoide\y
ListTriangle()\P3\z=*Surface\Point[3]\z / RayonEllipsoide\z
MakePlan()
;Et voici le second
AddElement(ListTriangle())
ListTriangle()\P1\x=*Surface\Point[0]\x / RayonEllipsoide\x
ListTriangle()\P1\y=*Surface\Point[0]\y / RayonEllipsoide\y
ListTriangle()\P1\z=*Surface\Point[0]\z / RayonEllipsoide\z
ListTriangle()\P2\x=*Surface\Point[1]\x / RayonEllipsoide\x
ListTriangle()\P2\y=*Surface\Point[1]\y / RayonEllipsoide\y
ListTriangle()\P2\z=*Surface\Point[1]\z / RayonEllipsoide\z
ListTriangle()\P3\x=*Surface\Point[2]\x / RayonEllipsoide\x
ListTriangle()\P3\y=*Surface\Point[2]\y / RayonEllipsoide\y
ListTriangle()\P3\z=*Surface\Point[2]\z / RayonEllipsoide\z
MakePlan()
EndProcedure
Procedure MakeEntity()
Protected Surface.Face
;Ellipsoide de la caméra
RayonEllipsoide\x = 13.0
RayonEllipsoide\y = 26.0
RayonEllipsoide\z = 13.0
NoEntity = 10 ; Reserve les 10 premières entitys
ForEach Segment()
;Calcul les caractéristiques de l'entity
Adjacent.f = (Segment()\x1 - Segment()\x2)
Oppose.f = (Segment()\Y1 - Segment()\Y2)
Hypothenuse.f = Sqr(Adjacent*Adjacent + Oppose*Oppose)
Angle.f = ACos(Adjacent/Hypothenuse)/0.0174533
If Segment()\Y1 > Segment()\Y2
Angle = 360 - Angle
EndIf
SX.f = (Segment()\Long)
SY.f = #Hauteur
SZ.f = 0
PX.f = ((Segment()\x1 + Segment()\x2) /2.0)
PZ.f = ((Segment()\Y1 + Segment()\Y2) /2.0)
;Ajoute une entity par segment
NoEntity + 1
Delta.f=SY/1.0
Dx.f=SX/Delta
If Dx<1
dx=1
EndIf
MakeMesh(NoEntity,Dx,SY/Delta)
CreateEntity(NoEntity,MeshID(NoEntity),MaterialID(1+Random(4)))
EntityLocate(NoEntity,PX,#Hauteur / 2,PZ)
ScaleEntity(NoEntity,SX,SZ,SY)
RotateEntity(NoEntity, Angle,90,0)
;Pour chaque segment il faut créer deux triangles
Surface\Point[0]\x=Segment()\x1
Surface\Point[0]\y=#Hauteur
Surface\Point[0]\z=Segment()\y1
Surface\Point[1]\x=Segment()\x2
Surface\Point[1]\y=#Hauteur
Surface\Point[1]\z=Segment()\y2
Surface\Point[2]\x=Segment()\x2
Surface\Point[2]\y=0.0
Surface\Point[2]\z=Segment()\y2
Surface\Point[3]\x=Segment()\x1
Surface\Point[3]\y=0.0
Surface\Point[3]\z=Segment()\y1
MakeTriangles(@Surface)
Next
;Ajoute un sol
Surface\Point[0]\x=0.0
Surface\Point[0]\y=0.0
Surface\Point[0]\z=0.0
Surface\Point[1]\x=800.0
Surface\Point[1]\y=0.0
Surface\Point[1]\z=0.0
Surface\Point[2]\x=800.0
Surface\Point[2]\y=0.0
Surface\Point[2]\z=600.0
Surface\Point[3]\x=0.0
Surface\Point[3]\y=0.0
Surface\Point[3]\z=600.0
MakeTriangles(@Surface)
For j = 1 To 6
For i = 1 To 8
NoEntity + 1
CreateEntity(NoEntity,MeshID(1),MaterialID(8))
ScaleEntity(NoEntity, 100, 1, 100)
EntityLocate(NoEntity, 100 * i - 50, 0 , 100 * j - 50)
Next i
Next j
;Un Plafond
For j = 1 To 6
For i = 1 To 8
NoEntity + 1
CreateEntity(NoEntity,MeshID(1),MaterialID(9))
ScaleEntity(NoEntity, 100, 1, 100)
EntityLocate(NoEntity, 100 * i - 50, #Hauteur, 100 * j - 50)
Next i
Next j
;Les escaliers
NbMarche = 8
HauteurEscalier.f = 9.0
LargeurEscalier.f = 53.0
ProfondeurEscalier.f = 32.0
EscalierX.f = 299
EscalierZ.f = 218+40
For i=1 To NbMarche
Surface\Point[0]\x=EscalierX - LargeurEscalier / 2
Surface\Point[0]\y=i * HauteurEscalier
Surface\Point[0]\z=EscalierZ + i * ProfondeurEscalier - ProfondeurEscalier / 2
Surface\Point[1]\x=EscalierX + LargeurEscalier / 2
Surface\Point[1]\y=i * HauteurEscalier
Surface\Point[1]\z=EscalierZ + i * ProfondeurEscalier - ProfondeurEscalier / 2
Surface\Point[2]\x=EscalierX + LargeurEscalier / 2
Surface\Point[2]\y=i * HauteurEscalier
Surface\Point[2]\z=EscalierZ + i * ProfondeurEscalier + ProfondeurEscalier / 2
Surface\Point[3]\x=EscalierX - LargeurEscalier / 2
Surface\Point[3]\y=i * HauteurEscalier
Surface\Point[3]\z=EscalierZ + i * ProfondeurEscalier + ProfondeurEscalier / 2
MakeTriangles(@Surface)
NoEntity + 1
CreateEntity(NoEntity,MeshID(0),MaterialID(7))
ScaleEntity(NoEntity, LargeurEscalier, HauteurEscalier * i, ProfondeurEscalier)
EntityLocate(NoEntity, EscalierX, i * HauteurEscalier - HauteurEscalier*i/2, EscalierZ + i * ProfondeurEscalier)
Next i
;Pour visualiser le tir
SphereI= NoEntity + 1
CreateEntity(SphereI,MeshID(2),MaterialID(7))
ScaleEntity(SphereI, 3, 3, 3)
EndProcedure
;/
;-La boucle principale
;/
Charge()
MakeEntity()
PasX.f=0.0
PasZ.f=0.0
InfosNinja.s_Collision
;Position de déPart
InfosNinja\PositionDansR3\x = 200
InfosNinja\PositionDansR3\y = 26
InfosNinja\PositionDansR3\z = 300
InfosNinja\VitesseDansR3\x = 0.0
InfosNinja\VitesseDansR3\y = 0.0
InfosNinja\VitesseDansR3\z = 0.0
InfosNinja\RayonEllipsoide\x=RayonEllipsoide\x
InfosNinja\RayonEllipsoide\y=RayonEllipsoide\y
InfosNinja\RayonEllipsoide\z=RayonEllipsoide\z
CameraLocate(0,InfosNinja\PositionDansR3\x, InfosNinja\PositionDansR3\y + RayonEllipsoide\y , InfosNinja\PositionDansR3\z)
CameraLookAt(0,InfosNinja\PositionDansR3\x + M3D_Cos(Camera\AngleX) * 80, InfosNinja\PositionDansR3\y + RayonEllipsoide\y ,InfosNinja\PositionDansR3\z - M3D_Sin(Camera\AngleX ) * 80)
Gravite\y=-#CameraSpeed
Gravite\x=0
Gravite\z=0
modeaff=1
MouseX.f
MouseY.f
Repeat
ClearScreen(0, 0, 0)
If ExamineMouse()
MouseX = -(MouseDeltaX()/10)*#CameraSpeed/2
MouseY = -(MouseDeltaY()/10)*#CameraSpeed/2
If MouseButton(1)
Tir=1
EntityLocate(SphereI,InfosNinja\PositionDansR3\x, InfosNinja\PositionDansR3\y, InfosNinja\PositionDansR3\z)
TirA\x=M3D_Cos(Camera\AngleX) * 2
TirA\y=M3D_Sin(Camera\AngleY) * 2
TirA\z=-M3D_Sin(Camera\AngleX) * 2
EndIf
EndIf
If ExamineKeyboard()
If KeyboardReleased(#PB_Key_F1) : Aff2D = 1 - Aff2D : EndIf
; Touches du joueur
Camera\AngleX = M3D_WrapValue( Camera\AngleX + MouseX)
RotateCamera(0,MouseX,0,0)
If MouseY > 0 And Camera\AngleY < 25
Camera\AngleY + MouseY
RotateCamera(0,0,MouseY,0)
ElseIf MouseY < 0 And Camera\AngleY > -25
Camera\AngleY + MouseY
RotateCamera(0,0,MouseY,0)
EndIf
If KeyboardPushed(#PB_Key_Left)
InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX+90) * #CameraSpeed
InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX+90) * #CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Right)
InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX-90) * #CameraSpeed
InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX-90) * #CameraSpeed
EndIf
If KeyboardPushed(#PB_Key_Up)
InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX) * #CameraSpeed
InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX) * #CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Down)
InfosNinja\VitesseDansR3\x + M3D_Cos(Camera\AngleX) * -#CameraSpeed
InfosNinja\VitesseDansR3\z - M3D_Sin(Camera\AngleX) * -#CameraSpeed
EndIf
If KeyboardPushed(#PB_Key_Space)
EndIf
EndIf
If NormeAuCarre(@InfosNinja\VitesseDansR3)>#CameraSpeed * #CameraSpeed
LongueurVecteur(@InfosNinja\VitesseDansR3,#CameraSpeed)
EndIf
GestionDeplacement(@InfosNinja)
CameraLocate(0,InfosNinja\PositionDansR3\x, InfosNinja\PositionDansR3\y, InfosNinja\PositionDansR3\z)
InfosNinja\VitesseDansR3\x = 0.0
InfosNinja\VitesseDansR3\z = 0.0
If tir=1
MoveEntity(SphereI,TirA\x,TirA\y,TirA\z)
EndIf
RenderWorld()
AffSegment(Aff2D)
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Procedure MakeMesh(No,U,V)
If CreateMesh(No)
*Ptr.Vertex=AllocateMemory(SizeOf(Vertex)*4)
*Mem.Vertex = *Ptr
*Mem\px=-0.5
*Mem\py=0
*Mem\pz=-0.5
*Mem\nx=0
*Mem\ny=1
*Mem\nz=0
*Mem\U=0
*Mem\V=0
*Mem+SizeOf(Vertex)
*Mem\px=-0.5
*Mem\py=0
*Mem\pz=0.5
*Mem\nx=0
*Mem\ny=1
*Mem\nz=0
*Mem\U=0
*Mem\V=V
*Mem+SizeOf(Vertex)
*Mem\px=0.5
*Mem\py=0
*Mem\pz=0.5
*Mem\nx=0
*Mem\ny=1
*Mem\nz=0
*Mem\U=U
*Mem\V=V
*Mem+SizeOf(Vertex)
*Mem\px=0.5
*Mem\py=0
*Mem\pz=-0.5
*Mem\nx=0
*Mem\ny=1
*Mem\nz=0
*Mem\U=U
*Mem\V=0
Flag = #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate
SetMeshData(No,Flag ,*Ptr,4)
SetMeshData(No,#PB_Mesh_face,?IndexPlain,4)
ProcedureReturn *Ptr
Else
ProcedureReturn 0
EndIf
EndProcedure
DataSection
IndexPlain:
Data.w 0,1,2
Data.w 2,3,0
Data.w 2,1,0
Data.w 0,3,2
EndDataSection
Dernière modification par comtois le ven. 09/déc./2005 20:38, 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.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
je ne pensais pas le faire ce soir , mais pendant que c'est chaud, je viens de faire une archive qui contient tout , les textures ;les exe, et les codes sources.
http://perso.wanadoo.fr/comtois/sources ... ssante.zip
http://perso.wanadoo.fr/comtois/sources ... ssante.zip
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Tiens toi qui bricole en C ou C++ , tu ne pourrais pas jeter un oeil dans les sources de Quake3 pour récupérer la gestion des collisions BSP et nous en faire une petite lib ?? ou quelqu'un d'autre , je ne suis pas contrariant 

http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Ben, je peux bricoler en C, en C++ déjà beaucoup moins, et alors les sources de Quakecomtois a écrit :Tiens toi qui bricole en C ou C++ , tu ne pourrais pas jeter un oeil dans les sources de Quake3 pour récupérer la gestion des collisions BSP et nous en faire une petite lib ?? ou quelqu'un d'autre , je ne suis pas contrariant


Mais en fait, leur source ne doivent pas être si intéressante que ça, je veux dire, en gros, ça fait la même chose que ce que tu as programmé, la seule différence (considérable, quand même), c'est que les collisions ne se font que dans des zones bien définie, c'est avantageux lorsqu'on a bcp d'objets.
Le problème, c'est que, si je me souviens bien, le format BSP contient les zones, pré calculées, et donc, si ton niveau n'est pas un fichier BSP, ça sert à rien

Et le format BSP a plein d'incovénient, je crois qu'il est protégé en plus, bref...

D'ailleurs, c'est marrant, en ce moment, j'essaye de faire une fonction qui teste la visibilité d'un objet par la caméra, c'est chaud à faire !! Mais c'est quand même une fonction vachement utile

Mais j'avoue que je patauge un peu, dès que quelque chose est lié aux maths, c'est dur

j'avais prévu d'ajouter une fonction LancerRayon() pour tester si un tir atteint son objectif , et si un tir atteint son objectif , c'est qu'il ne rencontre pas de mur, et donc que l'objet est visible, bon , un seul rayon c'est pas beaucoup pour de la vision , mais pour faire un essai , ça ira 
sinon je savais bien que j'avais balancé le code trop tôt , je viens de penser à une optimisation
Dans la procédure ReponseCollision()
on a
Faudrait faire la boucle directement dans la procédure TestCollision() ça évite d'appeler à chaque fois la procédure !!!
et dans la procédure TestCollision() il suffit de remplacer les ProcedureReturn par des Continue ,et voila, je ne sais pas si on gagne du FPS avec ça , moi je suis à fond déjà ( la fréquence de mon écran).

sinon je savais bien que j'avais balancé le code trop tôt , je viens de penser à une optimisation
Dans la procédure ReponseCollision()
on a
Code : Tout sélectionner
ForEach ListTriangle()
TestCollision(@InfosCollision)
Next
Code : Tout sélectionner
;ForEach ListTriangle()
TestCollision(@InfosCollision)
;Next
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Ben, moi, avec ton exemple, je suis à 33 FPS, bon, je n'ai pas une bête de course, hein 
De plus, c'est toujours mieux de dépasser la fréquence de l'écran, enfin, je veux dire, si tu arrives à avoir 100 FPS, c'est mieux que 75, car sur un ordi moins puissant, ça ne ramera pas
Je continue à potasser ma commande, moi

De plus, c'est toujours mieux de dépasser la fréquence de l'écran, enfin, je veux dire, si tu arrives à avoir 100 FPS, c'est mieux que 75, car sur un ordi moins puissant, ça ne ramera pas

Je continue à potasser ma commande, moi

comptois, je vais faire mon chieur, mais est ce que tu pourrais m'expliquer ce que tu fais pour obtenir les réponses de la collision ? Ton code est assez barbare, avec toutes ces structures encapsulées 
Parce qu'en fait, j'ai déjà une routine de collision qui marche (et qui est probablement similaire à la tienne, celle que j'ai faite traine sur mon pc depuis pas mal de temps, mais comme j'ai jamais réussi à faire les réponses

Parce qu'en fait, j'ai déjà une routine de collision qui marche (et qui est probablement similaire à la tienne, celle que j'ai faite traine sur mon pc depuis pas mal de temps, mais comme j'ai jamais réussi à faire les réponses

Structures encapsulées ? lesquelles ? tu peux être plus précis sur le point qui te bloque ?Polo a écrit :comptois, je vais faire mon chieur, mais est ce que tu pourrais m'expliquer ce que tu fais pour obtenir les réponses de la collision ? Ton code est assez barbare, avec toutes ces structures encapsulées
Bon voici le principe :
GestionDeplacement() permet de convertir la position et la vitesse dans la base vectorielle de l'ellipsoide , ça permet ensuite de travailler avec une sphère de rayon 1 dans la procédure TestCollision() et ReponseCollision().
La procédure ReponseCollision() est récursive, elle appelle d'abord TestCollision() pour savoir si un triangle est en collision , et si c'est le cas , TestCollision() renvoie le point d'intersection le plus proche .
Ensuite dans ReponseCollision() dans le cas d'une collision:
- On se place au point de collision trouvé
- On calcule le plan de glissement (il est tangeant à la sphère au point de collision).
- On en déduit la nouvelle vitesse en faisant une projection du point de destination initiale sur le plan de glissement.
- On Reboucle avec les nouveaux paramètres que l'on vient de calculer ,à savoir la nouvelle position et le nouveau vecteur vitesse , jusqu'à ce que la vitesse soit nulle .
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Non, en fait, ce qui me bloque, c'est que tu gère les collisions ou plus généralement les déplacements d'une manière qui n'est pas très familière à la mienne 
Bon, en fait, pour faire simple, moi, j'ai moins de donnée que toi, disons que quand je fais un test de collision, j'ai ça :
- Le nombre de collision
- Le point où les collisions se sont effectués
- Le point antérieur au déplacement qui a causé la collision
- la normale du/des triangles ayant subis la collision.
C'est tout je crois, je suis pas sûr remarque
Bon, donc, j'ai tout ça, j'ai détecté que j'ai une ou plusieurs collisions, maintenant, je veux calculer la nouvelle position, ce que tu fais je crois dans ta procédure ReponseCollision.
En gros, sans vouloir t'en demander trop
, je fais quoi à partir de ce moment, avec les données du bord ?

Bon, en fait, pour faire simple, moi, j'ai moins de donnée que toi, disons que quand je fais un test de collision, j'ai ça :
- Le nombre de collision
- Le point où les collisions se sont effectués
- Le point antérieur au déplacement qui a causé la collision
- la normale du/des triangles ayant subis la collision.
C'est tout je crois, je suis pas sûr remarque

Bon, donc, j'ai tout ça, j'ai détecté que j'ai une ou plusieurs collisions, maintenant, je veux calculer la nouvelle position, ce que tu fais je crois dans ta procédure ReponseCollision.
En gros, sans vouloir t'en demander trop
