PDA

Voir la version complète : GeRayCollider en python



valkaari
20/05/2011, 03h57
Bonjour,

j'essayes d'utiliser les fonctions GeRayCollider de Python mais j'arrive déjà pas à initialiser....

je crois qu'il faut faire un truc du genre


MyRayCollide = c4d.utils.GeRayCollider
MyRayCollide.Init(Object)

Alors le soucis, c'est que Object doit être du type BaseObject alors que moi j'ai un PolygonObject. En c++ j'aurais fait un static_cast comme un barbare mais en Python , je ne sais pas comment m'en sortir.

Si une âme charitable saurait comment faire. L'idée c'est d'avoir, en fonction d'une position, la position la plus proche sur la surface d'un objet. (utilisation des fonction intersection et GetNearestIntersection)

Merci d'avance à 4h du mat, ça me fatigue cette connerie xD

oli_d
20/05/2011, 08h18
Non, cela m'a l'air correct il faut bien un objet polygonal. Il manque juste les parenthèses après c4d.utils.GeRayCollider().

Un petit exemple pour un tag python qui met tous les objets enfants sur une surface (marche que sur l'axe y, pour les autres à adapter), il faut faire une UserData avec le lien sur l'objet cible qui doit bien être polygonal

Pour les distances et longueurs, il faudrait améliorer en calculant d'abord la taille de l'objet cible et en s'assurant de bien le mettre au dessus avant de calculer l'intersection, mais le principe est là (il y a aussi le fichier en pièce jointe):


import c4d

def Childs2mnt(obj,mnt,dist=10000,longueur = 100000):
"""place tous les enfants de obj sur mnt
mnt doit etre un objet polygonal"""

mat = mnt.GetMg()
invmat = ~mat
rc = c4d.utils.GeRayCollider()
rc.Init(mnt)

for o in obj.GetChildren():
mg = o.GetMg()
pos = mg.off*invmat
pos.y = dist
direct = c4d.Vector(0,-1,0) # pour projection verticale, a adapter pour d'autres type
i = rc.Intersect(pos, direct, longueur)
if i :
pos = rc.GetIntersection(0)["hitpos"]*mat
mg.off = pos
o.SetMg(mg)


def main():
obj = op.GetObject()
mnt = op[c4d.ID_USERDATA,1]
if mnt:
if mnt.GetType()==c4d.Opolygon:
Childs2mnt(obj,mnt)

valkaari
20/05/2011, 17h43
bon c'était bien ça merci. Saleté de parenthèse des 4h du mat :p


Bon par contre, ça sert à rien dans mon cas que je récupère le point le plus proche, puisque c'est pas là que je veux aller xD

Merci Oli :)

oli_d
20/05/2011, 18h51
En fait tu aimerais avoir le point d'intersection le plus proche sur une surface depuis un point ?

Je ferais un truc du genre :


calculer le point de ton maillage le plus proche
trouver les polys qui utilise ce point avec c4d.utils.Neighbor.GetPointPolys(pnt)
trouver le point d'intersection le plus proche entre ces polys (formule chez Bourke deuxième chapitre de la page (http://paulbourke.net/geometry/pointline/))

Bon faut juste comprendre la formule au père Bourke, mais avec ton cerveau j'suis pas inquiet, attaque peut-être juste avant 4 heure du matin :icon_mrgreen:

Edit : en fait j'ai p'tet rien pigé, c'est quoi quoi que tu veux faire ???

valkaari
20/05/2011, 20h43
En fait, l'idée globale, c'est de faire partir des particules d'une zone qui est proche du bords de l'image vers un texte qui est au centre pour le faire apparaitre. Les particules de gauche doivent aller sur la partie gauche du texte, celles de droite, à droite.

Tout ça en ayant 1 arrêtes ou un groupe d'arrêtés, voir une spline enfin bref une source et un texte. (je pourrais me débrouiller avec plusieurs objets mais le but est de faire un preset et donc un truc très simple)

Mais le soucis c'est qu'il faut un certain nombre de particules si tu veux un rendu pas trop dégueulasse. Alors pour récupérer le vertex le plus proche, il faut faire des calculs avec tous les points. (d'ailleurs il a un noeud xpresso qui permet de le faire)

C'est d'un lent didiou xD

Bref je vais me débrouiller autrement et chercher une astuce pour faire mon mouvement en deux temps.


edit : mais comme ça m'agace ce truc, je reviendrais surement dessus pour faire un truc plus nickel chrome surement