/**************************************************************************** ** $Id: fgui/cadformmd2.h ** AutoQ3D a qt 3d model editor program ** ** Copyright (C) 2005-2007 -Gonzalo Reynaga Garcia. ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public Licence ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later option. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ** *****************************************************************************/ #ifndef CADFORM_MD2_H #define CADFORM_MD2_H #include "../cadform.h" #include "selframe.h" #define MD2_MAX_TRIANGLES 4096 #define MD2_MAX_VERTICES 2048 #define MD2_MAX_TEXCOORDS 2048 #define MD2_MAX_FRAMES 512 #define MD2_MAX_SKINS 32 #define MD2_MAX_FRAMESIZE (MD2_MAX_VERTICES * 4 + 128) namespace { // normal table lifted from Mark Kilgard's md2bump demo float normaltable[][3]= { {-0.525731f, 0.000000f, 0.850651f}, {-0.442863f, 0.238856f, 0.864188f}, {-0.295242f, 0.000000f, 0.955423f}, {-0.309017f, 0.500000f, 0.809017f}, {-0.162460f, 0.262866f, 0.951056f}, {0.000000f, 0.000000f, 1.000000f}, {0.000000f, 0.850651f, 0.525731f}, {-0.147621f, 0.716567f, 0.681718f}, {0.147621f, 0.716567f, 0.681718f}, {0.000000f, 0.525731f, 0.850651f}, {0.309017f, 0.500000f, 0.809017f}, {0.525731f, 0.000000f, 0.850651f}, {0.295242f, 0.000000f, 0.955423f}, {0.442863f, 0.238856f, 0.864188f}, {0.162460f, 0.262866f, 0.951056f}, {-0.681718f, 0.147621f, 0.716567f}, {-0.809017f, 0.309017f, 0.500000f}, {-0.587785f, 0.425325f, 0.688191f}, {-0.850651f, 0.525731f, 0.000000f}, {-0.864188f, 0.442863f, 0.238856f}, {-0.716567f, 0.681718f, 0.147621f}, {-0.688191f, 0.587785f, 0.425325f}, {-0.500000f, 0.809017f, 0.309017f}, {-0.238856f, 0.864188f, 0.442863f}, {-0.425325f, 0.688191f, 0.587785f}, {-0.716567f, 0.681718f, -0.147621f}, {-0.500000f, 0.809017f, -0.309017f}, {-0.525731f, 0.850651f, 0.000000f}, {0.000000f, 0.850651f, -0.525731f}, {-0.238856f, 0.864188f, -0.442863f}, {0.000000f, 0.955423f, -0.295242f}, {-0.262866f, 0.951056f, -0.162460f}, {0.000000f, 1.000000f, 0.000000f}, {0.000000f, 0.955423f, 0.295242f}, {-0.262866f, 0.951056f, 0.162460f}, {0.238856f, 0.864188f, 0.442863f}, {0.262866f, 0.951056f, 0.162460f}, {0.500000f, 0.809017f, 0.309017f}, {0.238856f, 0.864188f, -0.442863f}, {0.262866f, 0.951056f, -0.162460f}, {0.500000f, 0.809017f, -0.309017f}, {0.850651f, 0.525731f, 0.000000f}, {0.716567f, 0.681718f, 0.147621f}, {0.716567f, 0.681718f, -0.147621f}, {0.525731f, 0.850651f, 0.000000f}, {0.425325f, 0.688191f, 0.587785f}, {0.864188f, 0.442863f, 0.238856f}, {0.688191f, 0.587785f, 0.425325f}, {0.809017f, 0.309017f, 0.500000f}, {0.681718f, 0.147621f, 0.716567f}, {0.587785f, 0.425325f, 0.688191f}, {0.955423f, 0.295242f, 0.000000f}, {1.000000f, 0.000000f, 0.000000f}, {0.951056f, 0.162460f, 0.262866f}, {0.850651f, -0.525731f, 0.000000f}, {0.955423f, -0.295242f, 0.000000f}, {0.864188f, -0.442863f, 0.238856f}, {0.951056f, -0.162460f, 0.262866f}, {0.809017f, -0.309017f, 0.500000f}, {0.681718f, -0.147621f, 0.716567f}, {0.850651f, 0.000000f, 0.525731f}, {0.864188f, 0.442863f, -0.238856f}, {0.809017f, 0.309017f, -0.500000f}, {0.951056f, 0.162460f, -0.262866f}, {0.525731f, 0.000000f, -0.850651f}, {0.681718f, 0.147621f, -0.716567f}, {0.681718f, -0.147621f, -0.716567f}, {0.850651f, 0.000000f, -0.525731f}, {0.809017f, -0.309017f, -0.500000f}, {0.864188f, -0.442863f, -0.238856f}, {0.951056f, -0.162460f, -0.262866f}, {0.147621f, 0.716567f, -0.681718f}, {0.309017f, 0.500000f, -0.809017f}, {0.425325f, 0.688191f, -0.587785f}, {0.442863f, 0.238856f, -0.864188f}, {0.587785f, 0.425325f, -0.688191f}, {0.688191f, 0.587785f, -0.425325f}, {-0.147621f, 0.716567f, -0.681718f}, {-0.309017f, 0.500000f, -0.809017f}, {0.000000f, 0.525731f, -0.850651f}, {-0.525731f, 0.000000f, -0.850651f}, {-0.442863f, 0.238856f, -0.864188f}, {-0.295242f, 0.000000f, -0.955423f}, {-0.162460f, 0.262866f, -0.951056f}, {0.000000f, 0.000000f, -1.000000f}, {0.295242f, 0.000000f, -0.955423f}, {0.162460f, 0.262866f, -0.951056f}, {-0.442863f, -0.238856f, -0.864188f}, {-0.309017f, -0.500000f, -0.809017f}, {-0.162460f, -0.262866f, -0.951056f}, {0.000000f, -0.850651f, -0.525731f}, {-0.147621f, -0.716567f, -0.681718f}, {0.147621f, -0.716567f, -0.681718f}, {0.000000f, -0.525731f, -0.850651f}, {0.309017f, -0.500000f, -0.809017f}, {0.442863f, -0.238856f, -0.864188f}, {0.162460f, -0.262866f, -0.951056f}, {0.238856f, -0.864188f, -0.442863f}, {0.500000f, -0.809017f, -0.309017f}, {0.425325f, -0.688191f, -0.587785f}, {0.716567f, -0.681718f, -0.147621f}, {0.688191f, -0.587785f, -0.425325f}, {0.587785f, -0.425325f, -0.688191f}, {0.000000f, -0.955423f, -0.295242f}, {0.000000f, -1.000000f, 0.000000f}, {0.262866f, -0.951056f, -0.162460f}, {0.000000f, -0.850651f, 0.525731f}, {0.000000f, -0.955423f, 0.295242f}, {0.238856f, -0.864188f, 0.442863f}, {0.262866f, -0.951056f, 0.162460f}, {0.500000f, -0.809017f, 0.309017f}, {0.716567f, -0.681718f, 0.147621f}, {0.525731f, -0.850651f, 0.000000f}, {-0.238856f, -0.864188f, -0.442863f}, {-0.500000f, -0.809017f, -0.309017f}, {-0.262866f, -0.951056f, -0.162460f}, {-0.850651f, -0.525731f, 0.000000f}, {-0.716567f, -0.681718f, -0.147621f}, {-0.716567f, -0.681718f, 0.147621f}, {-0.525731f, -0.850651f, 0.000000f}, {-0.500000f, -0.809017f, 0.309017f}, {-0.238856f, -0.864188f, 0.442863f}, {-0.262866f, -0.951056f, 0.162460f}, {-0.864188f, -0.442863f, 0.238856f}, {-0.809017f, -0.309017f, 0.500000f}, {-0.688191f, -0.587785f, 0.425325f}, {-0.681718f, -0.147621f, 0.716567f}, {-0.442863f, -0.238856f, 0.864188f}, {-0.587785f, -0.425325f, 0.688191f}, {-0.309017f, -0.500000f, 0.809017f}, {-0.147621f, -0.716567f, 0.681718f}, {-0.425325f, -0.688191f, 0.587785f}, {-0.162460f, -0.262866f, 0.951056f}, {0.442863f, -0.238856f, 0.864188f}, {0.162460f, -0.262866f, 0.951056f}, {0.309017f, -0.500000f, 0.809017f}, {0.147621f, -0.716567f, 0.681718f}, {0.000000f, -0.525731f, 0.850651f}, {0.425325f, -0.688191f, 0.587785f}, {0.587785f, -0.425325f, 0.688191f}, {0.688191f, -0.587785f, 0.425325f}, {-0.955423f, 0.295242f, 0.000000f}, {-0.951056f, 0.162460f, 0.262866f}, {-1.000000f, 0.000000f, 0.000000f}, {-0.850651f, 0.000000f, 0.525731f}, {-0.955423f, -0.295242f, 0.000000f}, {-0.951056f, -0.162460f, 0.262866f}, {-0.864188f, 0.442863f, -0.238856f}, {-0.951056f, 0.162460f, -0.262866f}, {-0.809017f, 0.309017f, -0.500000f}, {-0.864188f, -0.442863f, -0.238856f}, {-0.951056f, -0.162460f, -0.262866f}, {-0.809017f, -0.309017f, -0.500000f}, {-0.681718f, 0.147621f, -0.716567f}, {-0.681718f, -0.147621f, -0.716567f}, {-0.850651f, 0.000000f, -0.525731f}, {-0.688191f, 0.587785f, -0.425325f}, {-0.587785f, 0.425325f, -0.688191f}, {-0.425325f, 0.688191f, -0.587785f}, {-0.425325f, -0.688191f, -0.587785f}, {-0.587785f, -0.425325f, -0.688191f}, {-0.688191f, -0.587785f, -0.425325f} }; } struct header { int magic; // This is used to identify the file int version; // The version number of the file (Must be 8) int skinWidth; // The skin width in pixels int skinHeight; // The skin height in pixels int framesize; // The size in bytes the frames are int numSkins; // The number of skins associated with the model int numvertices; // The number of vertices (constant for each frame) int numtexCoords; // The number of texture coordinates int numtriangles; // The number of faces (polygons) int numglcmds; // The number of gl commands int numframes; // The number of animation frames int offsetSkins; // The offset in the file for the skin data int offsettexCoords; // The offset in the file for the texture data int offsettriangles; // The offset in the file for the face data int offsetframes; // The offset in the file for the frames data int offsetglcmds; // The offset in the file for the gl commands data int offsetEnd; // The end of the file offset }; struct compressed_vertex { unsigned char v[3]; // scaled byte to fit in frame mins/maxs unsigned char normalindex; }; struct frame { float scale[3]; // multiply byte verts by this float translate[3]; // then add this char name[16]; // frame name from grabbing compressed_vertex *verts; // variable sized }; struct glcmd_t { float s; float t; int index; }; void CadForm::InsertMD2(){ FILE * fp; header md2header; int i=0,bits; float inv=1.0; int vertnum; int numFrame=0; int* command; glcmd_t *data; frame *curframe; int simgle_vertnum; int vertindex; int numframes; unsigned int pindx=0,dtsize=0,sel_vert=0; /*QWidgetList windoL=ws->windowList(QWorkspace::CreationOrder); if ( windoL.count() ) { for (i = 0; i < int(windoL.count()); i++) { GLApp *win =(GLApp*) windoL.at( i ); win->close(); } }*/ /*DataLV.resize(0);DataTV.resize(0);DataSV.resize(0);*/ QString fn = QFileDialog::getOpenFileName(this,QString(tr("Insert MD2 file")),filename,tr("MD2 model(*.md2)") ); QString tempo; i=0; if ( !fn.isEmpty() ) { if ((fp = fopen(fn.toAscii(), "rb")) == 0 ) return; bits=fread(&md2header,sizeof(header),1, fp); numframes = md2header.numframes; SelFrame* w = new SelFrame(this); if(w->exec()){ numFrame=w->FindSize->text().toInt(); if(w->Checky->checkState()==Qt::Checked){ inv=-1.0; } if(numFrame>=numframes){ QMessageBox::information(this,"Error",QString(tr("Frame must be lower than %1")).arg(numframes),tr("&OK")); return; } }else{ delete w; return; } delete w; command = (int *)malloc (sizeof (int) * md2header.numglcmds); curframe=new frame[1]; numframes = md2header.numframes; fseek(fp, md2header.offsetglcmds, SEEK_SET); bits=fread(command, sizeof(int),md2header.numglcmds, fp); fseek(fp, md2header.offsetframes+md2header.framesize*numFrame, SEEK_SET); curframe->verts = (compressed_vertex *)malloc (sizeof (compressed_vertex) * md2header.numvertices); bits=fread (curframe->scale, sizeof (float)*3, 1, fp); bits=fread (curframe->translate, sizeof (float)*3, 1, fp); bits=fread (curframe->name, sizeof (char), 16, fp); bits=fread (curframe->verts, sizeof (compressed_vertex), md2header.numvertices, fp); /*for(j=0,q=0;j<1;j++) {*/ while (*command){ sel_vert=0; vertnum=*command; if (*command > 0) {simgle_vertnum = *command;}//triangle strip else {simgle_vertnum = -*command;}//triangle fan command++; for(i=0;is; DataTV[dtsize].t1[1]=1.0-data->t; vertindex=data->index; DataTV[dtsize].v1[0]=(curframe->verts[vertindex].v[0] * curframe->scale[0]) + curframe->translate[0]; DataTV[dtsize].v1[1]=(curframe->verts[vertindex].v[1] * curframe->scale[1]) + curframe->translate[1]; DataTV[dtsize].v1[2]=(curframe->verts[vertindex].v[2] * curframe->scale[2]) + curframe->translate[2]; DataTV[dtsize].n1[0] =normaltable[curframe->verts[vertindex].normalindex][0]*inv; DataTV[dtsize].n1[1] =normaltable[curframe->verts[vertindex].normalindex][1]*inv; DataTV[dtsize].n1[2] =normaltable[curframe->verts[vertindex].normalindex][2]*inv; } if(sel_vert==1){ DataTV[dtsize].t3[0]=data->s; DataTV[dtsize].t3[1]=1.0-data->t; vertindex=data->index; DataTV[dtsize].v3[0]=(curframe->verts[vertindex].v[0] * curframe->scale[0]) + curframe->translate[0]; DataTV[dtsize].v3[1]=(curframe->verts[vertindex].v[1] * curframe->scale[1]) + curframe->translate[1]; DataTV[dtsize].v3[2]=(curframe->verts[vertindex].v[2] * curframe->scale[2]) + curframe->translate[2]; DataTV[dtsize].n3[0] =normaltable[curframe->verts[vertindex].normalindex][0]*inv; DataTV[dtsize].n3[1] =normaltable[curframe->verts[vertindex].normalindex][1]*inv; DataTV[dtsize].n3[2] =normaltable[curframe->verts[vertindex].normalindex][2]*inv; } if(sel_vert==2){ DataTV[dtsize].t2[0]=data->s; DataTV[dtsize].t2[1]=1.0-data->t; vertindex=data->index; DataTV[dtsize].v2[0]=(curframe->verts[vertindex].v[0] * curframe->scale[0]) + curframe->translate[0]; DataTV[dtsize].v2[1]=(curframe->verts[vertindex].v[1] * curframe->scale[1]) + curframe->translate[1]; DataTV[dtsize].v2[2]=(curframe->verts[vertindex].v[2] * curframe->scale[2]) + curframe->translate[2]; DataTV[dtsize].n2[0] =normaltable[curframe->verts[vertindex].normalindex][0]*inv; DataTV[dtsize].n2[1] =normaltable[curframe->verts[vertindex].normalindex][1]*inv; DataTV[dtsize].n2[2] =normaltable[curframe->verts[vertindex].normalindex][2]*inv; } if(vertnum>0){ if(sel_vert>2&&(sel_vert)%2){ dtsize=DataTV.size(); DataTV.resize(dtsize+1); DataTV[dtsize].texture=0; DataTV[dtsize].c1[0]=1.0;DataTV[dtsize].c1[1]=1.0;DataTV[dtsize].c1[2]=1.0; DataTV[dtsize].c3[0]=1.0;DataTV[dtsize].c3[1]=1.0;DataTV[dtsize].c3[2]=1.0; DataTV[dtsize].c2[0]=1.0;DataTV[dtsize].c2[1]=1.0;DataTV[dtsize].c2[2]=1.0; DataTV[dtsize].v1[0]=DataTV[dtsize-1].v2[0]; DataTV[dtsize].v1[1]=DataTV[dtsize-1].v2[1]; DataTV[dtsize].v1[2]=DataTV[dtsize-1].v2[2]; DataTV[dtsize].v3[0]=DataTV[dtsize-1].v3[0]; DataTV[dtsize].v3[1]=DataTV[dtsize-1].v3[1]; DataTV[dtsize].v3[2]=DataTV[dtsize-1].v3[2]; DataTV[dtsize].n1[0]=DataTV[dtsize-1].n2[0]; DataTV[dtsize].n1[1]=DataTV[dtsize-1].n2[1]; DataTV[dtsize].n1[2]=DataTV[dtsize-1].n2[2]; DataTV[dtsize].n3[0]=DataTV[dtsize-1].n3[0]; DataTV[dtsize].n3[1]=DataTV[dtsize-1].n3[1]; DataTV[dtsize].n3[2]=DataTV[dtsize-1].n3[2]; DataTV[dtsize].t1[0]=DataTV[dtsize-1].t2[0];DataTV[dtsize].t1[1]=DataTV[dtsize-1].t2[1]; DataTV[dtsize].t3[0]=DataTV[dtsize-1].t3[0];DataTV[dtsize].t3[1]=DataTV[dtsize-1].t3[1]; DataTV[dtsize].t2[0]=data->s; DataTV[dtsize].t2[1]=1.0-data->t; vertindex=data->index; DataTV[dtsize].v2[0]=(curframe->verts[vertindex].v[0] * curframe->scale[0]) + curframe->translate[0]; DataTV[dtsize].v2[1]=(curframe->verts[vertindex].v[1] * curframe->scale[1]) + curframe->translate[1]; DataTV[dtsize].v2[2]=(curframe->verts[vertindex].v[2] * curframe->scale[2]) + curframe->translate[2]; DataTV[dtsize].n2[0] =normaltable[curframe->verts[vertindex].normalindex][0]*inv; DataTV[dtsize].n2[1] =normaltable[curframe->verts[vertindex].normalindex][1]*inv; DataTV[dtsize].n2[2] =normaltable[curframe->verts[vertindex].normalindex][2]*inv; } if(sel_vert>2&&(sel_vert+1)%2){ dtsize=DataTV.size(); DataTV.resize(dtsize+1); DataTV[dtsize].texture=0; DataTV[dtsize].c1[0]=1.0;DataTV[dtsize].c1[1]=1.0;DataTV[dtsize].c1[2]=1.0; DataTV[dtsize].c3[0]=1.0;DataTV[dtsize].c3[1]=1.0;DataTV[dtsize].c3[2]=1.0; DataTV[dtsize].c2[0]=1.0;DataTV[dtsize].c2[1]=1.0;DataTV[dtsize].c2[2]=1.0; DataTV[dtsize].v1[0]=DataTV[dtsize-1].v1[0]; DataTV[dtsize].v1[1]=DataTV[dtsize-1].v1[1]; DataTV[dtsize].v1[2]=DataTV[dtsize-1].v1[2]; DataTV[dtsize].v3[0]=DataTV[dtsize-1].v2[0]; DataTV[dtsize].v3[1]=DataTV[dtsize-1].v2[1]; DataTV[dtsize].v3[2]=DataTV[dtsize-1].v2[2]; DataTV[dtsize].n1[0]=DataTV[dtsize-1].n1[0]; DataTV[dtsize].n1[1]=DataTV[dtsize-1].n1[1]; DataTV[dtsize].n1[2]=DataTV[dtsize-1].n1[2]; DataTV[dtsize].n3[0]=DataTV[dtsize-1].n2[0]; DataTV[dtsize].n3[1]=DataTV[dtsize-1].n2[1]; DataTV[dtsize].n3[2]=DataTV[dtsize-1].n2[2]; DataTV[dtsize].t1[0]=DataTV[dtsize-1].t1[0]; DataTV[dtsize].t1[1]=DataTV[dtsize-1].t1[1]; DataTV[dtsize].t3[0]=DataTV[dtsize-1].t2[0]; DataTV[dtsize].t3[1]=DataTV[dtsize-1].t2[1]; DataTV[dtsize].t2[0]=data->s; DataTV[dtsize].t2[1]=1.0-data->t; vertindex=data->index; DataTV[dtsize].v2[0]=(curframe->verts[vertindex].v[0] * curframe->scale[0]) + curframe->translate[0]; DataTV[dtsize].v2[1]=(curframe->verts[vertindex].v[1] * curframe->scale[1]) + curframe->translate[1]; DataTV[dtsize].v2[2]=(curframe->verts[vertindex].v[2] * curframe->scale[2]) + curframe->translate[2]; DataTV[dtsize].n2[0] =normaltable[curframe->verts[vertindex].normalindex][0]*inv; DataTV[dtsize].n2[1] =normaltable[curframe->verts[vertindex].normalindex][1]*inv; DataTV[dtsize].n2[2] =normaltable[curframe->verts[vertindex].normalindex][2]*inv; } }else{ if(sel_vert>2){ dtsize=DataTV.size(); DataTV.resize(dtsize+1); DataTV[dtsize].texture=0; DataTV[dtsize].c1[0]=1.0;DataTV[dtsize].c1[1]=1.0;DataTV[dtsize].c1[2]=1.0; DataTV[dtsize].c3[0]=1.0;DataTV[dtsize].c3[1]=1.0;DataTV[dtsize].c3[2]=1.0; DataTV[dtsize].c2[0]=1.0;DataTV[dtsize].c2[1]=1.0;DataTV[dtsize].c2[2]=1.0; DataTV[dtsize].v1[0]=DataTV[pindx].v1[0]; DataTV[dtsize].v1[1]=DataTV[pindx].v1[1]; DataTV[dtsize].v1[2]=DataTV[pindx].v1[2]; DataTV[dtsize].v3[0]=DataTV[dtsize-1].v2[0]; DataTV[dtsize].v3[1]=DataTV[dtsize-1].v2[1]; DataTV[dtsize].v3[2]=DataTV[dtsize-1].v2[2]; DataTV[dtsize].n1[0]=DataTV[pindx].n1[0]; DataTV[dtsize].n1[1]=DataTV[pindx].n1[1]; DataTV[dtsize].n1[2]=DataTV[pindx].n1[2]; DataTV[dtsize].n3[0]=DataTV[dtsize-1].n2[0]; DataTV[dtsize].n3[1]=DataTV[dtsize-1].n2[1]; DataTV[dtsize].n3[2]=DataTV[dtsize-1].n2[2]; DataTV[dtsize].t1[0]=DataTV[pindx].t1[0];DataTV[dtsize].t1[1]=DataTV[pindx].t1[1]; DataTV[dtsize].t3[0]=DataTV[dtsize-1].t2[0];DataTV[dtsize].t3[1]=DataTV[dtsize-1].t2[1]; DataTV[dtsize].t2[0]=data->s; DataTV[dtsize].t2[1]=1.0-data->t; vertindex=data->index; DataTV[dtsize].v2[0]=(curframe->verts[vertindex].v[0] * curframe->scale[0]) + curframe->translate[0]; DataTV[dtsize].v2[1]=(curframe->verts[vertindex].v[1] * curframe->scale[1]) + curframe->translate[1]; DataTV[dtsize].v2[2]=(curframe->verts[vertindex].v[2] * curframe->scale[2]) + curframe->translate[2]; DataTV[dtsize].n2[0] =normaltable[curframe->verts[vertindex].normalindex][0]*inv; DataTV[dtsize].n2[1] =normaltable[curframe->verts[vertindex].normalindex][1]*inv; DataTV[dtsize].n2[2] =normaltable[curframe->verts[vertindex].normalindex][2]*inv; } } sel_vert++; command+=3; } } /*}*/ /*delete [] frames; delete [] command; delete [] curframe;*/ fclose(fp); }else { statusBar()->showMessage( tr("Loading aborted"), 2000 ); } } #endif