Вообщем написал свой формат:
Сигнатура формата,
Далее по вершине на строку:
Позиция, Нормаль, Текстурные координаты
Чем вы так любите свои форматы?
Мой парсер-вот
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; };
критикуйте
Прибой94, залей какую-нить модель в SMD. Нужно для изучения))
Критика? Можно было использовать чисто C++.. Вектора, стринги, потоки..
На самом деле в этом парсере была одна грубая ошибка.
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
пирамидка
На всякий случай скажу формат вершин:
Кость - Позиция3D - Нормаль3D - TexCoord2D - BlendWeight - BlendInd - BlendWeight - BlendInd - BlendWeight - BlendInd -BlendWeight - BlendInd.
Последних элементов может быть от 0 до 4
Тема в архиве.