Basic3D Tutorials Основы 3D
3D структуры.

 

В этом разделе, называемом "3D структуры", вы узнаете, как закодировать информацию о вершинах, гранях, объектах в 3D. Например, вершины в 3D можно представить в виде:

 

  float VertexX[1000]

  float VertexY[1000]

  float VertexZ[1000]

 

UV координаты текстуры можно хранить вот так:

 

  float VertexU[1000]

  float VertexV[1000]

 

Можно подумать, что это здорово. Но на самом деле можно сделать лучше! Потому что, если Вы ограничились1000 вершин, то это означает, что Вы не можете загружать объекты, у которых больше чем 1000 вершин. И второе, вершины при этом не объединены друг с другом. Это означает, что нет логического построения объекта. Теперь, рассмотрим другой метод:

 

  typedef struct VertexTYPE

  {

   float x,y,z; - координаты в мире

   float u,v; - координаты на текстуре

  } vertextype;

 

Или же:

 

  typedef struct VertexTYPE

  {

   float x,y,z;

  } vertextype;

 

  typedef struct MappingTYPE

  {

   float u,v;

  } mappingtype;

 

Но давайте вернемся к первому примеру. Пусть мы имеем структуру (vertextype), но что, если мы хотим иметь n-вершин? Отлично, мы выделяем их динамически:

 

  vertextype *vertices;

  vertices = malloc(sizeof(vertextype)*n);

 

где n - определяет число вершин. Так, мы можем иметь n-вершин, но как быть с гранями? Как мы их сохраним? Отлично, для определения грани мы нуждаемся в указателях на три вершины, и мы могли бы нуждаться в значении затенении или в среднем значении для сортировки. Вот так, например:

 

  typedef struct FaceTYPE

  {

   vertextype *p1,*p2,*p3;

   long vertex[3]; - номера вершин, в списке вершин

   char shading;

   long midz;

  } facetype;

 

Теперь, если мы допустим, что p1, p2 и p3 указатели на вершины, через которые мы можем модифицировать вершину непосредственно. Массив Vertex [3], который мы используем, если мы желаем обратиться к структурам вершины, т.е.

 

  x = vertices[face[currentface].vertex[0]].x;

  y = vertices[face[currentface].vertex[0]].y;

  z = vertices[face[currentface].vertex[0]].z;

 

Или с использованием указателей:

 

  x = face[currentface]->p1.x;

  y = face[currentface]->p2.y;

  z = face[currentface]->p3.z;

 

Также необходимо задать структуру объекта, чтобы сохранить все эти вершины. Структура могла бы содержать данные относительно того, как объект должен вращаться, где он позиционирован и возможно указатель на текстуру.

 

  typedef struct ObjectTYPE

  {

   float      rotatex,rotatey,rotatez;

   long       numvertices;

   long       numfaces;

   vertextype *vertices;

   facetype   *face;

   char       *textptr;

  } objecttype;

 

Допустим по указателю object.vertices мы можем найти все вершины, которые находится в этом объекте, вершина из object.vertices [0] первая, а вершина оbject.vertex[numvertices-1] последняя. То же самое и для структур граней. Это также дает нам возможность использовать один и тот же массив вершин для описания нескольких объектов. Следовательно, мы можем найти все вершины в нашем мире внутри переменной называемой "vertices" и каждую грань в переменной называемой "face". Следовательно, все вершины могут вращаться в новом массиве, который мы вызываем "vertices_rot", и мы имеем возможность обратиться к каждому объекту, чтобы вращать их отдельную вершину. Тот же самое относиться и к сортировке плоскостей, мы можем сортировать все плоскости на сцене, начинающейся с face[0], затем двигаемся далее. Мы нуждаемся в другой переменной, называемой "facesort", это массив плоскостей, но отсортированный по значению face.midz. Все это должно помочь в том, как представить объекты в 3D.

 

PMG  3 марта 2005 (c)  Сергей Анисимов