PDA

Voir la version complète : Ray collision en coffee ?



clemz
09/07/2009, 15h55
Hellolo les loulous

je souhaiterais savoir si il est possible de faire un effet similaire au noeud expresso ' ray collision ' . afin de pouvoir placer un objet toujours sur la surface d'un mesh en fait .

merki d'avance :odile:

clem

Eric Smit
09/07/2009, 16h33
Salut petit loulou,

Pourquoi n'utilises-tu pas un tag "Constraint" (Clamp > To : Surface) ?

clemz
09/07/2009, 17h02
Salut petit loulou,

Pourquoi n'utilises-tu pas un tag "Constraint" (Clamp > To : Surface) ?



salut Skymaster ;)

bein en fait c'est une "petite" fonction que je souhaite ajouter à un code existant plus gros .. je veux si possible pas utiliser de tag ou expresso annexes ... ( en gros ce code fait bouger les controlleurs de pieds d'un rig , mais j'ai aussi besoin qu'il place (ou du moins me donne l'info) ces controlleurs sur le sol . Si j'ai par exemple un point A , j'aimerais bien avoir un point A' , projeté de A sur le mesh/sol ..comme ça je peux positionner mon controlleur sur A' .. (pour l'instant je le positionne sur A , en attendant ça )

paspas
09/07/2009, 17h08
salut


je souhaiterais savoir si il est possible de faire un effet similaire au noeud expresso ' ray collision ' . afin de pouvoir placer un objet toujours sur la surface d'un mesh en fait .

c est un problème mathématique donc oui :mrgreen:
j avais pour m amusé testé fait un petit coffee qui le faisait

mathématiquement si tu as l' équation d un plan ( le polygone concerné ici ) et que tu a l' équation de la ligne qui le traverse tu sait trouvé le point commun des deux en résolvant la matrice

le souci que j ai eu et que j ai tj d 'ailleurs c est que le plan etait infini et j ai tj pas trouvé comment le résoudre a un triangle précis

en fait ce que je n arrive pas a fair c' est comment on divise mathématiquement un quadrangle en deux triangle

si tu veut le code de ce que j' avait deja trouvé fait moi signe

paspas

clemz
09/07/2009, 17h30
haaa super Paspas is in the place 8)

ouep biensur que je suis interessé par ton code :mrgreen: ( c'est pas dit que je comprenne tout cela dit )

en fait je pensais projeter "verticalement" les pieds jusqu'à intersection avec quelque chose ? tu penses que c'est faisable ?
quand je dis verticalement , c'est par rapport à l'orientation du controlleur principal du perso ( si on définit comme vertical , l'axe up du perso ) ..donc si le perso joue a superman et monte sur un mur , et donc le perso est a l'horisontal , son "up" sera à l'horisontal , et la projection des pieds se fera à l'horisontal aussi , sens opposé . Je sais pas si je suis très clair là :lol: . je peux faire une tite vid si c'est pas clair.

merci
clem

paspas
09/07/2009, 17h43
en fait je pensais projeter "verticalement" les pieds jusqu'à intersection avec quelque chose ? tu penses que c'est faisable ?
c'est par rapport à l'orientation du controlleur principal du perso


si tu a une orientaion c' est a dire soit un axe ou ( deux point ) c' est faisable , le souci est
dans intersection avec quelque chose
c est definir ce quelque chose , comme je disait plus haut il ne me manque que comment touver sur une maille le poly ou se trouve l' intersection ,
si j arrive a savoir comment on fait pour déterminer mathématiquement les deux triangles qui forme le polygone j' ai ce qu il te faut :mrgreen:


paspas

clemz
09/07/2009, 18h41
ouep , jai l'orientation des controlleurs de pieds deja ^^ . si je veux choisir juste une projection sur leur Y ?

je viens de faire un test rapido en expresso :

test RayCollision (http://kiteclem35.free.fr/3D/C4D/RayCollision.avi) 5mo avi Xvid

voila en gros ce que je souhaiterais :) . avoir le projeté vert sur le sol là

http://kiteclem35.free.fr/3D/C4D/RayCollision%20test.jpg

..mais en coffee :cry2: :mrgreen:

clemz
10/07/2009, 13h14
noboudy a une idée pliiize :oops: ?

paspas
10/07/2009, 14h16
je tai envoyer par mp le code si ca peut t aider ,

paspas

clemz
10/07/2009, 14h59
merci Paspas , je regarde ça !! :bounce: :odile:

edit : ok ayé j'ai zieuté :poucehaut: ( bon j'ai pas tout tout saisi encore :mrgreen: mais le principe fonctionne bien )

par contre là ça fonctionne qu'avec un polygone ? , donc si je veut travailler avec un mesh ça complique la donne ça nan ? ^^

paspas
10/07/2009, 16h24
par contre là ça fonctionne qu'avec un polygone ? , donc si je veut travailler avec un mesh ça complique la donne ça nan ? ^^
oui et non :oops:

compliqué non , comme je disait plus haut , si je trouve comment diviser mathématiquement un quadrangle en deux triangle par une de ses diagonal le reste est une histoire de condition et boucle qui n est pas insurmontable


paspas

clemz
10/07/2009, 16h46
oué je comprends :)

hmmm n'y aurait-il pas moyen alors de definir une suite de triangles en prenant 2 arêtes cote à cote , avec 1 point commun ? enfin je dis ça c'est pas tres clair pour moi là deja ^^.. qu'est -ce qu'on a en coffee comme fonction pour les arêtes ?
j'ai vu qu'on a GetPointCount() etc mais pour les arêtes :?:

( j'ai demandé à Maxon si ils pouvaient rajouter une class Ray collision en coffee .. avec un peu de chances dans 5 ans on l'aura :mrgreen: )

edit :
je pensais à un autre truc sinon : si par exemple on a un vecteur qui descend sur Y- à l'infini donc ( ou une droite Y- Y+ sur le controlleur ) et que l'on prend chaque point du mesh . Pour chaque point, on calcule sa distance ortho à la droite , et donc on garde seulement les 3 points dont la distance sera la plus petite . est-ce que l'on n'a pas défini le plan ( triangle ) de collision là ? même pour moi là ça ne me parait presque pas insurmontable :lol:

et donc là on utilise ta fonction d'intersection plan/droite Paspas ? :)

(cas exceptionnel : la droite passerait par un point du mesh ^^ .. crotte pfff .. la droite tu sorts :arrow: )

oli_d
10/07/2009, 18h03
C'est vrai que c'est dommage que ces fonctions basiques ne soient pas disponibles en COFFEE, alors qu'elles le sont en Xpresso et en C++.

Avant de goûter au C++ j'avais tenté de faire des fonctions pour ce genre de truc. C'est faisable en algorithme naif, mais après pour optimiser c'est autre chose, surtout quand tu as des maillages important ....

Personnellement je combinerais quand même noeuds Xpresso "Ray Collision" et noeuds COFFEE pour utiliser l'algorithme à la sauce MAXON ...

clemz
10/07/2009, 19h14
C'est vrai que c'est dommage que ces fonctions basiques ne soient pas disponibles en COFFEE, alors qu'elles le sont en Xpresso et en C++.

Avant de goûter au C++ j'avais tenté de faire des fonctions pour ce genre de truc. C'est faisable en algorithme naif, mais après pour optimiser c'est autre chose, surtout quand tu as des maillages important ....

Personnellement je combinerais quand même noeuds Xpresso "Ray Collision" et noeuds COFFEE pour utiliser l'algorithme à la sauce MAXON ...


salut Oli_D :) . oué Coffee est assez limité des fois :cry: . oui c'est peut-être la solution de la dernière chance , d'utiliser expresso pour les raycollisions .

:odile:

oli_d
10/07/2009, 23h05
Au cas ou tu voudrais tester des formules géométriques j'ai enfin retrouvé le lien sur ce site qui est une mine d'or : http://local.wasp.uwa.edu.au/~pbourke/geometry/

Je te mets un code que j'avais fait en COFFEE pour l'intersection d'un plan et d'une ligne fait d'après ces formules, il faut mettre le tag sur un objet polygonal avec au moins trois points, en premier enfant une spline qui représente le rayon, et en deuxième enfant l'objet à mettre à l'intersection (cela doit ressembler au code de paspas je suppose) :



NormalPlan (pt1,pt2,pt3)
{
//d'après : http://local.wasp.uwa.edu.au/~pbourke/geometry/planeeq/

var norm =new(array,4);
norm[0] = pt1.y*(pt2.z-pt3.z)+pt2.y*(pt3.z-pt1.z)+pt3.y*(pt1.z-pt2.z);
norm[1] = pt1.z*(pt2.x-pt3.x)+pt2.z*(pt3.x-pt1.x)+pt3.z*(pt1.x-pt2.x);
norm[2] = pt1.x*(pt2.y-pt3.y)+pt2.x*(pt3.y-pt1.y)+pt3.x*(pt1.y-pt2.y);
norm[3]= -(pt1.x*(pt2.y*pt3.z-pt3.y*pt2.z)+pt2.x*(pt3.y*pt1.z-pt1.y*pt3.z)+pt3.x*(pt1.y*pt2.z-pt2.y*pt1.z));
return norm;
}

IntersectionLignePlan(norm,pt1,pt2)
{
// d'après : http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
// pt1 et pt2 représente la ligne normPlan la normale d'un plan (voir fonction ci dessus)

var u= (norm[0]*pt1.x+norm[1]*pt1.y+norm[2]*pt1.z+norm[3])/(norm[0]*(pt1.x-pt2.x)+norm[1]*(pt1.y-pt2.y)+norm[2]*(pt1.z-pt2.z));
var ptInt= vector(0,0,0);
ptInt=pt1+u*(pt2-pt1);
return ptInt;
}


main(doc,op)
{
var i,n=0;
if (!instanceof(op,PolygonObject))return;
var sp = op->GetDown();
if (!sp ) return;
if (!instanceof(sp,SplineObject))return;
var obj=sp->GetNext();
if(!obj)
{
obj = new(NullObject);
doc->InsertObject(obj,op,sp);
}

var nbPtPoly = op->GetPointCount();
var nbPtSp =sp->GetPointCount();
if (nbPtPoly < 3)
{
TextDialog("Le polygone doit contenir au moins trois points");
return;
}
if(nbPtSp<2)
{
TextDialog("La spline doit contenir au moins deux points");
return;
}
var ptPoly=new(array,3);
for(i=0;i<3;i++)
{
ptPoly[i]=op->GetPoint(i);
}
var ptSp = new(array,2);
for (i=0;i<2;i++)
{
ptSp[i]=sp->GetPoint(i);
}

var plan = new(array,4);

plan = NormalPlan(ptPoly[0],ptPoly[1],ptPoly[2]);
var ptInt=IntersectionLignePlan(plan,ptSp[0],ptSp[1]);

obj#ID_BASEOBJECT_POSITION= ptInt;
}

Donc avant tout ça il faudrait trouver le polygone avec lequel ton rayon intersecte avec la formule "Inside / outside polygon test" : http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ ....

Bon c'est pas le tout, mais j'arrive pas à mettre les aspirines en pièces jointes.... :coup:

clemz
11/07/2009, 00h16
waouw merci Oli_D ! :bounce: . Paspas aussi m'a montré un code similaire ! merci à vous 2 :prie:
et Jean-Laurent m'a dit qu'il réfléchissait à ça aussi , merci à lui aussi d'avance :love:

( Robert de plugincafe ( Kuroyume ) m'a envoyé un code C++ de ray colider , mais là je comprends pas grand choseen C++ :mrgreen: ... )

je zieute ton lien ! merci ;)

clem

oli_d
11/07/2009, 08h26
( Robert de plugincafe ( Kuroyume ) m'a envoyé un code C++ de ray colider , mais là je comprends pas grand chose en C++ Mr. Green ... )

Si tu veux te lancer dans le C++, tu peux trouver un autre exemple d'utilisation de la ici avec "LandPaint" : http://www.frenchcinema4d.fr/forum/index.php?topic=21966.0 ( Code source (http://campus.hesge.ch/eil/e-eil/od/landpaint/landpaint_source.zip)) + évidemment la doc SDK C++ sous reference/libraries/Collider library

oli_d
11/07/2009, 09h48
J'ai fait un petit Xpresso combiné avec du COFFEE pour montrer le principe (je pense que tu maitrises, mais c'est toujours intéressant pour les débutants de trouver ce genre d'exemple)

( le fichier C4D (http://campus.hesge.ch/eil/e-eil/od/collision_rayon.zip))

Il y a deux DU dans le tag Xpresso qui place l'objet "tagué" sur l'objet cible selon la collision avec les deux premier point de la spline rayon. S'il n'y a pas de collision l'objet est caché.

Il est clair que l'on peut (plus) facilement faire tout en Xpresso, mais c'est vraiment pour montrer le principe d'interaction COFFEE/XPRESSO. Le code peut ensuite être complexifié à volonté !

Malheureusement avec cette méthode on ne peut pas créer de "véritables" plugins qui impressionnent les filles et qui s'affichent dans un menu et tout ça ...

EDIT : Eh eh j'avais pas vu mais c'est mon 100 ème message :bounce: ! (en 5 ans, je sais c'est pas exceptionnel ! :mrgreen:)

Jean-Laurent
11/07/2009, 10h48
Donc avant tout ça il faudrait trouver le polygone avec lequel ton rayon intersecte avec la formule "Inside / outside polygon test" :


C'est ça le problème. Si on trouve ça et qu'on peut récupérer les coordonnées des points. Ou la coordonnée d'un point et de la normale c'est dans la poche. :poucehaut:

tarlack
11/07/2009, 13h14
faire ce que tu veux de manière optimisée c'est faire un moteur de lancer de rayons...autant dire que c'est coton quand on en a jamais fait, mais c'est faisable en construisant une structure acceleratrice quelconque sur le maillage et en lancant les rayons dedans...

regardez du côté des BVH (Bounding Volume Hierarchy) avec des volumes englobants constitués de boites englobantes alignées aux axes (AABB, Axis Aligned Bounding Box), c'est pas trop compliqué ni trop long à construire et ca marche très bien tant que les triangles sont de taille relativement homogène, et au pire ca a des perfs tout de même tout à fait acceptables.
Ce site a l'air vachement bien, y a meme les algos :

http://www.cs.utah.edu/~bes/papers/fastRT/paper.html

À noter que la structure d'acceleration doit etre construite le moins souvent possible, ca peut couter cher si le nombre de polys est important...après y a des algos pour les mettre à jour (refitting, selective restructuring), qui marchent plus ou moins bien...

bon courage !

clemz
11/07/2009, 14h44
super ! :) merci à vous . je zieute ton exemple Oli_D

c'est vrai que je pensais pas que "descendre simplement le controlleur sur une surface" serait si compliqué :mrgreen: . si c'est pas possible tanpis hein , c'était un bonus dans le code , mais là c'est tout le reste qui semble être un bonus ^^ .

:odile:

clemz
04/08/2010, 18h51
saluche ,

je me permets de ressortir un peu ce topic car j'ai de nouveau besoin d'un truc un peu similaire en fait :

je voudrais trouver l'intersection d'un plan formé par 2 axes d'une matrice ( par ex ici V2 et V3 ) et d'une spline ( en fait ici ma spline est droite donc ça pourrait être un simple vecteur , mais je vais avoir besoin de pouvoir utiliser une B-spline (courbe en 3 points) aussi donc là faut que je passe par l'objet spline et non un vecteur j'imagine .

j'ai bien noté vos exemples de collisions droite-plans mathématiques , mais comme transférer ça à une matrice globale + ses axes v0 v1 v2 et v3 + la spline ?

j'ai pas trouvé d'exemples sur le net pour ce genre d'approche.

merci d'avance si quelqu'un a une idée :)

clem

tarlack
04/08/2010, 19h10
c'est "un tantinet" plus complique pour ca, mais ca devrait etre faisable...

ta spline est representee par une equation parametrique x(t), qui pour chaque coordonnee t (comprises entre 0 et 1) te donne la position du point dans l'espace (t te permet de te balader sur ta spline en fait). Par exemple pour les splines de bezier, x(t) est de la forme x(t) = somme(a_i(t) * x_i), ou les x_i sont les points de controle de ta spline, a_i(t) sont des fonctions qui te donnent le poids de chaque point de controle en fonction de ta coordonnee t le long de la spline, et x(t) la position du point le long de la spline. donc pour chaque t, on sait calculer la position.
de la meme maniere, on a une equation parametrique de ton plan, de la forme y(u,v) = (u*x0 + (1-u)*x1) * v + (1-v) * (u*x2 + (1-u)*x3), ou x0, x1, x2 et x3 sont 3 points de ton plan.

le but du jeu, c'est de trouver t, u et v tels que x(t) = y(u,v) (memes coordonnees spatiales). Si deja on arrive a ca, limiter ca a un plan fini sera pas dur, il suffira de bien choisir x0,...,x3 et de limiter les valeurs que peuvent prendre u et v.

et si c'est pas faisable en analytique, on peut toujours le faire via un algo qui marcherait pour tout type de spline, en decoupant la spline en bouts et en utilisant la forme implicite d'un plan, ie f(x) = ax.x + bx.y + cx.z + d (calculer a,b,c et d c'est pas dur). Le signe du resultat de cette equation te dit si ton point x est d'un cote ou de l'autre du plan. Donc s'il y a intersection en t le long de ta spline, le signe de f(x(t+d)) sera different du signe de f(x(t-d)), d etant un chiffre tres petit (par exemple 0.0001).

Pour etre efficace, si ta spline passe a travers le mur et a un bout d'un cote et l'autre de l'autre (elle ne revient pas du premier cote en contournant le plan), tu peux faire ca par dichotimie : tu calcules les points x(0), x(1/2) et x(1), tu calcules f(x(0)), f(x(1/2)), f(x(1)). si les signes de f(x(0)) et f(x(1/2)) sont differents, ton intersection est entre t=0 et t=1/2, sinon elle est entre t=1/2 et t = 1. Pour raffiner, tu coupes en deux l'intervalle de t pour lequel le signe change. Si par exemple c'etait entre 0 et 1/2, tu calcules f(x(1/4)), et tu continues comme ca jusqu'a arriver a une precision voulue.
si ta spline fait des circonvolutions ou croise plusieurs fois le plan, tu peux appliquer cette methode en decoupant ta spline suffisamment fin, genre tous les t=0.10, en commencant en t=0. si rien n'est trouve entre t=0 et t=0.10, tu continues entre t=0.10 et t=0.20, etc. Pour determiner la finesse de decoupage, il faut que tu t'assures que tu coupes de maniere a ce que dans chaque intervalle ta spline ne puisse pas croiser plusieurs fois ton plan, et, s'il y a intersection, que la fin du bout de spline soit bien de l'autre cote du plan que le debut de ton bout de spline.

clemz
04/08/2010, 22h49
merci Tarlak :)

bon je vais être franc j'ai pas tout capté ^^ .

Per-Anders de Maxon m'a donné un lien vers un site où il y a un code de ray collision en C++ (http://www.softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm#Line-Plane%20Intersection ) , ça m'a l'air pas mal du tout enfin le vocabulaire se rapproche bien de ce que je veux et peux faire , plus que du vocabulaire algébrique et théorique ;)

en fait si tu veux , je suis en train de réécrire mon générateur de toile d'araignée , et pour la distribution des branches radiales . Dans le principe , avant j'avais fais une ditribution assez simple qui consistait à prendre la somme des longueurs des segments qui forment le périmêtre et à diviser ça par le nombre de branches radiales voules , ce qui donnaient une distance d'espacement à reporter sur chaque segments ..mais ce qui était complêment faux et stupide car au final on avait un regroupement des branches dans les angles et peu de branches en plein milieu des segments ( je peux mettre des images si c'est pas clair ) .

donc là je veux utiliser une espèce de "projection " 'd'étoile' virtuelle (définie par les axes ZX de mon objet/matrice) sur l'ensemble des segments du périmêtre et donc je veux l'intersection ( pas forcement LA plus précise , mais relativement proche si possible ) de chaque branches de mon 'étoile' ( voir image jointe )
en fait je ne crée pas d'étoile ou de polygones , j'ai juste créé un repêre avec Z moyen en fonction de tous les controleurs définissants le périmêtre ..et après je tourne sur son Z ( B ) avec un angle = "2*PI / nbre de branches " .. (les faux plans blancs sur l'image sont une représentation de chaque position du plan ZX tournant sur B de chaque incrément ) .. et je veux avoir chaque points d'intersection ( faux points circulaires roses sur l'image ) avec les splines du périmêtre .
Donc 1er problême c'est ces intersections , mais après j'en ai un autre : bien controler sur quelle spline du périmêtre on cherche l'intersection , en fonction de la présence d'un point sur la spline ou non ..enfin je sais pas trop encore là

valavala :)

clem

clemz
04/08/2010, 23h17
ha j'ai peut-être une autre idée alors si c'est trop galère ces ray collisions : pour chaques splines je vais faire viser ma matrice en X sur le point de la spline , et lorsque la valeur en B ( même si B ne sera plus trop colinéaire avec le B moyen précedement calculé ) atteint la valeur d'incrément de rotation je note la position du point sur la spline .. hmm ça me semble presque faisable :)

je teste

oli_d
06/08/2010, 12h01
Je rentre de vacances, donc j'ai un peu des toiles d'araignée dans la boîte crânienne.

J'ai pas vraiment tout compris le problème, mais j'en profite pour répondre complétement à côté vu que je viens de découvrir un super petit tuto sur les collisions. C'est plutôt orienté jeu vidéo, mais les principes sont super intéressant et en plus en frenchie :

http://www.siteduzero.com/tutoriel-3-254492-theorie-des-collisions.html

Je ne pense pas que cela t'aide, mais dès que je retrouve une partie de mes neurones j'essaierai de comprendre la question

clemz
06/08/2010, 16h24
Je rentre de vacances, donc j'ai un peu des toiles d'araignée dans la boîte crânienne.

J'ai pas vraiment tout compris le problème, mais j'en profite pour répondre complétement à côté vu que je viens de découvrir un super petit tuto sur les collisions. C'est plutôt orienté jeu vidéo, mais les principes sont super intéressant et en plus en frenchie :

http://www.siteduzero.com/tutoriel-3-254492-theorie-des-collisions.html

Je ne pense pas que cela t'aide, mais dès que je retrouve une partie de mes neurones j'essaierai de comprendre la question


salut Oli-D :) merci pour le lien , je mets dans mes favoris !

sinon pour être plus clair , voici une image avec mon ancien script , pour que tu vois le problême que j'avais .

clemz
06/08/2010, 19h39
ayé ça fonctionne ! ^^ enfin juste sur 1/4 de tour .. j'ai encore merdouillé quelque part mais dans le principe c'est bon : chaque angle entre les branches est une valeur "fixe" ( "fixe" si on regarde dans l'axe Z de la matrice 'moyenne' calculée avec un axe Z moyen , normal à la moyenne des points définissants le périmêtre )... et donc les distances entre les extrémités des branches sont devenues aléatoires ( c'est un peu le principe de l'IK et de l'FK ..avant j'utilisais 'l'IK' ..plus simple .. mais pas bon )

clem