Exemplo n.º 1
0
/* Функция инициализации объекта анимации.
 * АРГУМЕНТЫ:
 *   - указатель на "себя" - сам объект анимации:
 *       vg4UNIT_CTRL *Uni;
 *   - указатель на контекст анимации:
 *       vg4ANIM *Ani;
 * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет.
 */
static VOID VG4_AnimUnitInit( vg4UNIT_CTRL *Uni, vg4ANIM *Ani )
{
  vg4PRIM pr;

  Uni->hFnt = CreateFont(30, 0, 0, 0, FW_BOLD, FALSE, FALSE,
    FALSE, RUSSIAN_CHARSET, OUT_DEFAULT_PRECIS,
    CLIP_DEFAULT_PRECIS, PROOF_QUALITY,
    VARIABLE_PITCH, "Bookman Old Style");

  VG4_RndPrimMatrConvert = MatrMulMatr(MatrMulMatr(MatrScale(0.0024, 0.0024, 0.0024), MatrRotateX(-0)), MatrTranslate(0, 0, 0));
  VG4_GeomLoad(&Uni->Helic, "MODELS\\Mi8\\havoc.g3d");
  Uni->Helic.ProgId = VG4_ShaderLoad("HELIC");


  VG4_RndPrimDefaultColor = ColorSet(1, 0, 0, 1);
  VG4_PrimCreatePlane(&pr, VecSet(-500, -0.030, 0), VecSet(1000, 0, 0), VecSet(0, 0.059, 0), 2, 2);
  VG4_GeomAddPrim(&Uni->Axes, &pr);

  VG4_RndPrimDefaultColor = ColorSet(0, 0, 1, 1);
  VG4_PrimCreatePlane(&pr, VecSet(0, -0.030, -500), VecSet(0, 0, 1000), VecSet(0, 0.059, 0), 2, 2);
  VG4_GeomAddPrim(&Uni->Axes, &pr);


  VG4_RndPrimDefaultColor = ColorSet(0, 1, 0, 1);
  VG4_PrimCreatePlane(&pr, VecSet(-0.030, -500, 0), VecSet(0, 1000, 0), VecSet(0.059, 0, 0), 2, 2);
  VG4_GeomAddPrim(&Uni->Axes, &pr);

  Uni->Axes.ProgId = VG4_ShaderLoad("AXIS");

  VG4_RndPrimDefaultColor = ColorSet(0.7, 0.5, 0.3, 1);
  VG4_PrimCreateSphere(&Uni->Sph, VecSet(0, 0, 0), 1, 8, 15);
  Uni->Sph.ProgId = Uni->Axes.ProgId;

  /* начальные параметры вертолета */
  Uni->Pos = VecSet(0, 18, 0);
  Uni->V = 0;
  Uni->Head = 0;
  Uni->Omega = 0;

  Uni->CPos = VecSet(59, 30, 59);
} /* End of 'VG4_AnimUnitInit' function */
Exemplo n.º 2
0
/* Функция загрузки геометрического объекта.
 * АРГУМЕНТЫ:
 *   - геометрический объект:
 *       vg4GEOM *G;
 *   - имя файла материалов:
 *       CHAR *FileName;
 * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ:
 *   (BOOL) TRUE при успехе.
 */
BOOL VG4_GeomLoad( vg4GEOM *G, CHAR *FileName )
{
  INT vn = 0, vtn = 0, vnn = 0, fn = 0, pn = 0, size, i, p;
  FILE *F;
  /* читаемые данные */
  VEC *ReadV, *ReadN;
  vg4UV *ReadUV;
  INT (*ReadF)[3];
  /* хранение примитивов */
  struct
  {
    INT
      First, Last, /* первый и последний номера вершин примитива */
      Mtl;         /* материал примитива */
  } *PrimInfo;

  memset(G, 0, sizeof(vg4GEOM));
  /* разбиваем имя на части и открываем файл */
  _splitpath(FileName, ModelDrive, ModelDir, ModelFileName, ModelFileExt);
  if ((F = fopen(FileName, "rt")) == NULL)
    return FALSE;

  /* считаем количества */
  while (fgets(Buf, sizeof(Buf), F) != NULL)
    if (Buf[0] == 'v' && Buf[1] == ' ')
      vn++;
    else if (Buf[0] == 'v' && Buf[1] == 't')
      vtn++;
    else if (Buf[0] == 'v' && Buf[1] == 'n')
      vnn++;
    else if (Buf[0] == 'f' && Buf[1] == ' ')
      fn += Split() - 3;
    else if (strncmp(Buf, "usemtl", 6) == 0)
      pn++;

  if (pn == 0)
    pn = 1; /* материалы не использовались */

  /* загружаем:
   *   вершины                        vn
   *   нормали                        vvn
   *   текстурные координаты          vtn
   *   треугольники                   fn
   *   примитивы                      pn
   * дополнительно:
   *   индексы (Vv, Vn, Vt) <- новые номера вершин  ? (vn + vt + vnn) * ???
   *   начальные индексы              vn
   */

  /* выделяем память под вспомогательные данные */
  size = 
    sizeof(VEC) * vn +                        /*   вершины               vn */
    sizeof(VEC) * vnn +                       /*   нормали               vnn */
    sizeof(vg4UV) * vtn +                     /*   текстурные координаты vtn */
    sizeof(INT [3]) * fn +                    /*   треугольники          fn */
    sizeof(PrimInfo[0]) * pn +                /*   примитивы             pn */
    sizeof(VertexRefs[0]) * (vn + vtn + vnn) + /*   индексы (Vv, Vn, Vt)  (vn + vt + vnn) */
    sizeof(INT) * vn;                         /*   начальные индексы     vn */
  if ((ReadV = malloc(size)) == NULL)
  {
    fclose(F);
    return FALSE;
  }
  memset(ReadV, 0, size);

  /* расставляем указатели */
  ReadN = ReadV + vn;
  ReadUV = (vg4UV *)(ReadN + vnn);
  ReadF = (INT (*)[3])(ReadUV + vtn);
  VertexRefsStart = (INT *)(ReadF + fn);
  PrimInfo = (VOID *)(VertexRefsStart + vn);
  VertexRefs = (VOID *)(PrimInfo + pn);
  NumOfAllocedVertexRefs = vn + vtn + vnn;
  NumOfVertexRefs = 0;
  /* начала списка индексов вершин ==> -1 */
  memset(VertexRefsStart, 0xFF, sizeof(INT) * vn);
  memset(VertexRefs, 0xFF, sizeof(VertexRefs[0]) * NumOfAllocedVertexRefs);

  /* второй проход - читаем геометрию */
  rewind(F);
  vn = 0;
  vtn = 0;
  vnn = 0;
  fn = 0;
  pn = 0;
  PrimInfo[0].First = 0;

  /* считаем количества */
  while (fgets(Buf, sizeof(Buf), F) != NULL)
    if (Buf[0] == 'v' && Buf[1] == ' ')
    {
      FLT x = 0, y = 0, z = 0;

      sscanf(Buf + 2, "%f%f%f", &x, &y, &z);
      ReadV[vn++] = VecSet(x, y, z);
    }
    else if (Buf[0] == 'v' && Buf[1] == 't')
    {
      FLT u = 0, v = 0;

      sscanf(Buf + 3, "%f%f", &u, &v);
      ReadUV[vtn++] = VG4_UVSet(u, v);
    }
    else if (Buf[0] == 'v' && Buf[1] == 'n')
    {
      FLT nx = 0, ny = 0, nz = 0;

      sscanf(Buf + 3, "%f%f%f", &nx, &ny, &nz);
      ReadN[vnn++] = VecNormalize(VecSet(nx, ny, nz));
    }
    else if (Buf[0] == 'f' && Buf[1] == ' ')
    {
      INT n0[3], n1[3], n[3], r0, r1, r;

      Split();
      SCANF3(Parts[1], n0);
      r0 = GetVertexNo(n0[0], n0[1], n0[2]);

      SCANF3(Parts[2], n1);
      r1 = GetVertexNo(n1[0], n1[1], n1[2]);

      for (i = 3; i < NumOfParts; i++)
      {
        SCANF3(Parts[i], n);
        r = GetVertexNo(n[0], n[1], n[2]);

        ReadF[fn][0] = r0;
        ReadF[fn][1] = r1;
        ReadF[fn][2] = r;
        r1 = r;
        fn++;
      }
    }
    else if (strncmp(Buf, "usemtl", 6) == 0)
    {
      Split();

      /* запоминаем номер последней грани */
      if (pn != 0)
        PrimInfo[pn - 1].Last = fn - 1;

      /* ищем материал */
      for (i = 0; i < G->NumOfMtls; i++)
        if (strcmp(Parts[1], G->Mtls[i].Name) == 0)
          break;
      if (i == G->NumOfMtls)
        PrimInfo[pn].Mtl = -1;
      else
        PrimInfo[pn].Mtl = i;
      PrimInfo[pn].First = fn;
      pn++;
    }
    else if (strncmp(Buf, "mtllib ", 7) == 0)
    {
      Split();
      LoadMaterials(G, Parts[1]);
    }

  /* у последнего примитива запоминаем номер последней грани */
  if (pn == 0)
  {
    PrimInfo[0].Last = fn - 1;
    PrimInfo[0].Mtl = -1;
  }
  else
    PrimInfo[pn - 1].Last = fn - 1;
  fclose(F);

  /* Формируем примитивы из прочитанных данных */
  VG4_DefaultColor = ColorSet(1, 1, 1);
  for (p = 0; p < pn; p++)
  {
    INT minv, maxv, j;
    vg4PRIM prim;

    minv = maxv = ReadF[PrimInfo[p].First][0];
    for (i = PrimInfo[p].First; i <= PrimInfo[p].Last; i++)
      for (j = 0; j < 3; j++)
      {
        if (minv > ReadF[i][j])
          minv = ReadF[i][j];
        if (maxv < ReadF[i][j])
          maxv = ReadF[i][j];
      }
    vn = maxv - minv + 1;
    fn = PrimInfo[p].Last - PrimInfo[p].First + 1;
    VG4_PrimCreate(&prim, VG4_PRIM_TRIMESH, vn, fn * 3);

    /* копируем вершины */
    for (i = 0; i < vn; i++)
    {
      INT n;

      prim.V[i].P = ReadV[VertexRefs[minv + i].Nv];
      if ((n = VertexRefs[minv + i].Nn) != -1)
        prim.V[i].N = ReadN[n];
      if ((n = VertexRefs[minv + i].Nt) != -1)
        prim.V[i].T = ReadUV[n];
    }
    /* копируем грани */
    for (i = 0; i < fn; i++)
      for (j = 0; j < 3; j++)
        prim.I[i * 3 + j] = ReadF[PrimInfo[p].First + i][j] - minv;
    prim.Mtl = PrimInfo[p].Mtl;
    VG4_GeomAddPrim(G, &prim);
  }
  /* освобождаем память из-под прочитанных данных */
  free(ReadV);
  return TRUE;
} /* End of 'VG4_GeomLoad' function */