Eu tenho uma projeção em perspectiva. Quando o usuário clica na tela, quero calcular o raio entre os planos de perto e de longe projetados a partir do ponto do mouse, para que eu possa fazer algum código de interseção de raios com o meu mundo.
Estou usando minhas próprias classes de matriz e vetor e raio e todas elas funcionam como esperado.
No entanto, quando tento converter o raio em coordenadas mundiais, minha distância sempre termina em 0,0,0 e, portanto, meu raio vai do clique do mouse até o centro do espaço do objeto, e não através dele. (As coordenadas x e y de perto e de longe são idênticas, diferem apenas nas coordenadas z em que são negativas uma da outra)
GLint vp[4];
glGetIntegerv(GL_VIEWPORT,vp);
matrix_t mv, p;
glGetFloatv(GL_MODELVIEW_MATRIX,mv.f);
glGetFloatv(GL_PROJECTION_MATRIX,p.f);
const matrix_t inv = (mv*p).inverse();
const float
unit_x = (2.0f*((float)(x-vp[0])/(vp[2]-vp[0])))-1.0f,
unit_y = 1.0f-(2.0f*((float)(y-vp[1])/(vp[3]-vp[1])));
const vec_t near(vec_t(unit_x,unit_y,-1)*inv);
const vec_t far(vec_t(unit_x,unit_y,1)*inv);
ray = ray_t(near,far-near);
O que eu entendi errado? (Como você projeta o ponto do mouse?)
Respostas:
Recentemente, tive que resolver isso sozinho para um aplicativo WebGL. Anexei o código fonte completo, mas, caso ele não funcione imediatamente, aqui estão algumas dicas de depuração:
Além disso, para responder a alguns comentários acima, você quase nunca deseja usar as APIs de seleção do OpenGL. Isso ajuda a escolher itens existentes, como se você estivesse criando um menu, mas falha na execução da maioria dos cenários do mundo real, como a edição de modelos 3D. Onde você precisa adicionar geometria como resultado do clique.
Aqui está a minha implementação. Não há nada mágico acontecendo aqui. Apenas JavaScript e a biblioteca Closure do Google.
gluUnProject
Uso
fonte
Não vejo nenhum problema com o seu código. Então, eu só tenho algumas sugestões:
E tentando mudar a multiplacação de matrizes para
(p*mv).inverse();
. Só porque os glMatrices são transpostos nutaralmente na memória. (este é um grande talvez, desculpe)Outro
desdobramento de raycasting não é apenas uma maneira de obter raios do pixel. Este é o meu código para o raycaster:
Você pode obter cameraRight, Up e Direção de matriz de visão (que é principalmente útil no shader) Ver matriz em OpenGL
Seleção de
cores A seleção de cores é uma técnica na qual você renderiza todos os objetos clicáveis com outra cor (sólida) e depois lê o valor da cor no ponto clicado. Funcionou como GL_SELECTION no opengl. Mas está obsoleto agora. Mas a seleção de cores é fácil de codificar como 1 passe de renderização adicional.
Use buffer de quadro e renderize para textura com a mesma resolução que a resolução da tela, use sombreador simples que apenas retorna cores no sombreador de fragmento. Após "passagem de cor", leia o valor de um endereçamento de textura com clicou emPoint x e y. Encontre o objeto com a cor que você lê. Fácil e bastante rápido.
fonte