Raydium 3D Game Engine

Official forum for everything about Raydium, ManiaDrive, MeMak, ...
It is currently Thu Mar 28, 2024 9:54 am

All times are UTC




Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: A l'aide (mouse pick)
PostPosted: Sat Feb 10, 2007 10:06 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Bonsoir,

Pour apporter ma contribution j'essaye d'implanter un point de la todo list a savoir le mouse pick.

Apres recherches je suis arrivé au resultat suivant.
Code:
        float vx,vy,vz;
        float mview[16],imview[16],mproj[16];
        float rx,ry,rz,rdx,rdy,rdz;
        int i;
       
        raydium_camera_replace();
       
        glGetFloatv(GL_PROJECTION_MATRIX,mproj);       
        glGetFloatv(GL_MODELVIEW_MATRIX,mview);
        _raydium_trigo_MatrixInverse(mview,imview);

       
        vy =(((2.0f * raydium_mouse_x)/raydium_window_tx)-1)/mproj[0];
        vz =-(((2.0f * raydium_mouse_y)/raydium_window_ty)-1)/mproj[5];
        vx = 1.0f;
       
        rdx = vx*imview[0] + vy*imview[1] + vz*imview[2];
        rdy = vx*imview[4] + vy*imview[5] + vz*imview[6];
        rdz = vx*imview[8] + vy*imview[9] + vz*imview[10];
        rx = imview[12];
        ry = imview[13];
        rz = imview[14];
   
        raydium_log("%3.3f %3.3f %3.3f %3.3f %3.3f %3.3f",rx,ry,rz,rdx,rdy,rdz);
       
       raydium_rendering_internal_prepare_texture_render(0); // !!!
       raydium_texture_current_set_name("rgb(0,1,0)");
      raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
      
      rx=ry=rz=0;
      //rdx=rdy=rdz=0;
      rz=2;
      //rdx=1;
      
      raydium_camera_replace();
      glBegin(GL_LINES);
           glVertex3f(rx,ry,rz);
           glVertex3f(rx+(rdx*100),ry+(rdy*100),rz+(rdz*100));
      glEnd();


Le problème c'est que j'ai peur de faire des erreurs sur les indices des matrices entre leur stockage linéaire et sous forme de vecteur.
Si quelqu'un au point en opengl peut jeter un oeil ?

A+
Jacques


Top
 Profile  
 
PostPosted: Sun Feb 11, 2007 9:32 am 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Bonjour,

Après recherche et surtout grâce au site de nehe
http://nehe.gamedev.net/data/articles/article.asp?article=13

Il est plus efficace d'utiliser gluUnProject

Des lors le code suivant marche à merveille:
Code:
    GLint viewport[4];
   GLdouble modelview[16];
   GLdouble projection[16];
   GLfloat winX, winY, winZ;
   GLdouble posX, posY, posZ;
    float rx,ry,rz,rdx,rdy,rdz;
   
    raydium_camera_replace();

   glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
   glGetDoublev( GL_PROJECTION_MATRIX, projection );
   glGetIntegerv( GL_VIEWPORT, viewport );

   winX = (float)raydium_mouse_x;
   winY = (float)(raydium_window_ty - raydium_mouse_y);
   glReadPixels( raydium_mouse_x, raydium_window_ty-raydium_mouse_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
   gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
   
   rdx=posX;
   rdy=posY;
   rdz=posZ;
    raydium_camera_replace();
    rx=raydium_camera_x;
    ry=raydium_camera_y;
    rz=raydium_camera_z;

        raydium_log("%3.3f %3.3f %3.3f %3.3f %3.3f %3.3f %3.3f",rx,ry,rz,rdx,rdy,rdz,dist);
       
       raydium_rendering_internal_prepare_texture_render(0); // !!!
       raydium_texture_current_set_name("rgb(0,1,0)");
      raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
      
      raydium_camera_replace();
      glBegin(GL_LINES);
           glVertex3f(rx,ry,rz+0.1);
          // glVertex3f(rx+(rdx*100),ry+(rdy*100),rz+(rdz*100));
           glVertex3f(rdx,rdy,rdz);
      glEnd();

La ligne s'affiche bien.

Reste un question pour Xfennec:
Je suis perplexe quant à la définition du rayon.
Voici les solutions que j'envisage, a toi de me dire laquelle est la plus raydium complient

1- Créer un objet (sphère) avec un rayon attaché repositionné à chaque image sur la camera et tourné en fonction de la direction de picking.
Problème: imposer la rotation semble assez complexe, il faut retrouver la matrice de rotation a partir du vecteur et l'appliquer mais il me semble que ça ne se fait pas aussi facilement.

2- Crée un ray special en passant directement par l'api ode, mais il faudrait alors assurer sa gestion des les callback ode de raydium. Un petit peu lourd ?

J'attends ton avis pour poursuivre.

A+
Jacques
[/i]


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 11, 2007 1:53 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
La question est très bonne ... Pour y répondre, il faut savoir ce que l'on souhaite réaliser avec cette fonction de picking.

Je te laisse donner ta vision des choses, mais pour moi l'idée est très liée à la physique du moteur :
Ces rayons devraient par exemple me permettre de savoir quel est l'élément (au sens RayODE du terme) que le joueur désigne avec sa souris/le centre de sa vision, de façon à ce que je puisse savoir à quelle distance est cet élément, voire même que je puisse attacher cet élément au joueur pour qu'il le "transporte" (à la manière des célèbres "gravity gun" des jeux actuels) :
http://www.youtube.com/watch?v=Gd48MTHi0Lc
Pour ne pas plomber les perfs, ce rayon ne devrait exister que très ponctuellement (1 step ou même 0).

Ca demande effectivement quelques galipettes mathématiques, mais ça me semble la solution la plus simple (et puissante) pour l'utilisateur de Raydium.
Après, j'ai pas beaucoup de recul sur tout ça, et j'ai visiblement passé beaucoup moins de temps que toi sur la question :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 11, 2007 2:36 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Bonjour,

Je n'avance plus.

Que veut on faire:

1-Pour moi il s'agissait plutôt d'un outil d'investigation, debug:
On pointe sur un objet et on peut avoir des infos dessus.

2- Concernant le gravity gun, il me semble qu'il suffit d'ajouter un rayon au jouer (player) avec un offset correct ce rayon point sur le point de visé du joueur. On a alors les infos sur l'objet visé.

Toute la partie recherche du point de visée en fonction de la position du curseur est alors simplifiée.

Si on veux pouvoir interagir avec les souris sur des objets:
le code proposé est alors très utile.
par contre il faudrait une sorte d'objet global qui indique quel est l'objet en mire. Cet objet peut être aussi utilisé pour le gravity gun (il faut prendre comme coordonnée de picking le pointeur souris ou le viseur).

On pourrait ajouter a Raydium un rayon au sens ode du terme sans physique / rendu associée
Dont la position serait mise a jour sur la camera à chaque step.
le point de visé obtenu par le code ci dessus.
La routine de collision mettant alors à jour une structure globale qui contiendra les infos de picking:
Nom de l'element
Distance
Point de contact.
...

Enfin une activation / desactivation du picking permettrait de decharger le cpu.

As tu un bout de code pour definir les rotations d'un object pour qu'il point vers un point donné. Je seche la dessus.

Enfin normal ou non, un element RAYDIUM_ODE_STATIC ne supporte pas l'ajout d'un rayon, normal ?

A+
Jacques.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 11, 2007 6:47 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
Le rayon doit être présent que lorsque c'est nécessaire. Il faut penser l'API que l'on expose à l'utilisateur de Raydium, mais je la vois bien se présenter comme une seule fonction qui retourne l'élément touché (ou rien), et la position du contact sur l'élément concerné. La fonction (forcément un peu "gourmande") ferait appel en interne à collide() pour déduire son résultat.

L'autre solution, un calcul qui se fait en permanence à chaque timestep, me semble moins intéressante en particlier au niveau des perfs.

Les rayons de l'API Raydium ont besoin d'un body ODE pour des calculs d'orientation, ce qui fait qu'ils ne peuvent être liés à des objets statiques (avec juste une geom et pas de body, donc).

Du coup, il faut pouvoir transformer la caméra (+ l'offset de la souris ?) en un vecteur dans l'espace "du monde".


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 11, 2007 7:31 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
bonjour,

je vais déja tenter un implantation. On itèrera dessus.

Cependant je suis d'accord:
rayon présent a la demande.


J'a crée un ray ode directement.
Par contre je n'arrive pas a récuperer les collisions de ce ray. même très tot dans raydium_ode_near_callback.

Y a t'il un filtrage que j'aurais loupé ?

Quelque chose d'illogique dans la méthode ?

Les rayon ode sont des geom. Pour moi le body contenait la physique (inertie ...) le geom l'enveloppe (collision ...) un rayon en general n'ayant pas d'influence sur la physique (sauf raycar ;o) ) peuvent etre basé sur des geoms seuls. Ou bien ais'je loupé une etape ?


A+

Jacques.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 11, 2007 7:52 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
Fiouuuu ... ta question demande une étude un peu approfondie du machin qu'est la gestion des collides de ode.c :) Il est effectivement possible que des filtres existent (en tout cas, ils ont existé). Je n'ai pas le temps de regarder ça maintenant, mais je vais me pencher sur la question si tu ne trouve rien de ton coté. Tout ça manque un peu de doc "interne", en définitive.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Feb 11, 2007 7:58 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Ne te penche pas dessus, je finirais bien par trouver, c'est plutôt pour éviter de chercher quelque chose d'évident.

A+


Top
 Profile  
 
 Post subject: il va falloir choisir
PostPosted: Sun Feb 11, 2007 10:11 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Bonjour,

je vais essayer d'etre clair ...

Ca y est le gravity raydium gun marche.
Plein de paramètres sont à affiner mais le principe est la.

Pour le moment c'est implanté comme suit:
sur activation création d'un ray ode avec comme data -1 et nom pas un pointeur sur l'élement.

la fonction raydium_ode_near_callback est un peu modifiée pour ne pas traiter les élement à -1 et appelle une autre fonction qui rempli des variables globales avec l'élément touché, distance ect.

1) Ce n'est pas propre du tout. Je sais :( :(

2) Pour l'implanter proprement:
Peu de modifs
On crée un nouveau type d'element RAYDIUM_MOUSE_PICK
Cet element de génère pas de collision c'est juste un support pour un rayon.
Le callback ode met a jour position et orientation (du rayon)
le callback de collision rempli la structure ray de l'élément donc quasiment aucune modif du code.


3) Plus de modifs
On crée des fonction de picking spécifiques.
raydium_pick_create
-> crée le rayon en objet ode avec un magic number pour data (-1 ou 0)
raydium_pick_delete
-> détruit le rayon, plus de surchare dans le code de collision.
raydium_pick_get_name
-> retourne le nom de l'objet pointé
raydium_pick_get
-> retourne l'id de l'objet pointé
raydium_pick_origin
-> défini l'origine de ray de picking (camera par defaut) mais pourquoi pas un objet (joueur pour le gravity gun)
raydium_pick_aim
-> point de visé, curseur souris principalement, mais aussi valeur fixe

4) inconvénient que je vois:
encore des variables globales
dépendance avec ode accrue
modification du callback des des collisions

5) Qu'est ce qu'il te semble etre le plus viable a long terme?
Le plus facile à prendre en main ?

6) J'ai du mal a voir les problèmes pour s'adapter à l'objet du type player
Comment gérer les vues à la troisième personne ?

A+
Jacques

P.S.
7) J'ai un très gros doute:
ligne 3679 d'ode.c
Code:
      contact[i].geom.g1=raydium_ode_element[e1->id].geom;

e1 contient deja un pointeur sur raydium_ode_element[id] non ?
du coup e1->geom devrais suffire
:?:


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 13, 2007 9:46 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
Question "présentation", a mon avis, il faut faire plus simple (pour l'utilisateur). Déjà, je pense que le picking ne se fait qu'a partir de la caméra, que la vue soit à la 3éme personne ou à la 1ére, en tenant compte dans la position de la souris à l'écran (sachant que dans les FPS [cf test6], la souris est automatiquement centrée à chaque frame, donc c'est parfait).

Ensuite (j'insiste :) ), la fonction est ponctuelle : la rayon ne doit exister que dans ODE (et pas dans RayODE), et surtout que pour *un* appel à collide() (que la fonction réalise elle même).
C'est peut être ce que tu réalises déjà, mais je ne suis pas sûr de lire ça dans ton message. Si l'utilisateur doit créer le rayon et penser à l'effacer un peu plus tard, ça lui complique beaucoup la tâche.

Enfin, toujours à mon avis, le picking doit renvoyer l'identifiant de l'élément touché et/ou la distance, pas plus, pas moins (l'id suffit largement pour retrouver facilement le reste des infos).

Pour le point n°7, tu as raison, c'est une jolie étourderie. Elle se retrouve dupliquée un peu plus bas pour e2. Je te laisse le plaisir de chasser cette lourdeur syntaxique ;)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 13, 2007 9:58 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Bonjour,

Effectivement je vais essayer de faire simple, c'est un des avantages de raydium, continuons.

Ponctuelle je ne comprends pas trop:
Pour moi il faut regler le rayon, attendre un step ode et recuperer les infos, ce qui interdit un appel a une fonction
raydium_mouse_pick...
Serais tu en train d'insinuer que l'on peut appeler collide un peu n'importe quant et sur un objet precis ???? Si c'est ca je suis passé à coté.

Pour le moment je crée un rayon qui existe pendant la durée du picking (plusieurs images ) et gère les collisions de ce rayon.
Ce ne semble pas correspondre.
Peux tu detailler stp ? Surtout sur le collide.


Point 7: mon ode.c est en travaux !!!! et serieusement meme, je te laisse faire la correction ou je la ferrais plus tard.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 13, 2007 10:22 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
En pratique, ODE distingue deux phases lors d'un "step" :
1 - La recherche de collisions (dSpaceCollide())
2 - La mise à jour du "monde" avec le résultat des calculs de contraintes (d*WorldStep())

J'enfonce peut être une porte ouverte, car tu commences visiblement à avoir une certaine connaissance de toute cette section du moteur :)

Dans ma vision des choses, il faudrait éclater le code actuel pour distinguer ces deux phases dans RayODE, ce qui pourrait nous permettre de faire au besoin un appel à la détection des collisions sans modifier le monde. Cette solution nous permet, je pense, d'arriver à une solution très simple pour l'utilisateur picking. En revanche, ça demande un peu plus de boulot de notre coté : En effet, j'ai peur que faire un appel à la détection de collisions telle qu'elle est gérée actuellement dans RayODE ne modifie quand même le monde (au travers des divers callbacks qu'on y trouve). Il faut y faire attention en tout cas.

(C'est une "vue d'esprit", je comprendrais que ce message ne te semble pas très clair :) )

(edit : j'ai fait la modif du point 7)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 14, 2007 9:11 am 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
C'est un plus clair.

Par contre il me semble que les callback de la partie collide, génèrent les contacts de la partie world step.

Deuxièmement je crois que l'algo de collision ne prends pas les objets dans un ordre précis, mais plutôt parcours la hiérarchie pour traiter toutes les collisions. Ce code est en plus assez gourmand en cpu.

Du coup on risque d'avoir deux appels à la partie détection de collision une pour le picking un pour le fonctionnement normal.
Comme on ne peut pas (je crois je n'en suis pas sur) cibler la fonction de détection sur un objet, la surcharge risque d'être importante.

Surement plus que de conserver un rayon et gérer les collision "normalement" avec juste une mise a jour de structure.
La primitive rayon est assez simple et je crois que les collisions sont traitées très rapidement

En fait je me rends compte que le deux approches sont assez diamétralement opposées.

J'essaye d'iterer sur cette fonction de collision "specifique"

A+
Ouille


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 14, 2007 12:28 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
Il n'agit pas de faire les choses en double ("deux appels à la partie détection de collision une pour le picking un pour le fonctionnement normal"), mais d'avoir de temps en temps (par exemple à chaque fois que le joueur essaye de "prendre" un objet au sol) un collide() en plus. Pour rappel, Raydium en réalise déjà 400 par seconde ... en faire 401 de temps en temps ne devrait pas être insurmontable ;)

Note que je ne cherche pas à imposer "ma" solution, je considère juste qu'a priori, elle est moins gourmande que d'avoir un élément en plus en permanence (ou presque) dans le monde.

De toutes façons, ce sujet demande de la réflexion et un peu de recherche, donc rien n'est figé pour moi.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 14, 2007 1:29 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Quote:
Note que je ne cherche pas à imposer "ma" solution, je considère juste qu'a priori, elle est moins gourmande que d'avoir un élément en plus en permanence (ou presque) dans le monde.


J'en suis bien conscient, mais comme tu maitrise plus la structure de raydium et surement d'ode que moi, je préfère que l'on trouve la meilleure solution ensemble avant de l'appliquer. C'est d'ailleurs l'objectif de :( tous :( mes messages.

Une analyse contradictoire n'a jamais fait de mal.

Je regarde la possibilité d'appeler un collide quand on veux, quitte a rediriger les call back, au final ca se goupille bien aussi !

On peut choisir les collisions a tester, (dspacecollide2 dans notre cas il faudrait tester le rayon avec le reste de l'espace (maintenant il faut que je trouve ou tout cela est defini).

Enfin il faut désactiver la géneration de contacts dans
Code:
 raydium_ode_near_callback

Ou bien appeler un callback spécifique au picking.

Un avis ?

Bonne journée
Jacques


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 48 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group