Code source complet -Collision 3D et réponse

Généralités sur la programmation 3D
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Comme je te l'ai dit dans le post précédent , la procédure TestCollision() retourne le point de collision et la distance la plus courte , donc déjà commence par faire ça ! inutile de traiter plusieurs collisions.
Sélectionne le point le plus proche , c'est le seul que tu as à traiter.
- Le nombre de collision
ça n'a aucun intérêt .
- Le point où les collisions se sont effectués
Voila , ça c'est utile :) , mais seulement le plus proche.
- Le point antérieur au déplacement qui a causé la collision
C'est ton point d'origine en clair ? donc oui , tu en as besoin.
- la normale du/des triangles ayant subis la collision.
Tu n'en as pas besoin pour la réponse ,tu devras calculer la normale du plan de glissement.

Donc tu as besoin :
-Du point de collision
-La distance de la Sphère au point de collision (pour replacer la sphère)
-L'origine de la sphère
-La vitesse

et rien d'autre.

Et là je recopie ce que j'ai écrit dans le post précédent , parce que je ne vois pas comment le dire autrement. Regarde aussi le code.

Si tu n'as pas de collision , tu te déplaces normalement ,*PositionInitiale c'est la position d'origine de ta sphère si tu préfères.

Code : Tout sélectionner

 	;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
Sinon dans ReponseCollision() dans le cas d'une collision:
- On se place au point de collision trouvé
Puisqu'on déplace notre sphère, on calcule son NouveauPointOrigine

Code : Tout sélectionner

 
        ;Initialise NouveauPointOrigine
	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
- On calcule le plan de glissement (il est tangent à la sphère au point de collision).
Il y a plusieurs façons de définir un plan (wikipédia)
Un plan est uniquement défini par :

* Trois points distincts et non alignés.
* Une droite et un point n'appartenant pas à cette droite.
* Deux droites non confondues et sécantes.
* Deux droites non confondues et parallèles.
* Un point et un vecteur normal.
Ici on utilise Un point et un vecteur normal.
- Le point , c'est le point de collision.
- La normale ,c'est le vecteur allant du point de collision au centre de la sphère , comme le rayon de la sphère est 1 , c'est inutile de normer le vecteur, je viens de m'apercevoir que je le faisais, je l'ai viré du code :)

Code : Tout sélectionner

 ;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)
- On en déduit la nouvelle vitesse en faisant une projection du point de destination initiale sur le plan de glissement.
Calcul du point de destination initiale

Code : Tout sélectionner

 	;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
Pour la projection du point de destination

Code : Tout sélectionner

	;Nouveau point de destination
Longueur.f=IntersectionRayonPlan(@Pointdestination,@PlanDeGlissement\Normale,@PlanDeGlissement)
	NouveauPointDestination\x = PointDestination\x + Longueur * PlanDeGlissement\Normale\x
 	NouveauPointDestination\y = PointDestination\y + Longueur * PlanDeGlissement\Normale\y
  	NouveauPointDestination\z = PointDestination\z + Longueur * PlanDeGlissement\Normale\z
Et finalement la nouvelle vitesse s'obtient ainsi :

Code : Tout sélectionner

	;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
- 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

Code : Tout sélectionner

Test si la vitesse est nulle (ou faible)
 	;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
On reboucle avec les nouveaux paramètres

Code : Tout sélectionner

 	ReponseCollision(*PositionFinale, @NouveauPointOrigine, @NouvelleVitesse)
Et ensuite tu as juste à placer ton Entity à la positionFinale.
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.
Polo
Messages : 612
Inscription : sam. 03/juil./2004 20:14

Message par Polo »

Merci pour toutes ces explications, je vais mettre ça en pratique quand j'aurai un petit moment, sinon, je ne vois pas trop la différence entre ces deux données :
-Du point de collision
-La distance de la Sphère au point de collision (pour replacer la sphère)
Parce que la sphère se trouve en toute logique sur le point de collision, avant de calculer la position ?
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

C'est là que nos méthodes diffèrent :)

On calcule le point de collision avant de déplacer la sphère.
Et on cherche une collision sur tout le parcours possible de la sphère.


Bon , j'avais commencé à rédiger un truc sur le sujet , faudrait que je le finisse et que je le mette en ligne .
C'est presque une traduction du tut de Fauerby .
Enfin , je ne cherche pas à traduire, mais plutôt à rédiger comme je l'ai compris , alors forcément je suis de très près son tut , il est plutôt bien fait.
Tu devrais le lire :lol:
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.
Polo
Messages : 612
Inscription : sam. 03/juil./2004 20:14

Message par Polo »

Je devrais le lire, t'as pas tord :)
Mais je comprend pas très bien en fait.
Comment tu peux trouver une collision "possible" si elle n'a pas lieu ?
Si jamais tu finis ton article, ça m'intéresse aussi :)
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Voila le début , C'est presque une traduction , comme je te le disais :

Après un changement de base vectorielle , on se ramène à une sphère S de rayon 1.
Notre sphère S d'origine S0(x0,y0,z0) se déplace dans la direction du vecteur Vitesse.

La sphère se déplace de son point d'origine S0 à S0+Vitesse ,on peut encore l'écrire sous cette forme :
S(t)=S0+t*Vitesse avec t inclu dans l'intervalle [0..1].
En effet pour:
t=0 S(0) = S0
t=1 S(1) = S0+1*Vitesse = S0+Vitesse

Il faut donc vérifier si la sphère entre en collision dans cet intervalle.
La sphère est en collision avec le plan si la distance de la sphère au plan est dans l'intervalle [-1..1] .

Maintenant, il nous reste à déterminer à quel moment distance = -1 et distance = 1.

La distance d'un point p à un plan se calcule ainsi (http://homeomath.imingo.net/displan.htm):
Distance = NormaleDuPlan.Point+Constante du plan (D=N.p+Cp)

1=N.p+Cp
Avec p=S0+t0*Vitesse,ce qui donne
1=N.S0+t0*(N.Vitesse)+Cp
N.S0+Cp correspond à la distance de l'origine de la sphère au plan :
1=t0*(N.Vitesse)+DistanceSpherePlan

On en déduit t0:
t0=1-DistanceSpherePlan/N.Vitesse

On fait la même chose pour calculer t1 donnant une distance =-1
t1=-1-DistanceSpherePlan/N.Vitesse

Si t0 et t1 se trouvent en dehors de cet intervalle , il n'y a pas de collision.

Remarque : Si la sphère se déplace parallèlement au plan : N.Vitesse est nul.
- Si la distance de la sphère au plan est dans l'intervalle [-1..1] alors la sphère est en collision avec le plan en permanence le long de son trajet (déplacement parallèle au plan).
soit t0=0 et t1=1.

- Sinon si la distance est en dehors de l'intervalle [-1..1] il n'y a pas de collision possible.

On connait dans quel intervalle [t0..t1] on sera en collision avec le plan , mais on ne sait pas encore comment notre sphère touche le triangle.

Il y a 4 possibilités

-Le point d'intersection se trouve à l'intérieur du triangle
-Le point d'intersection se trouve sur un des sommets du triangle
-Le point d'intersection se trouve le long d'une arête du triangle
-Il n'y a pas de point d'intersection avec le triangle
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.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Je vois qu'il y a pas mal de visites, tant mieux :)

Si jamais un visiteur de ce post trouvait des améliorations ou des corrections ,qu'il n'hésite pas à partager.

J'avais lu sur un autre forum que quelqu'un avait utilisé et amélioré mon ancien système de collision (BoxCollision) , c'est dommage qu'il ne nous montre pas comment il a fait.
Enfin , je n'oblige personne, c'est juste que j'apprécierais voir évoluer les codes que je donne, et ça rendrait service à beaucoup , moi le premier :)

Je cherche comment améliorer le glissement dans une jointure entre deux murs.Si l'angle entre les murs est à 90° ça se passe bien , par contre s'il est plus important , et que l'on se dirige dans la jointure , alors l'image devient trouble parce qu'on passe d'un mur à l'autre.Je ne sais pas si je suis clair :)

Si quelqu'un trouve comment corriger ce défaut , je suis preneur.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

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

Message par comtois »

Merci , j'avais utilisé le tut de Fauerby mais dans sa version anglaise , et comme j'ai du mal avec l'anglais , il y a peut-être des trucs qui m'ont échappés :)

Je vais jeter un oeil à la traduction , on ne sait jamais.

Merci à toi .

En attendant j'ai modifié un paramètre dans la procédure Reponse , ça ne broute plus , mais ça glisse moins , c'est pas vraiment gênant , c'est peut-être même mieux :)
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.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

3 demos 3D

Message par comtois »

Pour fêter la beta , voici 3 démos faisant usage des material script , un pure bonheur ces materials script :)

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


Je suis curieux de connaitre votre FPS , chez moi il est de 60 pour toutes les démos.
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.
CameleonTH
Messages : 333
Inscription : sam. 25/juin/2005 11:18
Localisation : Laon (02)
Contact :

Message par CameleonTH »

Euh chez moi sa marche pas ta démo ce me met une erreur, et c'est quoi les mateiral script.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

il faut que tu copies le fichier engine3D.dll et le fichier stlport_vc646.dll
Dans le même répertoire que les exe.

Le fichier stlport_vc646.dll se trouve ici

http://www.purebasic.com/beta/

Et le fichier engine3D.dll se trouve dans le répertoire Compiler de PureBasic.

Pour le material script je te renvoie à la doc :)

http://www.ogre3d.org/docs/manual/manual_15.html#SEC24
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.
CameleonTH
Messages : 333
Inscription : sam. 25/juin/2005 11:18
Localisation : Laon (02)
Contact :

Message par CameleonTH »

C'est bien fait, ta utiliser la version 4 pour faire sa?
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

ah oui , sans la version 4 c'était impossible à faire :)

J'avais déjà pas mal avancé avec la 3.94.
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.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

au fait , tu n'as pas donné ton FPS , ça tourne comment chez toi ?
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.
CameleonTH
Messages : 333
Inscription : sam. 25/juin/2005 11:18
Localisation : Laon (02)
Contact :

Message par CameleonTH »

Tu peut donner ta source, et un conseil change le fov de la camera car sa fait un effet de zoom et c'est desagrable. :D
Répondre