Page 3 sur 14

Publié : dim. 27/nov./2005 12:35
par djes
Je n'ai que le sol et le ciel; la carte s'affiche correctement, c'est fluide, mais pas de murs!

Publié : dim. 27/nov./2005 12:52
par comtois
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.

Publié : dim. 27/nov./2005 13:48
par djes
J'ai une nvidia 6600. L'ancienne démo fonctionnait. Peut-être une histoire de sens des textures? Le sol est noir, seul le ciel est affiché.

Publié : dim. 27/nov./2005 15:23
par Polo
33 FPS (Geforce FX 5200)
Ben dis donc, tes collisions sont parfaites maintenant !!!
Euh, j'en peu plus, j'ai trop envie de voir comment tu as fait pour faire ça, quand je pense que j'ai séché la dessus pendant plusieurs mois :D

Publié : dim. 27/nov./2005 16:36
par comtois
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.

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

Publié : dim. 27/nov./2005 18:48
par comtois
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
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)
et avant j'avais ça :

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

Publié : dim. 27/nov./2005 19:13
par comtois
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

Publié : dim. 27/nov./2005 19:15
par Polo
ça m'a l'air sympa, je vais regarder :)
Merci beaucoup !

Publié : dim. 27/nov./2005 20:30
par comtois
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 :D

Publié : dim. 27/nov./2005 20:44
par Polo
comtois 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 :D
Ben, je peux bricoler en C, en C++ déjà beaucoup moins, et alors les sources de Quake :? :lol:
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 :)

Publié : dim. 27/nov./2005 20:54
par comtois
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

Code : Tout sélectionner

	ForEach ListTriangle()
  		TestCollision(@InfosCollision)
 	Next 
Faudrait faire la boucle directement dans la procédure TestCollision() ça évite d'appeler à chaque fois la procédure !!!

Code : Tout sélectionner

	;ForEach ListTriangle()
  		TestCollision(@InfosCollision)
 	;Next 
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).

Publié : dim. 27/nov./2005 21:07
par Polo
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 :)

Publié : lun. 28/nov./2005 21:08
par Polo
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 :oops:

Publié : mar. 29/nov./2005 16:21
par comtois
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 :)
Structures encapsulées ? lesquelles ? tu peux être plus précis sur le point qui te bloque ?


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 .

Publié : mar. 29/nov./2005 20:21
par Polo
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 ?