PDA

Voir la version complète : Utiliser la detection de collision dans un programme coffee



s.liszewski
30/06/2007, 16h28
Bonjour,

je souhaite utiliser la fonction xpresso de détection des collisions à l'intérieur d'un programme coffee.
Est-ce possible ? Comment ? Existe-t-il une fonction coffee qui fait plus ou moins la même chose ?

Je sais que je peux intégrer un programme coffee dans une feuille xpresso, mais dans ce cas je rencontre un autre problème :
mon programme coffee détermine les entrées de la fonction xpresso (les 2 objets en collision ou non, jusque la tout va bien) mais doit également recevoir le résultat de cette fonction de détection. Ceci implique de faire une boucle fermée en xpresso, ce qui s'avère être impossible (ou alors je ne sais pas comment le faire) ...

merci de votre aide sur cette question délicate (pour moi en tout cas :oops: )

Jean-Laurent
01/07/2007, 08h34
Salut. :odile:

De mémoire (mais elle n'est pas très bonne) je dirais que la fonction n'existe pas en coffee.

Par contre, pour la deuxième méthode il ne devrait pas y avoir de problème.

Tu utilises le noeud détection, avec tes deux objets et tu récupéres le résultats dans une entrée du noeud coffee.
Le noeud coffee peut avoir autant d'entrées que nécessaire.
En l'occurence, tu peux en avoir ici trois. Deux pour les objets, et une pour le résultat de la collision.

Il faudrait être un peu plus précis sur ce que tu souhaites faire.
Si ça se trouve l'utilisation du coffee n'est pas nécessaire, ou au contraire, tout peut se faire facilement en coffee. :odile:

s.liszewski
01/07/2007, 13h56
merci pour ta réponse :efface:

En fait mon problème est que le programme COFFEE determine aussi l'entrée du noeud de collision

http://s.liszewski.free.fr/Architecture/Xpresso.jpg

C'est à dire que la sortie "Collision" du module de détection des collisions doit être reliée à l'entrée "Input1" de module COFFEE
Apparement ca n'est pas possible (on fait une boucle ce qui ne doit pas être permis)

Sinon mon but est de créer un programme qui desactive les arbres Xfrog qui sont contenus dans un volume quelconque, pour soulager mon ordinateur pour des projets pleins d'arbres.
Par exemple je veux pouvoir créer un volume englobant la motier de ma scène et désactiver tous les arbres présents dedans

L'essentiel est fait mais je bloque sur la partie : est-ce qu'un arbre est présent dans le volume ?

po facile...

tarlack
01/07/2007, 14h06
le volume ca sera toujours une boite parallélépipédique ou ca peut etre une forme quelconque ?

Jean-Laurent
01/07/2007, 14h41
L'essentiel est fait mais je bloque sur la partie : est-ce qu'un arbre est présent dans le volume ?
po facile...


:o

Tient. Curieux. C'est la partie qui me semble la plus simple.
C'est sans doute pour ça que tarlack te pose la question.
Si le volume est une boîte ça se fait en deux coups de cuillère à pot en coffee sans utiliser le noeud détection.

Je ne vois pas trop l'intérêt d'un volume plus complexe pour ce que tu veux faire, mais pourquoi pas.

Il faudrait que tu précises ce que fait ton noeud coffee avec les objets.
Eventuellement donne nous le code si c'est possible.
Normalement ta boucle peut être placée dans le noeud coffee.

base80
01/07/2007, 16h03
Pas besoin de collisions pour détecter si un objet est dans une boite.
Il suffi de comparer la position de l'arbre par rapport a la surface de la boite.

Donc si position de l'arbre est entre x1 et x2 et entre z1 et z2 l'arbre doit être désactivé

non?

D'ailleurs pas besoin de coffee pour un truc pareil

tarlack
01/07/2007, 16h31
si t'es en 3D avec une boiboite (parallelepipedique) orientée n'importe comment, c'est un peu différent : (je parie que JL a encore plus simple que ce que je vais dire)
t'as besoin d'un point de la boite qui servira de centre d'un repere, et des 3 points qui sont connectés à ce point par une arête. soit O le point que t'as choisi, A, B et C les 3 autres (on se fiche de l'ordre), et X la position de ton arbre.

tu calcules les 3 choses suivantes :
(A - O | X - O) / (norme(A - O)^2) (coffee a des fonctions pour tout ca il me semble)
(B - O | X - O) / (norme(B - O)^2)
(C - O | X - O) / (norme(A - O)^2)

si au moins une des trois valeurs n'est pas entre 0 et 1 (inclus), ton arbre est pas dans la boite.

j'ai bon JL ?

Jean-Laurent
01/07/2007, 19h30
j'ai bon JL ?


A vu d'oeil je dirais non. :mrgreen:

Tout dépend ce que tu notes (A - O | X - O) , mais si c'est un rapport, il y a un problème. :wink:

Il faudrait plus de précisions.
Comme le dit base, avec les calques, ou tout un tas d'autres trucs on peut même éviter le coffee.

Sinon, si c'est une boite, le plus simple est de la matérialiser par un cube.
Récupérer la position, la hauteur, la largeur et la longueur du cube en coffee (3 lignes de code)
et voir si les arbres sont dedans.
On peut même faire tourner le cube en rajoutant un ou deux sinus s'il le faut.

tarlack
01/07/2007, 21h24
c'est un produit scalaire, notation (presque) habituelle. tout ce que je fais c'est une projection sur les 3 axes du repère, et je verifie que le point a des coordonnées entre 0 et 1 selon les 3 axes.

s.liszewski
01/07/2007, 23h32
merci à tous pour vos réponses :poucehaut:

je pense que je vais utiliser un truc assez simple genre produit scalaire...

Sinon j'utilise COFFEE parce que je veux pouvoir insérer des arbres de manière simple, qu'ils soient reconnus comme tels et pouvoir ensuite activer le niveau de branchage voulu (pour ceux qui connaissent xfrog)

pour info voila mon code :

RechercheAlentour(Obj,NomCherche) // Cherche un objet donné dans la hierarchie
{
var Nom=Obj->GetName();
if (Nom==NomCherche) return Obj;

var ObjDown=Obj->GetDown();
if (ObjDown){
var Retour = RechercheAlentour(ObjDown,NomCherche);
if (Retour!=Null) return Retour;}

var ObjNext=Obj->GetNext();
if (ObjNext){
var Retour = RechercheAlentour(ObjNext,NomCherche);
return Retour;}

return Null;
}

Niveau0(Tronc,On){
Tronc->SetDeformMode(On);
}
Niveau1(Branche1,On){
if (Branche1) Branche1->SetDeformMode(On);
}
Niveau2(Branche2,Branche2b,Branche2c,On){
if (Branche2) Branche2->SetDeformMode(On);
if (Branche2b) Branche2b->SetDeformMode(On);
if (Branche2c) Branche2c->SetDeformMode(On);
}
Niveau3(Branche3,Branche3b,Branche3c,Branche4,leaf 1,On){
if (Branche3) Branche3->SetDeformMode(On);
if (Branche3b) Branche3b->SetDeformMode(On);
if (Branche3c) Branche3c->SetDeformMode(On);
if (Branche4) Branche4->SetDeformMode(On);
if (leaf1) leaf1->SetDeformMode(On);
}

ReductionDetails(Tronc, Niveau)
{
var Branche1=RechercheAlentour(Tronc,"b1");
var Branche2=RechercheAlentour(Tronc,"b2");
var Branche2b=RechercheAlentour(Tronc,"b2b");
var Branche2c=RechercheAlentour(Tronc,"b2c");
var Branche3=RechercheAlentour(Tronc,"b3");
var Branche3b=RechercheAlentour(Tronc,"b3b");
var Branche3c=RechercheAlentour(Tronc,"b3c");
var Branche4=RechercheAlentour(Tronc,"b4");
var leaf1=RechercheAlentour(Tronc,"leaf1");

if (Niveau==0){
Niveau0(Tronc,1);
Niveau1(Branche1,1);
Niveau2(Branche2,Branche2b,Branche2c,1);
Niveau3(Branche3,Branche3b,Branche3c,Branche4,leaf 1,1);}
if (Niveau==1){
Niveau0(Tronc,0);
Niveau1(Branche1,1);
Niveau2(Branche2,Branche2b,Branche2c,1);
Niveau3(Branche3,Branche3b,Branche3c,Branche4,leaf 1,1);}
if (Niveau==2){
Niveau0(Tronc,0);
Niveau1(Branche1,0);
Niveau2(Branche2,Branche2b,Branche2c,1);
Niveau3(Branche3,Branche3b,Branche3c,Branche4,leaf 1,1);}
if (Niveau==3){
Niveau0(Tronc,0);
Niveau1(Branche1,0);
Niveau2(Branche2,Branche2b,Branche2c,0);
Niveau3(Branche3,Branche3b,Branche3c,Branche4,leaf 1,1);}
if (Niveau==4){
Niveau0(Tronc,0);
Niveau1(Branche1,0);
Niveau2(Branche2,Branche2b,Branche2c,0);
Niveau3(Branche3,Branche3b,Branche3c,Branche4,leaf 1,0);}

Tronc->SetName("trunkModif");

}

main()
{
var doc=GetActiveDocument();

var Tronc=doc->FindObject("trunkModif");
while (Tronc){
Tronc->SetName("trunk");
Tronc=doc->FindObject("trunkModif");
}

var Tronc=doc->FindObject("trunk");
while (Tronc){
ReductionDetails(Tronc, NiveauDesact);
Tronc=doc->FindObject("trunk");
}

Tronc=doc->FindObject("trunkModif");
while (Tronc){
Tronc->SetName("trunk");
Tronc=doc->FindObject("trunkModif");
}

}


pas très compliqué mais pas trop documenté non plus :oops:

base80
01/07/2007, 23h41
Ça me fait bien rire les français dans du code, c'est tellement plus pittoresque

while (Tronc){
Tronc->SetName("trunk");

s.liszewski
01/07/2007, 23h46
Ça me fait bien rire les français dans du code, c'est tellement plus pittoresque

while (Tronc){
Tronc->SetName("trunk");




lol :wink:
et en plus parfois c'est plus pratique, ca évite de tomber sur des fonctions du langage

Jean-Laurent
02/07/2007, 09h42
c'est un produit scalaire, notation (presque) habituelle. tout ce que je fais c'est une projection sur les 3 axes du repère, et je verifie que le point a des coordonnées entre 0 et 1 selon les 3 axes.


Alors c'est juste. :oops:
Maintenant que tu le dis, je n'ai plus utilisé cette notation depuis la fin de mes études.
Du temps où je faisais encore de l'algèbre. En physique quantique ça prend un autre sens.
En physique le scalaire le plus souvent n'est pas représenté, et les vecteurs sont notés en lettres grasses.
Plus sournoisement, lors d'opérations plus compliquées le produit scalaire est noté X, avec alors une confusion possible avec le produit vectoriel.
Je raisonnais en projection et trouvais ta formule louche. :oops:

Sinon je comprends mieux ton problème liszewski, et ce que tu entends par désactiver les arbres.

tarlack
02/07/2007, 15h59
c'est les "ket" (état quantique d'un objet ?) chez vous ? il me semble avoir croisé ce mot associé à un machin ayant cette notation dans un document obscur que je lisais dans le noir... :mrgreen:

base : et encore, c'est possible de faire pire :mrgreen:

base80
02/07/2007, 16h43
$prout ...

s.liszewski
04/07/2007, 19h30
S'il y en a que ca intéresse, il faut à mon avis plutot utilisé le produit vectoriel

ici le but est de savoir si un point "P" se trouve dans un triangle "Objet"
voila le code

vectoriel(Vect1,Vect2) // Produit vectoriel en 2 dimensions
{
var a=Vect1.x*Vect2.z-Vect2.x*Vect1.z;
return a;
}

main()
{

var pointsObjet=Objet->GetPoints();
var P1=pointsObjet[0];
var P2=pointsObjet[1];
var P3=pointsObjet[2];

var P=Point->GetPosition();

var a=vectoriel(P3-P1,P-P1);
var b=vectoriel(P-P1,P2-P1);
var c=vectoriel(P-P2,P3-P2);

}

le point est dans le triangle si et seulement si a, b et c sont positifs

merci à tous pour votre aide :D

serge

Jean-Laurent
05/07/2007, 16h41
Je suis d'autant plus intéressé que je ne comprends pas comment ça marche. :oops:



ici le but est de savoir si un point "P" se trouve dans un triangle "Objet"


Un triangle "objet" ?
Un trièdre associé à un objet ?



vectoriel(Vect1,Vect2) // Produit vectoriel en 2 dimensions


Au passage, le produit vectoriel existe en coffee. On peut l'utiliser directement et récupérer la composante qui nous intéresse (ici x apparemment, mais je ne sais pas pourquoi?) ou la norme.

Je ne vois pas très bien ce qu'est un produit vectoriel en 2 dimensions ?



var a=vectoriel(P3-P1,P-P1);
var b=vectoriel(P-P1,P2-P1);
var c=vectoriel(P-P2,P3-P2);
}

le point est dans le triangle si et seulement si a, b et c sont positifs


C'est là que je suis le plus perdu.
P1,P2 et P3 sont les vecteurs associés aux coordonnées des points de la boite ?
Dans ce cas là, il faut bien les choisir, non? Il faut avoir un trièdre direct.

a,b,c ne peuvent pas être positifs seulement si les coordonnées de P sont positives par rapport au trièdre ?

Le produit scalaire me semblait plus simple, mais bon, si ça marche. :wink:

tarlack
05/07/2007, 17h12
y a encore plus simple si tu veux savoir si t'es dans un triangle. Tu calcules les coordonnées barycentriques (u,v) du point dans ton triangle, et le point est dedans si u <= 1 et u+v <= 1

s.liszewski
05/07/2007, 23h09
Jean Laurent,

le produit vectoriel permet de savoir si un point est au dessous ou au dessus d'une droite (caractérisée par un vecteur), selon le signe du produit vectoriel (on est en 2d, la seule composante non nulle du produit vectoriel est la composante verticale)
ici pour un triangle ABC, on verifie que le point est au dessus de AB, au dessous de AC et au dessous de BC.

j'ai abandonné l'idée de la boite au profit d'un plan : si l'abre est audessus, on l'active, s'il n'est pas au dessus je ne l'active pas.
Le but est de diviser un plan quelconque en triangle et de vérifier pour chanque triangle sur le point est dessus

P1, P2 et P3 sont les coordonnées des points du triangle a vérifier


ca fonctionne bien pour n'importe quel surface, même composée de plusieurs triangles. Si tu veux le fichier je le mettrais...

tarlak, effectivement j'y avait pas pensé, mais bon ca n'est pas beaucoup plus simple :roll: