Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





un picking relativamente sencillo

Iniciado por marcode, 02 de Julio de 2008, 03:10:08 AM

« anterior - próximo »

marcode

quiero saber en qué lugar de la superficie, se proyecta un supuesto rayo que sale de una posición en 2D (del cursor del ratón).

La idea es hacer una función a la que supongo tendré que pasar la matriz de vista, la de proyección, el viewport y la posición del cursor. Y me devuelva la coordenada 3D donde hace el picking.

Como el lugar de "colisión" del rayo un plano recto en la altura cero, pues basta con que me devuelva la coordenada X/Z de la superficie del suelo sobre la que estoy "pasando" el cursor.

¿alguien sabría la fórmula?, imagino que es el proceso inverso al de pasar la coordenada 3D a 2D en la pantalla, pero ando un poco liado y no quiero perder demasiado tiempo dando palos de ciego, si alguien lo supiera pues estupendo, mientras seguiré indagando.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

AK47

Busca en google "picking 3d" y cosas así. Por cierto, como fue lo de los impostores?

Buffon

Si no recuerdo mal esta era la parte de mi código que lo hacía.

if(state == GLUT_DOWN){
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix((GLdouble) x,(GLdouble) (vista[3]-y),.5,.5,vista);
gluPerspective(anglecam,aspect,radi,5*radi);
glMatrixMode(GL_MODELVIEW);

//TORNEM A DIBUIXAR L'ESCENA
redibuixa();
hits=glRenderMode(GL_RENDER);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
mode=!mode;

int ind=0;
int i=3;
int j=4;

while(ind<hits && ind<mida/5){
 
 scene->meshobjlist[*(nom+i)].facelist[*(nom+j)].selected=!scene->meshobjlist[*(nom+i)].facelist[*(nom+j)].selected;
 
 i+=5;
 j+=5;
 ind++;
}

glEnable(GL_CULL_FACE);
glutPostRedisplay();

     }

marcode

Cita de: "AK47"Busca en google "picking 3d" y cosas así. Por cierto, como fue lo de los impostores?

sigue pendiente  :(


lo otro a ser posible no querría usar el gluPickMatrix
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

Prompt

joder... "scene->meshobjlist[*(nom+i)].facelist[*(nom+j)].selected=!scene->meshobjlist[*(nom+i)].facelist[*(nom+j)].selected;"

AK47


Buffon

Cita de: "marcode"
Cita de: "AK47"Busca en google "picking 3d" y cosas así. Por cierto, como fue lo de los impostores?

sigue pendiente  :(


lo otro a ser posible no querría usar el gluPickMatrix

tu no tas leído mi respuesta xDDDDD

(ese código tiene 5 años por lo menos y es una práctica de tercero de carrera <.<)

me edito:

tu querías el orden de multiplicación de las matrices no el código concreto que lo hiciera ^^ :P

Buffon

Cita de: "Prompt"joder... "scene->meshobjlist[*(nom+i)].facelist[*(nom+j)].selected=!scene->meshobjlist[*(nom+i)].facelist[*(nom+j)].selected;"

cada mesh le metimo un booleano que decía si estaba seleccionado o no y en el rendering lo pintabamos de otro color si así era.

Aún así no es forma de programar, lo se xDDDDD

marcode

es que no quiero usar el modo de render de selección de opengl, porque es que no lo necesito, y además no sería lo más eficaz.

Quiero poder seleccionar la celda correspondiente en la típica matriz de celdas iguales. Que en 2D sería muy fácil, pero en 3D se complica un poco porque depende de la posición y la orientación de la cámara, de la proyección y el viewport.

Todavía no lo he intentado hacer, pero es que como no lo tengo nada claro quería saber si alguien que esté puesto en el tema tenía alguna idea.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

Prompt

Es que para 3D está pensado GL_SELECT :) como método más optimo, si vas a hacer calculos más complejos y volver a hacer el rayo a mano, quizás sea más optimo no usarlo e implementarte el tuyo.

Yo particularmente lo que haría es pintar en GL_SELECT obtener a que objeto le he dado y comprobar si mi rayo da en ese objeto y donde.

Buffon

Cita de: "marcode"es que no quiero usar el modo de render de selección de opengl, porque es que no lo necesito, y además no sería lo más eficaz.

Quiero poder seleccionar la celda correspondiente en la típica matriz de celdas iguales. Que en 2D sería muy fácil, pero en 3D se complica un poco porque depende de la posición y la orientación de la cámara, de la proyección y el viewport.

Todavía no lo he intentado hacer, pero es que como no lo tengo nada claro quería saber si alguien que esté puesto en el tema tenía alguna idea.

piensa que te he pasado un código de hace 5 años jaja.

a ver si encuentro uno que tengo más actual que usa GL_SELECT como dice prompt.

pero repito, tu pedías el orden de multiplicación de las matrices y te he puesto algo que utilizar como esquema, no creí que quisieras el código completo :P

Prompt

Cita de: "Buffon"
pero repito, tu pedías el orden de multiplicación de las matrices y te he puesto algo que utilizar como esquema, no creí que quisieras el código completo :P

Es que la gente es mu floja... muy muy floja :P no pide links ni algo para estudiar no... piden ya el código para copiar, pegar y adaptar. :evil:

marcode

CitarEs que la gente es mu floja... muy muy floja Razz no pide links ni algo para estudiar no... piden ya el código para copiar, pegar y adaptar.

?
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

Warchief

Puedes mirar en motores de código abierto. Por ejemplo en Irrlicht (version 3demon):

getScreenCoordinatesFrom3DPosition( const core::vector3df& pos3d, ICameraSceneNode* camera )
{
core::vector2di pos2d(-1000,-1000);

 // ...

core::vector2di dim = Driver->getScreenSize();
dim.X /= 2;
dim.Y /= 2;

f32 transformedPos[4];

core::matrix4 trans = camera->getProjectionMatrix();
trans *= camera->getViewMatrix();

transformedPos[0] = pos3d.X;
transformedPos[1] = pos3d.Y;
transformedPos[2] = pos3d.Z;
transformedPos[3] = 1.0f;

trans.multiplyWith1x4Matrix(transformedPos);

if(transformedPos[3] < 0)
return core::vector2di(-10000,-10000);

f32 zDiv = transformedPos[3] == 0.0f ? 1.0f :
(1.0f / transformedPos[3]);

pos2d.X = (s32)(dim.X * transformedPos[0] * zDiv) + dim.X;
pos2d.Y = ((s32)(dim.Y - (dim.Y * (transformedPos[1] * zDiv))));

return pos2d;
}


Será cuestión de adaptarlo a las funciones que tengas en tu motor o API.

marcode

Cita de: "Warchief"Puedes mirar en motores de código abierto. Por ejemplo en Irrlicht (version 3demon):

getScreenCoordinatesFrom3DPosition( const core::vector3df& pos3d, ICameraSceneNode* camera )
{
core::vector2di pos2d(-1000,-1000);

 // ...

core::vector2di dim = Driver->getScreenSize();
dim.X /= 2;
dim.Y /= 2;

f32 transformedPos[4];

core::matrix4 trans = camera->getProjectionMatrix();
trans *= camera->getViewMatrix();

transformedPos[0] = pos3d.X;
transformedPos[1] = pos3d.Y;
transformedPos[2] = pos3d.Z;
transformedPos[3] = 1.0f;

trans.multiplyWith1x4Matrix(transformedPos);

if(transformedPos[3] < 0)
return core::vector2di(-10000,-10000);

f32 zDiv = transformedPos[3] == 0.0f ? 1.0f :
(1.0f / transformedPos[3]);

pos2d.X = (s32)(dim.X * transformedPos[0] * zDiv) + dim.X;
pos2d.Y = ((s32)(dim.Y - (dim.Y * (transformedPos[1] * zDiv))));

return pos2d;
}


Será cuestión de adaptarlo a las funciones que tengas en tu motor o API.

Quiero hacer eso pero al revés. Creo que se aproxima más a lo que haría un trazador de rayos, es decir, que conozco la posición 2D, la proyección y vista de la cámara, y quiero saber a qué posición 3D corresponde. Con la ventaja de que el lugar de colisión no es un objeto, sino una superficie plana y recta con respecto al origen de coordenadas e infinita.

Pensaba que iba a ser más sencillo y que lo sabría alguien, una simple fórmula.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.