PB modeleur 3D changement du centre de rotation de l objet

Signaler
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009
-
Messages postés
3
Date d'inscription
samedi 21 juillet 2007
Statut
Membre
Dernière intervention
23 juillet 2007
-
bonjour a tous

je vous contacte car j ai un petit probleme : je developpe actuellement un petit modeleur 3d sous opengl et qt et j aimerais implementer une fonction rotation autour d un point pour cela j utilise la fonction suivante :


bool GLBox::pointUnderPixel(
int x,
int y,
double vec[3])


{



float depth;



// Qt uses upper corner for its origin while GL uses the lower corner.


glReadPixels(x, height()-y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);



bool found = depth < 1.0;


GLdouble dx = x;


GLdouble dy = y;


GLdouble dz = depth;


GLdouble proj[16];


glGetDoublev(GL_PROJECTION_MATRIX, proj);


GLdouble modelview[16];


glGetDoublev(GL_MODELVIEW_MATRIX, modelview);


GLint viewport[4];


glGetIntegerv (GL_VIEWPORT, viewport);



double rx,ry,rz;


gluUnProject(dx,dy,dz, modelview, proj, viewport, &rx,&ry,&rz);




vec[0] = rx;


vec[1] = ry;


vec[2] = rz;



return found;


}

mais le point trouvé n a rien a voir avec le point clické et de plus la rotation ne se fait pas autour du nouveau point mais autour du centre de l objet comme auparavant ...

avez vous de piste ???

merci de votre aide ...

a plus

tom

21 réponses

Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
"Rotation autour d'un point" -> c'est une rotation un peu libre non... ?
D'apres ce que j'ai compris de ton code, tu veux cliquer a l'ecran et faire une rotation par rapport a un axe = axe de profondeur passant par le point cliqué ?
Dis en peu plus... peut etre que je pourrai mieux t'aider.
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009

ben j ai programme un espace de rotation de type arcball/track ball (fortement aide par la lecon 48 de nehe...)cette rotation ce fait par rapport au centre de lobjet... moi je recupere grace a la methode ci dessus un point physique je je rentre en parametre a ma methode trackball pour definir le nouveau centre de rotation mais cela n a aucun effet ...
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Ok, j'y etais presque donc... Rotation ArcBall/TrackBall connait pas (==transformation solide ? (rotation+translation)).

- Une rotation par rapport a un point ne veut rien dire en 3D, faire tourner tel objet par rapport au point P de X degrés ca donne quoi ? en 2D ca a un sens, mais en 3D je vois pas.
A moins que l'objet est un vecteur d'orientation et que tu veuilles faire tourner l'objet par rapport a son centre tel que le vecteur d'orientation pointe vers ton point selectionné

- As tu testé ta fonction de "picking" ci-dessus ? (ca a l'air de marché mais sais t on jamais) ? pourquoi le depth==1.0 est il dérangeant pour toi ? (bool found=depth<1.0 et rajoute juste apres if(!found) return false ou un if(found) { tout le reste }jusqu'avant return found car les glGetXXX ca pourri les perfs).

- Pour faire un truc plus rapide que les glGetXXX et finalement gluUnProject pour trouver les coordonnees 3D du point cliqué, si tu connais tes axes camera (up,right,profondeur en orthonormé direct), le depth du point clique et un peu de math, et bien tu peux calculer directement les coords du point connaissant ta matrice de projection (enfin plutot connaissant la fonction que tu emplois pour definir ta matrice de projection, glFrustrum, gluPerspective,etc..).

Pour finir expliques clairement la rotation que tu comptes faire une fois que tu as le point 3D

@+, KeniiyK.
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009

merci bcp pour ta reponse

une rotation en CAO est definie a l aide des quaternions pour definir les troix valeurs xyz de la rotation nouxs avons besoin de 2 points le point de debut du click et le point de relachement ces coordonnees enregistrees je les projete sur une sphere de centre O pour obtenir une coordonnee en z correspondante ensuite je calcule le produit vectoriel de OP1 avecOP2 et j obtient mon axe de rotation, avec la norme j obtient mon angle....

voici pour l environnement arcballl ou trackball. le principe de la rotation autour d un point est le meme a part qu on remplace directement le point O par le nouveau centre de rotation on aura donc une rotation sui vant x, y, et z mais par rapport au centre C...

depth = =1 est la profondeur du plan de clipping par defaut non, il ne faut pas que notre point soit dessus...

je n utilise aucune perspective car on est dans l environnement CAO

qu entends tu par "fonction de picking" ?
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Ok je crois qu'on va y arriver. J'ai besoin juste d'une derniere precision concernant la rotation (dis moi laquelle de ces deux propositions est la bonne) :
- L'objet tourne sur lui meme, son centre + l'axe de rotation determiné par les 2 points cliqués et que tu "translate" donc au centre de l'objet pour faire une rotation locale. (donc sans modification du centre de l'objet).

- L'objet tourne autour de l'axe de rotation determiné par les 2 points cliqués pour faire une rotation "univers"/"globale"/"spatiale" (choisis ton terme...). (donc avec une modification du centre de l'objet).

Pour l'histoire du depth==1.0, effectivement cela veut dire que le point sera sur le plan de clipping, mais...... ...... et alors ????????, tu veux un point 3D non ?, en quoi cela perturbe le calcul du point ?

"je n utilise aucune perspective car on est dans l environnement CAO", tu veux dire que ta projection est orthogonale ?, et moi quand je disais "(enfin plutot connaissant la fonction que tu emplois pour definir ta matrice de projection, glFrustrum, gluPerspective,etc..)." je parlais de toute les fonctions de projection, y compris glOrtho().

Le picking c'est la sélection d'un objet (ou d'un groupe d'objets) a l'ecran, c'est un peu ce que tu fais : selection d'un point dans un nuage de points en gros...
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009

wé c ca...

la bonne proposition est le :

- L'objet tourne sur lui meme, son centre + l'axe de rotation determiné par les 2 points cliqués et que tu "translate" donc au centre de l'objet pour faire une rotation locale. (donc sans modification du centre de l'objet).

as tu des piste ???

comme tu peux le voir je ne suis pqs du tout codeur a la base ... ca fait 2 sem que je code ce bordel et g un peu de mal ... voila merci !
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Des pistes j'en ai, mais j'aimerais finir d'abord de bien cerner ton probleme pour te donner la/les adéquat(s)....

Dans ta fonction le int x, et le int y represente les coordonnées souris je pense alors pourquoi dans l'appel a glReadPixels(x, height()-y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); il y a "height()-y" et pas "y" en coordonnées ? parce que là c'est sur tu ne vas pas recevoir le depth correspondant au point cliqué.

Et j'ai pas tout saisi là :
"nous avons besoin de 2 points le point de debut du click et le point de relachement ces coordonnees enregistrees je les projete sur une sphere de centre O pour obtenir une coordonnee en z correspondante ensuite je calcule le produit vectoriel de OP1 avecOP2 et j obtient mon axe de rotation, avec la norme j obtient mon angle...."

sphere de centre O == sphere centrée à l'origine ? ou amors O est quelconque ?
coordonnee en z correspondante == coordonnée en z égale/équivalente ? sinon c'est quoi ce z (celui du quaternion?)
calcule le produit vectoriel de OP1 avecOP2 et j obtient mon axe de rotation, ben je croyais que cétait P1P2 ton axe de rotation ?
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009

le height - y c est parce que je developpe avec Qt regarde le commentaire tt est dedans...

// Qt uses upper corner for its origin while GL uses the lower corner.

la sphere est centree a l origine et l axe est donne par le produit vectoriel et non pas par P1P2

le z correspond a la hauteur du point de coord x,y projete sur la sphere z appartient donc a [0,r]
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Autant pour moi je viens de verifier dans un de mes codes (je developpe aussi avec Qt) l'histoire du height-y, tu as raison par contre je mettrais height-1-y car y appartient a [0,height-1].

Finalement j'ai re-testé tout ca, alors mon glReadPixels marche impec (couleur, depth, etc...). Par contre j'ai juste un truc chiant mais a savoir c'est que le depth renvoyé est sur une echelle logarithmique et non lineaire, du au fait que ma projection est perspective. Mais toi tu dois avoir la bonne valeur vu que t'as une projection orthogonale (enfin d'apres ce que j'ai compris).
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009

wé c ca ... alors la mehode marche sans soucis ???

d ou veint mon erreur ???

dsl j e suis tres chiant mais ossi tres coince ds mon boulot ... lol

merci a plus !
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
ben ton erreur je sais pas, peut etre qu'elle n'est pas là. Mais reponds : as tu une projection orthogonale ?
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Dans ton code t'as bien un resizeGL (QGLWidget) ou tu doit faire un truc du style :
void TA_CLASSE_GL::resizeGL(int width, int height)
{


glViewport(0,0,width,height);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/*a cette ligne tu as quoi ?*/
glMatrixMode(GL_MODELVIEW);
}
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009

oui j ai une projection orthogonale


void GLBox::resizeGL(
int w,
int h )


{


GLfloat wn = ((
float) w) / ((
float) h);


GLfloat hn = 1.0;


glViewport( 0, 0, w, h );


glMatrixMode( GL_PROJECTION );


glLoadIdentity();


glOrtho( -wn, wn, -hn, hn, -18.0, 22.0 );
// fixes the z-near and the z-far planes. Here the domain is [-500;500] because of the translated view factor on the z-axis


glMatrixMode( GL_MODELVIEW );


}

voila mon resizeGL, je fais bien du glOrtho, je m'en sert pour zoomer aussi ...
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Bon ok, (desole je voulais etre sur...)
- je suppose que tu es en DoubleBuffer (mode par defaut des QGLWidget)
- Si tu as changé le buffer en lecture, si tu as ca dans ton code : glReadBuffer(GL_FRONT);
alors appele glReadBuffer(GL_BACK); avant le glReadPixel();
- Ensuite si tu as changé le glDepthRange il te faut appelle gluUnProject4 a la place de gluUnProject.
- pour finir (valable aussi pour gluUnProject4 si la condition precedente est verifier) change l'appel a gluUnProject(dx,dy,dz, modelview, proj, viewport, &rx,&ry,&rz);
avec dy=height()-y-1 et n'oublie pas aussi de le changer dans glReadPixel(x, height()-y-1,....)

Ben voila, (enfin chez moi ca marche alors je pense que ca ne vas pas tarde pour toi).

Petites ameliorations :
- gluUnProject* retourne GL_TRUE si reussi, GL_FALSE sinon, n'oublies pas de tester, histoire que tu ne te retrouves pas avec des points pourris.
- si ta matrice de projection de change pas constamment alors fait le glGetDoublev(GL_PROJECTION_MATRIX, proj); dans le resizeGL et avec "proj" membre statique de classe et idem pour le viewport fait glGetIntegerv (GL_VIEWPORT, viewport); dans le resizeGL avec "viewport" membre static de classe.

Tiens nous au courant.
@+, KeniiyK.
Messages postés
34
Date d'inscription
mercredi 9 mars 2005
Statut
Membre
Dernière intervention
29 octobre 2009

Merciiiiiiiiiiiiii

ca fonctionne nickel

je te dois une fiere chandelle !!!!

c super sympa te ta part de m avoir aidé ....
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Super !!!, suis content pour toi et desole d'avoir ete si long a trouver la faille...
Parce qu'en fait projection orthogonale ou perspective ne change rien au probleme mais dans le book d'OpenGL ils sont un peu ambigüs au sujet de l'echelle logarithmique du depth.

M'enfin, tout est bien qui fini bien....

tchao.

KeniiyK.
Messages postés
3
Date d'inscription
samedi 21 juillet 2007
Statut
Membre
Dernière intervention
23 juillet 2007

peux-tu m'aider  aussi? ca ne marche pas.
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Salut, je veux bien t'aider mais quel est ton probleme ?
Messages postés
3
Date d'inscription
samedi 21 juillet 2007
Statut
Membre
Dernière intervention
23 juillet 2007

avec camera()->pointUnderPixel() , ma valeur Z est beaucoup trop grande. DOnc, quand je tourne la camera, mes lignes et points disparaissent.

Merci,
Messages postés
326
Date d'inscription
vendredi 13 août 2004
Statut
Membre
Dernière intervention
2 novembre 2007
2
Tu utilise gluUnProject* ? si c'est le cas regarde le retour de la fonction qui doit etre GL_TRUE si cela marche.