ПрограммированиеФорумГрафика

Выбор формата модели [DX10] (2 стр)

Страницы: 1 2
#15
23:18, 28 авг 2009

Вообщем написал свой формат:

Сигнатура формата,
Далее по вершине на строку:
Позиция, Нормаль, Текстурные координаты

#16
2:07, 29 авг 2009

Чем вы так любите свои форматы?

Мой парсер-вот

bool Load_HL12SMD(char *name,Tmesh *m,Tanim *a)
{
  // для работы с файлами подключить #include <stdio.h>
  FILE *in=fopen(name,"rb"); 
  if(in==NULL){ALERT("HL12SMD::can't load (%s)");return 0;};
  char buf[4096];
  char bname[1024];
  int parent;
  DWORD mf=0,mv=0,i,j,k;
  byte mb=0;
  float tf;
  int ti;
  DWORD vertexcnt = 0;

  //сперва определим количества (вершин костей ...и тд) и выделим память
  while(fgets(buf,4095,in))
  {

    // считаем кости
    if(!strncmp(buf,"nodes", 5))
    {
      while(fgets(buf,4095,in))
      {
        if(!strncmp(buf,"end", 3))
        {
          m->mb=mb;
          m->bv=new vec3f[mb];
          m->ba=new vec3f[mb];
          m->p=new int[mb];
          a->max_b=mb;
          a->fr=new TMAFrame[mb];a->Initfr();    
          break;
        };
        mb++;
      };
    }; 

    // считаем треугольники
    if(!strncmp(buf,"triangles", 9))
    {
      while(fgets(buf,4095,in))
      {
        if(!strncmp(buf,"end", 3))
        {
          m->mv=mv;
          m->v=new vec3f[mv];
          m->t=new vec2f[mv];
          m->ti=new int[mv];    
          if(mb>0)
          {
            m->mbi=new byte[mv];
            m->bi=new int*[mv];
            m->sbi=new float*[mv];          
          };
          m->mf=mf;
          m->f=new vec3l[mf];
          break;
        };

        // покачто не нужная информация - пропускаем
        fgets(buf,4095,in);fgets(buf,4095,in);fgets(buf,4095,in);
        mf++;
        mv+=3;
      };
    };
  };

  // сбрасываем позицию чтения файла на начало
  rewind(in);

  // заполняем массивы
  while(fgets(buf,4095,in))
  {
  
    //читаем имена и индксы костей (я не сохраняю имена)
    if(!strncmp(buf,"nodes", 5))
    {
      for(i=0;i<mb;i++)
      {
        fgets(buf,4095,in);
        sscanf(buf,"%d \"%[^\"]\" %d",&ti,bname,&parent);
        m->p[i]=parent;
      };
    };

    // читаем сами кости
    if(!strncmp(buf,"skeleton", 5))
    {
      fgets(buf,4095,in);//time 0
      for(i=0;i<mb;i++)
      {
        fgets(buf,4095,in);
        sscanf(buf,"%d %f %f %f %f %f %f",&ti,&m->bv[i][0],&m->bv[i][1],&m->bv[i][2],
                       &m->ba[i][0],&m->ba[i][1],&m->ba[i][2]);
      };

      // чтение анимации
      //(!)важно(!) анимация уже перемножена с начальным положением костей
      char cmd[10];
      DWORD fcnt=0;
      a->max_fr=0;
      bool animFound=false;
      while(fgets(buf,4095,in))
      {
        sscanf(buf,"%s %d",cmd,&k);
        if(!strncmp(cmd,"end", 3))
        {
          if(!animFound)
          {
            a->max_b=0;
          };
          break;
        };
        if(!strncmp(cmd,"time", 4))
        {
          animFound=true;
          a->max_fr++;
          for(i=0;i<mb;i++)
          {
            fgets(buf,4095,in);
            a->fr[i].max_tkf++;
            a->fr[i].pos=(vec3f*)realloc(a->fr[i].pos,sizeof(vec3f)*a->fr[i].max_tkf);
            a->fr[i].Ttime=(float*)realloc(a->fr[i].Ttime,sizeof(float)*a->fr[i].max_tkf);
            a->fr[i].max_rkf++;
            a->fr[i].rot=(vec3f*)realloc(a->fr[i].rot,sizeof(vec3f)*a->fr[i].max_rkf);
            a->fr[i].Rtime=(float*)realloc(a->fr[i].Rtime,sizeof(float)*a->fr[i].max_rkf);
            fcnt=a->fr[i].max_tkf-1;
            a->fr[i].Ttime[fcnt]=(float)k;
            a->fr[i].Rtime[fcnt]=(float)k;
            sscanf(buf,"%d %f %f %f %f %f %f",&ti,&a->fr[i].pos[fcnt][0],&a->fr[i].pos[fcnt][1],&a->fr[i].pos[fcnt][2],
                &a->fr[i].rot[fcnt][0],&a->fr[i].rot[fcnt][1],&a->fr[i].rot[fcnt][2]);
          };
        };
      };
    }; 

    //читаем треугольники
    if(!strncmp(buf,"triangles", 9))
    {
      int nb,bi[5];
      DWORD cnt=0,index;
      float bw[5];
      D3DXVECTOR3 RV;
      vec2f RT;
      for(i=0;i<mf;i++)
      {
   
        // сперва идёт имя текстуры 
        memset(buf,'\0',4095);fgets(buf,4095,in);
        if(buf[0]=='\0')
        {
          m->ti[i]=0;
        }
        else
        {
          long num=-1;
          buf[strlen(buf)-1]='\0';buf[strlen(buf)-1]='\0';//'\n\t'
          for(j=0;j<m->mtx;j++)
          {
            if(!strcmp(m->txn[j],buf))
              continue;
            num=j;
            break;
          };
          if(num==-1)
          {
            m->ti[i]=m->mtx;
            m->mtx++;
            m->tnl=(int*)realloc(m->tnl,sizeof(int)*m->mtx);
            m->tnl[m->mtx-1]=strlen(buf)+1;
            m->txi=(int*)realloc(m->txi,sizeof(int)*m->mtx);
            m->txi[m->mtx-1]=num;
            m->txn=(char**)realloc(m->txn,sizeof(char*)*m->mtx);
            m->txn[m->mtx-1]=new char[m->tnl[m->mtx-1]];
            memcpy(m->txn[m->mtx-1],buf,sizeof(char)*m->tnl[m->mtx-1]);
            m->txn[m->mtx-1][m->tnl[m->mtx-1]]='\0';
          }
          else
          {
            m->ti[i]=num;
          };
        };

        //после имени текстуры следуют 3 вершины (со всеми свойствами)  
        for(j=0;j<3;j++)
        {
          fgets(buf,4095,in);
          nb=0;

          // читаем
          // %d - индекс кости (если привязано к вершине всего одна кость)
          // %f %f %f - вершина
          // %f %f %f - нормаль (я не сохраняю)
          // %f %f - текстурные координаты
          // %d - количество привязанных костей 
          // %d %f ....... - индекс кости и её вес (weight)
          // вроде больше чем 5 костей на вершину не встречал
          int numRead=sscanf(buf,"%d %f %f %f %f %f %f %f %f %d %d %f %d %f %d %f %d %f",&ti,
                &RV[0],&RV[1],&RV[2],&tf,&tf,&tf,&RT[0],&RT[1],
                &nb,&bi[0],&bw[0],&bi[1],&bw[1],&bi[2],&bw[2],&bi[3],&bw[3],&bi[4],&bw[4]);
          RT[1]=RT[1]+1.0f;
          if(nb==0)
          {
            nb=1;bi[0]=ti;bw[0]=1.0;
          };

          // проверка: дублирование вершины (если да то запоминаем индекс)
          //-------------find face index
          index=cnt;
          for(k=0;k<cnt;k++)
          {
            if(  m->v[k][0]==RV[0] &&
              m->v[k][1]==RV[1] &&
              m->v[k][2]==RV[2] &&
              m->t[k][0]==RT[0] &&
              m->t[k][1]==RT[1])
            {
              index=k;
              break;
            };
          };
          m->f[i][j]=index;
          if(index==cnt)
          {
            COPY(m->v[index],RV);
            COPY2(m->t[index],RT);
            //-------------------bones
            if(mb>0)
            {
              m->mbi[index]=nb;
              m->bi[index]=new int[nb];
              m->sbi[index]=new float[nb];
              for(k=0;k<(DWORD)nb;k++)
              {
                m->bi[index][k]=bi[k];
                m->sbi[index][k]=bw[k];
              };
            }; 
            //-----------------end bones
            cnt++;
          };
          //------------end find index
        };
        // меняем порядок обхода вершин
        k=m->f[i][0];
        m->f[i][0]=m->f[i][2];
        m->f[i][2]=k;
      };
      m->mv=cnt;
    };
  };
  fclose(in);
  return true;
};

критикуйте

#17
14:01, 29 авг 2009

Прибой94, залей какую-нить модель в SMD. Нужно для изучения))

Критика? Можно было использовать чисто C++.. Вектора, стринги, потоки..

#18
15:18, 29 авг 2009

На самом деле в этом парсере была одна грубая ошибка.

strlen и strnlen возвращают 0 когда строки равны, а там в условии продолжения было наоборот.
И еще: проверка строки идет напр. на "nodes" а при загрузке из файла там "nodes#13#10#"

Залить в SMD? Так?


version 1
nodes
  0 "Bone1"  -1
end
skeleton
time 0
  0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
end
triangles
test_noise.dds
  0 0.5000 0.5000 0.5000 0.5774 0.5774 0.5774 1.0000 0.0000
  0 -0.5000 -0.5000 0.5000 -0.5774 -0.5774 0.5774 0.0000 1.0000
  0 0.5000 -0.5000 -0.5000 0.5774 -0.5774 -0.5774 0.0000 0.0000
test_noise.dds
  0 0.5000 0.5000 0.5000 0.5774 0.5774 0.5774 1.0000 0.0000
  0 -0.5000 0.5000 -0.5000 -0.5774 0.5774 -0.5774 1.0000 1.0000
  0 -0.5000 -0.5000 0.5000 -0.5774 -0.5774 0.5774 0.0000 1.0000
test_noise.dds
  0 -0.5000 0.5000 -0.5000 -0.5774 0.5774 -0.5774 1.0000 1.0000
  0 0.5000 0.5000 0.5000 0.5774 0.5774 0.5774 0.0000 1.0000
  0 0.5000 -0.5000 -0.5000 0.5774 -0.5774 -0.5774 0.0000 0.0000
test_noise.dds
  0 -0.5000 -0.5000 0.5000 -0.5774 -0.5774 0.5774 1.0000 0.0000
  0 -0.5000 0.5000 -0.5000 -0.5774 0.5774 -0.5774 1.0000 1.0000
  0 0.5000 -0.5000 -0.5000 0.5774 -0.5774 -0.5774 0.0000 0.0000
end

пирамидка

#19
15:21, 29 авг 2009

На всякий случай скажу формат вершин:

Кость - Позиция3D - Нормаль3D - TexCoord2D - BlendWeight - BlendInd - BlendWeight - BlendInd - BlendWeight - BlendInd -BlendWeight - BlendInd.

Последних элементов может быть от 0 до 4

Страницы: 1 2
ПрограммированиеФорумГрафика

Тема в архиве.