Apontamento de Objetos em Ambientes Virtuais

Para que se possa apontar um obejto em uma ambiente virtual é necessário determinar se há ou não interseção entre o objeto apontador e algum objeto do cenário 3D.
O objeto apontador pode ter qualquer formato. Sugere-se entretanto que se use um objeto que falicite o apontamento como uma caneta ou um raio.
A fim de facilitar o cálculo das interseções entre o apontador e os objetos 3D sugere-se que estes sejam formados por triângulos.
 
 

Cálculo de intersecção entre triângulos

Para determinar a interseção entre triângulos, use as rotinas existentes neste exemplo.
 

Exercício

Sugestão de como armazenar um triângulo como um vetor
// Object data struct
SmVR_CPoint Tri[3] =
     {
      SmVR_CPoint(0,0,0),
      SmVR_CPoint(10,0,0),
      SmVR_CPoint(10,10,0)
     };
Sugestão de como exibir um triângulo armazenado em um vetor
 
// **********************************************************************
// int DrawTest(void *p)
//
// **********************************************************************
int DrawTest(void *p)
{
 int i;
 // Draw a triangle
 glBegin (GL_TRIANGLES);
  glColor3f(1,0,0);
  for (i=0;i<3;i++)
  {
   glVertex3f(Tri[i].X, Tri[i].Y, Tri[i].Z);
  }
 glEnd();
 return 1;
}
Sugestão de como obter as coordenadas atualizadas dos vértices do triângulo armazenado em um vetor
 
SmVR_CPoint aux;

TestObject->TranslateBy(-5,0,0);

TestObject->GetPointInOCS(Tri[0],&aux,RootObject); // coloca em 'aux' as coordenadas atualizadas do vértice 0 do triângulo
printf("Ponto : (%6.3f, %6.3f, %6.3f)\n", aux.X, aux.Y, aux.Z);
TestObject->GetPointInOCS(Tri[1],&aux,RootObject); // coloca em 'aux' as coordenadas atualizadas do vértice 1 do triângulo
printf("Ponto : (%6.3f, %6.3f, %6.3f)\n", aux.X, aux.Y, aux.Z);
TestObject->GetPointInOCS(Tri[2],&aux,RootObject); // coloca em 'aux' as coordenadas atualizadas do vértice 2 do triângulo
printf("Ponto : (%6.3f, %6.3f, %6.3f)\n", aux.X, aux.Y, aux.Z);
 


Se voce está usando OpenGL SEM a SmallVR, o que vem a seguir, pode ser útil

Aplicação de transformações geométricas a um ponto em OpenGL.

Cálculo das coordenadas de um ponto

Quando você desenha objetos em OpenGL,  geralmente especifica as coordenadas destes objetos e a partir de transformações geométricas(rotação , translação e escala) pode fazer o objeto mover-se no espaço.
Para obter as novas coordenadas deste objeto no espaço(após as transformações geométricas) pode ser usada a função calcula_ponto apresentqada a seguir.

No caso de apontamento de objetos esta função é útil pois permite calcular as coordenadas dos vértices dos triângulos que formam este apontador e a partir destas determinar se há ou não intersecçõa etre os obnjetos e o apontador.
 

#include <windows.h>
#include <gl\gl.h>

typedef struct
{
 GLfloat x,y,z;
} Ponto3D;

// ***********************************************
//  void calcula_ponto(Ponto3D *p, Ponto3D *out)
//
//  Esta função calcula as coordenadas
//  de um ponto no sistema de referência do
//  universo (SRU), ou seja, aplica as rotações,
// escalas e translações a um ponto no sistema
//  de referência do objeto SRO.
//
// ***********************************************
void calcula_ponto(Ponto3D *p, Ponto3D *out)
{
   GLfloat ponto_novo[4];
   GLfloat matriz_gl[4][4];
   int  i;

   glGetFloatv(GL_MODELVIEW_MATRIX,&matriz_gl[0][0]);

   for(i=0;i<4;i++)
   {
      ponto_novo[i]= matriz_gl[0][i] * p->x+
                     matriz_gl[1][i] * p->y+
                     matriz_gl[2][i] * p->z+
                     matriz_gl[3][i];
   }
   out->x=ponto_novo[0];
   out->y=ponto_novo[1];
   out->z=ponto_novo[2];
}
 

Ponto3D p1, p2;

// ***********************************************
//  void Desenha ()
//
//
// ***********************************************
void Desenha ()
{
     Ponto3D p1_new, p2_new;

     p1.x = 10;   p1.y = 10;   p1.z = 20;
     p1.x = 20;   p1.y = 10;   p1.z = 20;

     glRotate3f(10,0,0,1);
     glBegin(GL_LINES);
         //desenha a linha
         glVertex3f(p1.x, p1.y, p1.z);
         glVertex3f(p2.x, p2.y, p2.z);
         // aplica as transformações geométricas
         // aos pontos da linha
         calcula_ponto(&p1, &p1_new);
         calcula_ponto(&p2, &p2_new);
         //imprime p1_new e p2_new
         // .......
     glEnd();
}