X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=ABM2%2FAmaltheia%2Fmd2reader.cpp;fp=ABM2%2FAmaltheia%2Fmd2reader.cpp;h=1ce89632913b9a19cedef81c01a24d8614ddfd46;hb=9dae6dd1f05eed22b6ce5e75bd1e5893d5ee1ac6;hp=0000000000000000000000000000000000000000;hpb=0557fdb7b7567901ca7e82def55fe5ceab0ccef0;p=matthijs%2FABM2.git diff --git a/ABM2/Amaltheia/md2reader.cpp b/ABM2/Amaltheia/md2reader.cpp new file mode 100644 index 0000000..1ce8963 --- /dev/null +++ b/ABM2/Amaltheia/md2reader.cpp @@ -0,0 +1,679 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dimitris Saougos & Filippos Papadopoulos * + * * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * 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 A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library 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. * + ***************************************************************************/ + +#include "md2model.h" + +#include +#include +#include +#include +#include +// extern FILE *errorfp; + +struct vec3 +{ + float nx, ny, nz; +}; + +struct vec3 normalVectorArray[] = + { + { -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 } + }; + + + +model::model( char * md2_filename, char *bfilename, Graphics *g ) +{ + int i; + + modelTexture = new Texture( bfilename, g); + + graph = g; + + FILE *fp = fopen( md2_filename, "rb" ); + if ( fp == NULL ) + { + ok = false; + return ; + } + fread( ( void * ) & md2h, 1, sizeof( md2h ), fp ); + + tex1 = ( struct tex * ) malloc( sizeof( struct tex ) * md2h.numTexCoords ); + + fseek( fp, md2h.offsetTexCoords, SEEK_SET ); + fread( ( void * ) tex1, sizeof( struct tex ), md2h.numTexCoords, fp ); + + tc = ( struct texturecoord * ) malloc( sizeof( struct texturecoord ) * md2h.numTexCoords ); + + for ( i = 0;i < md2h.numTexCoords;i++ ) + { + tc[ i ].u = ( float ) ( tex1[ i ].u ) / ( float ) ( md2h.skinWidth ); + tc[ i ].v = ( float ) ( tex1[ i ].v ) / ( float ) ( md2h.skinHeight ); + } + free( tex1 ); + + fc = ( struct face * ) malloc( sizeof( struct face ) * md2h.numTriangles ); + + fseek( fp, md2h.offsetTriangles, 0 ); + fread ( ( void * ) fc, sizeof( struct face ), md2h.numTriangles, fp ); + + fseek( fp, md2h.offsetFrames, 0 ); + + fr = ( struct frame ** ) malloc( sizeof( struct frame * ) * md2h.numFrames ); + + for ( i = 0;i < md2h.numFrames;i++ ) + { + fr[ i ] = ( struct frame * ) malloc( sizeof( struct frame ) ); + fread( ( void * ) ( &( fr[ i ] ->scale[ 0 ] ) ), 3, sizeof( float ), fp ); + fread( ( void * ) ( &( fr[ i ] ->translate[ 0 ] ) ), 3, sizeof( float ), fp ); + fread( ( void * ) & ( fr[ i ] ->name[ 0 ] ), 1, sizeof( fr[ i ] ->name ), fp ); + fr[ i ] ->tr = ( struct triangle ** ) malloc( sizeof( struct triangle* ) * md2h.numVertices ); + int j; + for ( j = 0;j < md2h.numVertices;j++ ) + { + fr[ i ] ->tr[ j ] = ( struct triangle * ) malloc( sizeof( struct triangle ) ); + fread( ( void * ) & ( fr[ i ] ->tr[ j ] ->vertex[ 0 ] ), 3, sizeof( BYTE ), fp ); + fread( ( void * ) & ( fr[ i ] ->tr[ j ] ->lightNormalIndex ), 1, sizeof( BYTE ), fp ); + } + + } + + // fhead=NULL; + // ftail=NULL; + + ok = true; + change = false; + + mark = NULL; + + FPS = 200.0f; + + // v = ( struct vertex * ) malloc( sizeof( struct vertex ) * ( md2h.numTriangles + 5 ) * 3 ); + /* 12 einai to plh8os twn floats (vertices, normals, colour ktl*/ + v = new GLfloat[12 * ( md2h.numTriangles + 5 ) * 3]; + return ; +} + + + +model::~model( void ) +{ + free( tc ); + free( fc ); + + int i, j; + for ( i = 0;i < md2h.numFrames;i++ ) + { + for ( j = 0;j < md2h.numVertices;j++ ) + free ( fr[ i ] ->tr[ j ] ); + free( fr[ i ] ->tr ); + free( fr[ i ] ); + } + + delete modelTexture; + + free( fr ); + delete[] v ; + + return ; +} + + + + + +void model::render( float t ) +{ + int i; + int j = 0; + /* + if (mark!=NULL) + (*mark)=false; + + if (mark!=NULL && strcmp(current_frame_sequence,"run")==0 && + (cpointer->fnumber-current_offset==3 || + cpointer->fnumber-current_offset==0)) + (*mark)=true; + + t=gettime(); + if (oldt>t) cpointer=cpointer->next; + oldt=t; + + graph->setTexture(modelTexture); + */ + for ( i = 0;i < md2h.numTriangles;i++ ) + { + int k; + + for ( k = 0;k < 3;k++ ) + { + int p = fc[ i ].vindex[ k ]; + BYTE x, y, z; + float xx, yy, zz; + float nx1, ny1, nz1; + + framecounter = cpointer->fnumber; + + x = fr[ framecounter ] ->tr[ p ] ->vertex[ 0 ]; + y = fr[ framecounter ] ->tr[ p ] ->vertex[ 1 ]; + z = fr[ framecounter ] ->tr[ p ] ->vertex[ 2 ]; + + xx = ( float ) x * fr[ framecounter ] ->scale[ 0 ]; + yy = ( float ) y * fr[ framecounter ] ->scale[ 1 ]; + zz = ( float ) z * fr[ framecounter ] ->scale[ 2 ]; + + xx = xx + fr[ framecounter ] ->translate[ 0 ]; + yy = yy + fr[ framecounter ] ->translate[ 1 ]; + zz = zz + fr[ framecounter ] ->translate[ 2 ]; + + + nx1 = normalVectorArray[ fr[ framecounter ] ->tr[ p ] ->lightNormalIndex ].nx; + ny1 = normalVectorArray[ fr[ framecounter ] ->tr[ p ] ->lightNormalIndex ].ny; + nz1 = normalVectorArray[ fr[ framecounter ] ->tr[ p ] ->lightNormalIndex ].nz; + + + float xx1, yy1, zz1; + float nx2, ny2, nz2; + + framecounter = cpointer->next->fnumber; + + x = fr[ framecounter ] ->tr[ p ] ->vertex[ 0 ]; + y = fr[ framecounter ] ->tr[ p ] ->vertex[ 1 ]; + z = fr[ framecounter ] ->tr[ p ] ->vertex[ 2 ]; + + xx1 = ( float ) x * fr[ framecounter ] ->scale[ 0 ]; + yy1 = ( float ) y * fr[ framecounter ] ->scale[ 1 ]; + zz1 = ( float ) z * fr[ framecounter ] ->scale[ 2 ]; + + xx1 = xx1 + fr[ framecounter ] ->translate[ 0 ]; + yy1 = yy1 + fr[ framecounter ] ->translate[ 1 ]; + zz1 = zz1 + fr[ framecounter ] ->translate[ 2 ]; + + nx2 = normalVectorArray[ fr[ framecounter ] ->tr[ p ] ->lightNormalIndex ].nx; + ny2 = normalVectorArray[ fr[ framecounter ] ->tr[ p ] ->lightNormalIndex ].ny; + nz2 = normalVectorArray[ fr[ framecounter ] ->tr[ p ] ->lightNormalIndex ].nz; + + + p = fc[ i ].tindex[ k ]; + + v[ 12 * j] = tc[ p ].u; + v[ 12 * j + 1] = 0.0 - tc[ p ].v; + + v[ 12 * j + 2] = 1.0; + v[ 12 * j + 3] = 1.0; + v[ 12 * j + 4] = 1.0; + v[ 12 * j + 5] = 1.0; + + v[ 12 * j + 6] = nx1 + t * ( nx2 - nx1 ); + v[ 12 * j + 7] = nz1 + t * ( nz2 - nz1 ); + v[ 12 * j + 8] = ny1 + t * ( ny2 - ny1 ); + + v[ 12 * j + 9] = xx + t * ( xx1 - xx ); + v[ 12 * j + 10] = zz + t * ( zz1 - zz ); + v[ 12 * j + 11] = yy + t * ( yy1 - yy ); + + + j++; + } + } + i = 0; + + // graph->renderMd2(v, (md2h.numTriangles+5)*3); + graph->setTexture( modelTexture ); + unsigned int numOfTris = ( md2h.numTriangles + 5 ) * 3; +// if ( graph->getAlpha() ) + // glDisable( GL_DEPTH_TEST ); + + //graph->setAlpha(true); + + +// graph->renderTriangles(AM_TRIANGLES, v, numOfTris); + graph->renderVertexArray((vertex *)v, numOfTris, AM_TRIANGLES); + + + //if ( graph->getAlpha() ) +// glEnable( GL_DEPTH_TEST ); +// glDisable(GL_DEPTH_TEST); + + return ; +} + + + + + +/* + +void model::delframelist(void) +{ + fnode *tmp; + fnode *tmp1; + + if (fhead!=NULL) + { + + tmp=fhead->next; + tmp1=fhead; + + if (fhead->next==fhead) + { + free(fhead); + fhead=NULL; + ftail=NULL; + } + else + { + while(1) + { + if (tmp==fhead) break; + free(tmp1); + tmp1=tmp; + tmp=tmp->next; + } + free(tmp1); + } + fhead=NULL; + ftail=NULL; + } + framecounter=-1; + nframes=-1; + return ; +} +*/ + +/* +void model::setframesequence(char *name) +{ + fnode *tmp; + int i, j; + + minMax = true; + + delframelist(); + + nframes=0; + for (i=0;iname,name)!=NULL) + { + + for (j=0; j < md2h.numTriangles; j++) + { + float x,y,z; + int k; + for (k=0;k<3;k++) + { + int p=fc[j].vindex[k]; + x=fr[i]->tr[p]->vertex[0]*fr[i]->scale[0]+fr[i]->translate[0]; + y=fr[i]->tr[p]->vertex[1]*fr[i]->scale[1]+fr[i]->translate[1]; + z=fr[i]->tr[p]->vertex[2]*fr[i]->scale[2]+fr[i]->translate[2]; + + if (x>xmax) xmax=x; + if (xymax) zmax=z; + if (zzmax) ymax=y; + } + } + tmp=(fnode *)malloc(sizeof(fnode)); + tmp->fnumber=i; + tmp->next=NULL; + if (fhead==NULL) + { + fhead=tmp; + ftail=tmp; + current_offset=tmp->fnumber; + } + else + { + ftail->next=tmp; + ftail=tmp; + } + nframes++; + } + } + framecounter=0; + if (fhead==NULL) + { + framecounter=-1; + return ; + } + + cpointer=fhead; + current_frame_sequence=name; + ftail->next=fhead; + oldt=0.0f; + + return ; +} + +*/ + +int model::getframecounter( void ) +{ + return framecounter; +} + + + +c_model::c_model( model *m ) +{ + mod = m; + FPS = mod->FPS; + + fhead = NULL; + ftail = NULL; + + return ; +} + +void c_model::setFrameSequence( char *name ) +{ + fnode * tmp; + int i; + + delFrameSequence(); + + xmin = 0;ymin = 0;zmin = 0; + xmax = 0;ymax = 0;zmax = 0; + + nframes = 0; + for ( i = 0;i < mod->md2h.numFrames;i++ ) + { + if ( strstr( mod->fr[ i ] ->name, name ) != NULL ) + { + tmp = ( fnode * ) malloc( sizeof( fnode ) ); + tmp->fnumber = i; + tmp->next = NULL; + if ( fhead == NULL ) + { + fhead = tmp; + ftail = tmp; + } + else + { + ftail->next = tmp; + ftail = tmp; + } + nframes++; + for ( int j = 0;j < mod->md2h.numTriangles;j++ ) + { + float x, y, z; + for ( int k = 0;k < 3;k++ ) + { + int p = mod->fc[ j ].vindex[ k ]; + + + x = mod->fr[ i ] ->tr[ p ] ->vertex[ 0 ] * mod->fr[ i ] ->scale[ 0 ] + mod->fr[ i ] ->translate[ 0 ]; + + + y = mod->fr[ i ] ->tr[ p ] ->vertex[ 2 ] * mod->fr[ i ] ->scale[ 2 ] + mod->fr[ i ] ->translate[ 2 ]; + + + z = mod->fr[ i ] ->tr[ p ] ->vertex[ 1 ] * mod->fr[ i ] ->scale[ 1 ] + mod->fr[ i ] ->translate[ 1 ]; + if ( x < xmin ) xmin = x; + if ( x > xmax ) xmax = x; + if ( y < ymin ) ymin = y; + if ( y > ymax ) ymax = y; + if ( z < zmin ) zmin = z; + if ( z > zmax ) zmax = z; + } + } + } + } + if ( fhead == NULL ) + { + cpointer = NULL; + return ; + } + + cpointer = fhead; + current_frame_sequence = name; + ftail->next = fhead; + oldt = 0.0f; + + return ; +} + +void c_model::delFrameSequence( void ) +{ + fnode * tmp; + fnode *tmp1; + + if ( fhead != NULL ) + { + + tmp = fhead->next; + tmp1 = fhead; + + if ( fhead->next == fhead ) + { + free( fhead ); + fhead = NULL; + ftail = NULL; + } + else + { + while ( 1 ) + { + if ( tmp == fhead ) break; + free( tmp1 ); + tmp1 = tmp; + tmp = tmp->next; + } + free( tmp1 ); + } + fhead = NULL; + ftail = NULL; + } + nframes = -1; + return ; +} + +void c_model::render() +{ + float t; + t = gettime(); + if ( oldt > t ) cpointer = cpointer->next; + oldt = t; + + mod->cpointer = cpointer; + mod->render( t ); + return ; +} + + + +float c_model::gettime( void ) +{ + int k = SDL_GetTicks(); + k = k % ( ( int ) ( FPS + 1.0f ) ); + return ( float ) k / ( float ) FPS; +} + + +c_model::~c_model( void ) +{ + delFrameSequence(); + return ; +} +