X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=tools%2Fquake2%2Fqdata_heretic2%2Ffmodels.c;h=a3e06c0b9f29649f91c527accc3728f2767c02e6;hb=e4287c28bb2dafedc81c66e63951d947cfbeb225;hp=7570240ac50a2ece1e1175fae0b2edf1609c6905;hpb=203343b01a7ad87cb3d136689c9936ff5bc23c01;p=xonotic%2Fnetradiant.git diff --git a/tools/quake2/qdata_heretic2/fmodels.c b/tools/quake2/qdata_heretic2/fmodels.c index 7570240a..a3e06c0b 100644 --- a/tools/quake2/qdata_heretic2/fmodels.c +++ b/tools/quake2/qdata_heretic2/fmodels.c @@ -1,23 +1,23 @@ /* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant 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. + GtkRadiant 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 General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "qd_fmodel.h" #include "animcomp.h" @@ -30,34 +30,34 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include /* -======================================================================== + ======================================================================== -.FM triangle flexible model file format + .FM triangle flexible model file format -======================================================================== -*/ + ======================================================================== + */ //================================================================= -#define NUMVERTEXNORMALS 162 +#define NUMVERTEXNORMALS 162 -extern float avertexnormals[NUMVERTEXNORMALS][3]; +extern float avertexnormals[NUMVERTEXNORMALS][3]; -#define MAX_GROUPS 128 +#define MAX_GROUPS 128 typedef struct { - triangle_t triangle; - int group; + triangle_t triangle; + int group; } trigroup_t; -#define TRIVERT_DIST .1 +#define TRIVERT_DIST .1 typedef struct { - int start_frame; - int num_frames; - int degrees; + int start_frame; + int num_frames; + int degrees; char *mat; char *ccomp; char *cbase; @@ -72,90 +72,89 @@ typedef struct //================================================================ // Initial -fmheader_t fmheader; +fmheader_t fmheader; // Skin -extern char g_skins[MAX_FM_SKINS][64]; +extern char g_skins[MAX_FM_SKINS][64]; // ST Coord -extern fmstvert_t base_st[MAX_FM_VERTS]; +extern fmstvert_t base_st[MAX_FM_VERTS]; // Triangles -extern fmtriangle_t triangles[MAX_FM_TRIANGLES]; +extern fmtriangle_t triangles[MAX_FM_TRIANGLES]; // Frames -fmframe_t g_frames[MAX_FM_FRAMES]; +fmframe_t g_frames[MAX_FM_FRAMES]; //fmframe_t *g_FMframes; // GL Commands -extern int commands[16384]; -extern int numcommands; +extern int commands[16384]; +extern int numcommands; // // varibles set by commands // -extern float scale_up; // set by $scale -extern vec3_t adjust; // set by $origin -extern int g_fixedwidth, g_fixedheight; // set by $skinsize -extern char modelname[64]; // set by $modelname +extern float scale_up; // set by $scale +extern vec3_t adjust; // set by $origin +extern int g_fixedwidth, g_fixedheight; // set by $skinsize +extern char modelname[64]; // set by $modelname -extern char *g_outputDir; +extern char *g_outputDir; // Mesh Nodes -mesh_node_t *pmnodes = NULL; -fmmeshnode_t mesh_nodes[MAX_FM_MESH_NODES]; +mesh_node_t *pmnodes = NULL; +fmmeshnode_t mesh_nodes[MAX_FM_MESH_NODES]; -fmgroup_t groups[MAX_GROUPS]; -int num_groups; -int frame_to_group[MAX_FM_FRAMES]; +fmgroup_t groups[MAX_GROUPS]; +int num_groups; +int frame_to_group[MAX_FM_FRAMES]; // // variables set by command line arguments // -qboolean g_no_opimizations = false; +qboolean g_no_opimizations = false; // // base frame info // -static int triangle_st[MAX_FM_TRIANGLES][3][2]; +static int triangle_st[MAX_FM_TRIANGLES][3][2]; // number of gl vertices -extern int numglverts; +extern int numglverts; // indicates if a triangle has already been used in a glcmd -extern int used[MAX_FM_TRIANGLES]; +extern int used[MAX_FM_TRIANGLES]; // indicates if a triangle has translucency in it or not -static qboolean translucent[MAX_FM_TRIANGLES]; +static qboolean translucent[MAX_FM_TRIANGLES]; // main output file handle -extern FILE *headerouthandle; +extern FILE *headerouthandle; // output sizes of buildst() -static int skin_width, skin_height; +static int skin_width, skin_height; // statistics -static int total_skin_pixels; -static int skin_pixels_used; +static int total_skin_pixels; +static int skin_pixels_used; -int ShareVertex( trigroup_t trione, trigroup_t tritwo); -float DistBetween(vec3_t point1, vec3_t point2); -int GetNumTris( trigroup_t *tris, int group); -void GetOneGroup(trigroup_t *tris, int grp, triangle_t* triangles); -void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts); -void NewDrawLine(int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height); +int ShareVertex( trigroup_t trione, trigroup_t tritwo ); +float DistBetween( vec3_t point1, vec3_t point2 ); +int GetNumTris( trigroup_t *tris, int group ); +void GetOneGroup( trigroup_t *tris, int grp, triangle_t* triangles ); +void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts ); +void NewDrawLine( int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height ); #ifndef _WIN32 -void strupr(char *string) -{ +void strupr( char *string ){ int i; - for (i=0 ; iverts[fmheader.num_xyz]; + fmheader.framesize = (int)&( (fmaliasframe_t *)0 )->verts[fmheader.num_xyz]; - WriteHeader(modelouthandle, FM_HEADER_NAME, FM_HEADER_VER, sizeof(fmheader), &fmheader); + WriteHeader( modelouthandle, FM_HEADER_NAME, FM_HEADER_VER, sizeof( fmheader ), &fmheader ); // // write out the skin names // - WriteHeader(modelouthandle, FM_SKIN_NAME, FM_SKIN_VER, fmheader.num_skins * MAX_FM_SKINNAME, g_skins); + WriteHeader( modelouthandle, FM_SKIN_NAME, FM_SKIN_VER, fmheader.num_skins * MAX_FM_SKINNAME, g_skins ); // // write out the texture coordinates // c_on = c_off = 0; - for (i=0 ; iname, in->name); - for (j=0 ; j<3 ; j++) + strcpy( out->name, in->name ); + for ( j = 0 ; j < 3 ; j++ ) { - out->scale[j] = (in->maxs[j] - in->mins[j])/255; + out->scale[j] = ( in->maxs[j] - in->mins[j] ) / 255; out->translate[j] = in->mins[j]; outFrames[i].scale[j] = out->scale[j]; outFrames[i].translate[j] = out->translate[j]; } - for (j=0 ; jverts[j].lightnormalindex = in->v[j].lightnormalindex; - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { - // scale to byte values & min/max check - v = Q_rint ( (in->v[j].v[k] - out->translate[k]) / out->scale[k] ); + // scale to byte values & min/max check + v = Q_rint( ( in->v[j].v[k] - out->translate[k] ) / out->scale[k] ); - // clamp, so rounding doesn't wrap from 255.6 to 0 - if (v > 255.0) + // clamp, so rounding doesn't wrap from 255.6 to 0 + if ( v > 255.0 ) { v = 255.0; - if (v < 0) + } + if ( v < 0 ) { v = 0; + } out->verts[j].v[k] = v; } } - for (j=0 ; j<3 ; j++) + for ( j = 0 ; j < 3 ; j++ ) { - out->scale[j] = LittleFloat (out->scale[j]); - out->translate[j] = LittleFloat (out->translate[j]); + out->scale[j] = LittleFloat( out->scale[j] ); + out->translate[j] = LittleFloat( out->translate[j] ); } - SafeWrite (modelouthandle, out, fmheader.framesize); + SafeWrite( modelouthandle, out, fmheader.framesize ); } // Go back and finish the header - // WriteHeader(modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, -1, NULL); + // WriteHeader(modelouthandle, FM_FRAME_NAME, FM_FRAME_VER, -1, NULL); } else { - WriteHeader(modelouthandle, FM_SHORT_FRAME_NAME, FM_SHORT_FRAME_VER,FRAME_NAME_LEN*fmheader.num_frames, NULL); - for (i=0 ; iname,FRAME_NAME_LEN); + SafeWrite( modelouthandle,in->name,FRAME_NAME_LEN ); } - WriteHeader(modelouthandle, FM_NORMAL_NAME, FM_NORMAL_VER,fmheader.num_xyz, NULL); + WriteHeader( modelouthandle, FM_NORMAL_NAME, FM_NORMAL_VER,fmheader.num_xyz, NULL ); in = &g_frames[0]; - for (j=0 ; jv[j].lightnormalindex,1); + for ( j = 0 ; j < fmheader.num_xyz ; j++ ) + SafeWrite( modelouthandle,&in->v[j].lightnormalindex,1 ); } // // write out glcmds // - WriteHeader(modelouthandle, FM_GLCMDS_NAME, FM_GLCMDS_VER, numcommands*4, commands); + WriteHeader( modelouthandle, FM_GLCMDS_NAME, FM_GLCMDS_VER, numcommands * 4, commands ); // // write out mesh nodes // - for(i=0;idegrees*sizeof(char) - char *ccomp; g->num_frames*g->degrees*sizeof(char) - char *cbase; fmheader.num_xyz*3*sizeof(unsigned char) - float *cscale; g->degrees*sizeof(float) - float *coffset; g->degrees*sizeof(float) - float trans[3]; 3*sizeof(float) - float scale[3]; 3*sizeof(float) -} fmgroup_t; -*/ + typedef struct + { + int start_frame; + int num_frames; + int degrees; + char *mat; fmheader.num_xyz*3*g->degrees*sizeof(char) + char *ccomp; g->num_frames*g->degrees*sizeof(char) + char *cbase; fmheader.num_xyz*3*sizeof(unsigned char) + float *cscale; g->degrees*sizeof(float) + float *coffset; g->degrees*sizeof(float) + float trans[3]; 3*sizeof(float) + float scale[3]; 3*sizeof(float) + } fmgroup_t; + */ int tmp,k; fmgroup_t *g; - size=sizeof(int)+fmheader.num_frames*sizeof(int); - for (k=0;kdegrees*sizeof(char); - size+=g->num_frames*g->degrees*sizeof(char); - size+=fmheader.num_xyz*3*sizeof(unsigned char); - size+=g->degrees*sizeof(float); - size+=g->degrees*sizeof(float); - size+=12*sizeof(float); - } - WriteHeader(modelouthandle, FM_COMP_NAME, FM_COMP_VER,size, NULL); - SafeWrite (modelouthandle,&num_groups,sizeof(int)); - SafeWrite (modelouthandle,frame_to_group,sizeof(int)*fmheader.num_frames); - - for (k=0;kstart_frame); - SafeWrite (modelouthandle,&tmp,sizeof(int)); - tmp=LittleLong(g->num_frames); - SafeWrite (modelouthandle,&tmp,sizeof(int)); - tmp=LittleLong(g->degrees); - SafeWrite (modelouthandle,&tmp,sizeof(int)); - - SafeWrite (modelouthandle,g->mat,fmheader.num_xyz*3*g->degrees*sizeof(char)); - SafeWrite (modelouthandle,g->ccomp,g->num_frames*g->degrees*sizeof(char)); - SafeWrite (modelouthandle,g->cbase,fmheader.num_xyz*3*sizeof(unsigned char)); - SafeWrite (modelouthandle,g->cscale,g->degrees*sizeof(float)); - SafeWrite (modelouthandle,g->coffset,g->degrees*sizeof(float)); - SafeWrite (modelouthandle,g->trans,3*sizeof(float)); - SafeWrite (modelouthandle,g->scale,3*sizeof(float)); - SafeWrite (modelouthandle,g->bmin,3*sizeof(float)); - SafeWrite (modelouthandle,g->bmax,3*sizeof(float)); - free(g->mat); - free(g->ccomp); - free(g->cbase); - free(g->cscale); - free(g->coffset); + size = sizeof( int ) + fmheader.num_frames * sizeof( int ); + for ( k = 0; k < num_groups; k++ ) + { + g = &groups[k]; + size += sizeof( int ) * 3; + size += fmheader.num_xyz * 3 * g->degrees * sizeof( char ); + size += g->num_frames * g->degrees * sizeof( char ); + size += fmheader.num_xyz * 3 * sizeof( unsigned char ); + size += g->degrees * sizeof( float ); + size += g->degrees * sizeof( float ); + size += 12 * sizeof( float ); + } + WriteHeader( modelouthandle, FM_COMP_NAME, FM_COMP_VER,size, NULL ); + SafeWrite( modelouthandle,&num_groups,sizeof( int ) ); + SafeWrite( modelouthandle,frame_to_group,sizeof( int ) * fmheader.num_frames ); + + for ( k = 0; k < num_groups; k++ ) + { + g = &groups[k]; + tmp = LittleLong( g->start_frame ); + SafeWrite( modelouthandle,&tmp,sizeof( int ) ); + tmp = LittleLong( g->num_frames ); + SafeWrite( modelouthandle,&tmp,sizeof( int ) ); + tmp = LittleLong( g->degrees ); + SafeWrite( modelouthandle,&tmp,sizeof( int ) ); + + SafeWrite( modelouthandle,g->mat,fmheader.num_xyz * 3 * g->degrees * sizeof( char ) ); + SafeWrite( modelouthandle,g->ccomp,g->num_frames * g->degrees * sizeof( char ) ); + SafeWrite( modelouthandle,g->cbase,fmheader.num_xyz * 3 * sizeof( unsigned char ) ); + SafeWrite( modelouthandle,g->cscale,g->degrees * sizeof( float ) ); + SafeWrite( modelouthandle,g->coffset,g->degrees * sizeof( float ) ); + SafeWrite( modelouthandle,g->trans,3 * sizeof( float ) ); + SafeWrite( modelouthandle,g->scale,3 * sizeof( float ) ); + SafeWrite( modelouthandle,g->bmin,3 * sizeof( float ) ); + SafeWrite( modelouthandle,g->bmax,3 * sizeof( float ) ); + free( g->mat ); + free( g->ccomp ); + free( g->cbase ); + free( g->cscale ); + free( g->coffset ); } } // write the skeletal info - if(g_skelModel.type != SKEL_NULL) - { + if ( g_skelModel.type != SKEL_NULL ) { size = 0; - temp = sizeof(int); // change this to a byte - memcpy(data + size, &g_skelModel.type, temp); + temp = sizeof( int ); // change this to a byte + memcpy( data + size, &g_skelModel.type, temp ); size += temp; // number of joints - temp = sizeof(int); // change this to a byte - memcpy(data + size, &numJointsInSkeleton[g_skelModel.type], temp); + temp = sizeof( int ); // change this to a byte + memcpy( data + size, &numJointsInSkeleton[g_skelModel.type], temp ); size += temp; // number of verts in each joint cluster - temp = sizeof(int)*numJointsInSkeleton[g_skelModel.type]; // change this to shorts - memcpy(data + size, &g_skelModel.new_num_verts[1], temp); + temp = sizeof( int ) * numJointsInSkeleton[g_skelModel.type]; // change this to shorts + memcpy( data + size, &g_skelModel.new_num_verts[1], temp ); size += temp; // cluster verts - for(i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i) + for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i ) { current = g_skelModel.vertLists[i]; - while(current) + while ( current ) { - temp = sizeof(int); // change this to a short - memcpy(data + size, ¤t->data, temp); + temp = sizeof( int ); // change this to a short + memcpy( data + size, ¤t->data, temp ); size += temp; toFree = current; current = current->next; - free(toFree); // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base + free( toFree ); // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base } } - if(!num_groups) // joints are stored with regular verts for compressed models - { + if ( !num_groups ) { // joints are stored with regular verts for compressed models framesWritten = true; - temp = sizeof(int); // change this to a byte - memcpy(data + size, &framesWritten, temp); + temp = sizeof( int ); // change this to a byte + memcpy( data + size, &framesWritten, temp ); size += temp; - for (i = 0; i < fmheader.num_frames; ++i) + for ( i = 0; i < fmheader.num_frames; ++i ) { in = &g_frames[i]; - for (j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j) + for ( j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j ) { - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { // scale to byte values & min/max check - v = Q_rint ( (in->joints[j].placement.origin[k] - outFrames[i].translate[k]) / outFrames[i].scale[k] ); + v = Q_rint( ( in->joints[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] ); // write out origin as a float since they arn't clamped - temp = sizeof(float); // change this to a short - assert(size+temp < DATA_SIZE); - memcpy(data + size, &v, temp); + temp = sizeof( float ); // change this to a short + assert( size + temp < DATA_SIZE ); + memcpy( data + size, &v, temp ); size += temp; } - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { - v = Q_rint ( (in->joints[j].placement.direction[k] - outFrames[i].translate[k]) / outFrames[i].scale[k] ); + v = Q_rint( ( in->joints[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] ); // write out origin as a float since they arn't clamped - temp = sizeof(float); // change this to a short - assert(size+temp < DATA_SIZE); - memcpy(data + size, &v, temp); + temp = sizeof( float ); // change this to a short + assert( size + temp < DATA_SIZE ); + memcpy( data + size, &v, temp ); size += temp; } - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { - v = Q_rint ( (in->joints[j].placement.up[k] - outFrames[i].translate[k]) / outFrames[i].scale[k] ); + v = Q_rint( ( in->joints[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] ); // write out origin as a float since they arn't clamped - temp = sizeof(float); // change this to a short - assert(size+temp < DATA_SIZE); - memcpy(data + size, &v, temp); + temp = sizeof( float ); // change this to a short + assert( size + temp < DATA_SIZE ); + memcpy( data + size, &v, temp ); size += temp; } } @@ -541,169 +529,162 @@ typedef struct } else { - temp = sizeof(int); // change this to a byte - memcpy(data + size, &framesWritten, temp); + temp = sizeof( int ); // change this to a byte + memcpy( data + size, &framesWritten, temp ); size += temp; } - WriteHeader(modelouthandle, FM_SKELETON_NAME, FM_SKELETON_VER, size, data); + WriteHeader( modelouthandle, FM_SKELETON_NAME, FM_SKELETON_VER, size, data ); } - if(g_skelModel.references != REF_NULL) - { + if ( g_skelModel.references != REF_NULL ) { int refnum; size = 0; - if (RefPointNum <= 0) - { // Hard-coded labels + if ( RefPointNum <= 0 ) { // Hard-coded labels refnum = numReferences[g_skelModel.references]; } else - { // Labels indicated in QDT + { // Labels indicated in QDT refnum = RefPointNum; } - temp = sizeof(int); // change this to a byte - memcpy(data2 + size, &g_skelModel.references, temp); + temp = sizeof( int ); // change this to a byte + memcpy( data2 + size, &g_skelModel.references, temp ); size += temp; - if(!num_groups) - { + if ( !num_groups ) { framesWritten = true; - temp = sizeof(int); // change this to a byte - memcpy(data2 + size, &framesWritten, temp); + temp = sizeof( int ); // change this to a byte + memcpy( data2 + size, &framesWritten, temp ); size += temp; - for (i = 0; i < fmheader.num_frames; ++i) + for ( i = 0; i < fmheader.num_frames; ++i ) { in = &g_frames[i]; - for (j = 0 ; j < refnum; ++j) + for ( j = 0 ; j < refnum; ++j ) { - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { // scale to byte values & min/max check - v = Q_rint ( (in->references[j].placement.origin[k] - outFrames[i].translate[k]) / outFrames[i].scale[k] ); + v = Q_rint( ( in->references[j].placement.origin[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] ); // write out origin as a float since they arn't clamped - temp = sizeof(float); // change this to a short - assert(size+temp < DATA_SIZE); - memcpy(data2 + size, &v, temp); + temp = sizeof( float ); // change this to a short + assert( size + temp < DATA_SIZE ); + memcpy( data2 + size, &v, temp ); size += temp; } - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { - v = Q_rint ( (in->references[j].placement.direction[k] - outFrames[i].translate[k]) / outFrames[i].scale[k] ); + v = Q_rint( ( in->references[j].placement.direction[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] ); // write out origin as a float since they arn't clamped - temp = sizeof(float); // change this to a short - assert(size+temp < DATA_SIZE); - memcpy(data2 + size, &v, temp); + temp = sizeof( float ); // change this to a short + assert( size + temp < DATA_SIZE ); + memcpy( data2 + size, &v, temp ); size += temp; } - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { - v = Q_rint ( (in->references[j].placement.up[k] - outFrames[i].translate[k]) / outFrames[i].scale[k] ); + v = Q_rint( ( in->references[j].placement.up[k] - outFrames[i].translate[k] ) / outFrames[i].scale[k] ); // write out origin as a float since they arn't clamped - temp = sizeof(float); // change this to a short - assert(size+temp < DATA_SIZE); - memcpy(data2 + size, &v, temp); + temp = sizeof( float ); // change this to a short + assert( size + temp < DATA_SIZE ); + memcpy( data2 + size, &v, temp ); size += temp; } } } } - else // FINISH ME: references need to be stored with regular verts for compressed models + else // FINISH ME: references need to be stored with regular verts for compressed models { framesWritten = false; - temp = sizeof(int); // change this to a byte - memcpy(data2 + size, &framesWritten, temp); + temp = sizeof( int ); // change this to a byte + memcpy( data2 + size, &framesWritten, temp ); size += temp; } - WriteHeader(modelouthandle, FM_REFERENCES_NAME, FM_REFERENCES_VER, size, data2); + WriteHeader( modelouthandle, FM_REFERENCES_NAME, FM_REFERENCES_VER, size, data2 ); } } -static void CompressFrames() -{ +static void CompressFrames(){ fmgroup_t *g; int i,j,k; - fmframe_t *in; + fmframe_t *in; - j=0; - for (i=0;i=groups[j].start_frame+groups[j].num_frames&&j= groups[j].start_frame + groups[j].num_frames && j < num_groups - 1 ) j++; - frame_to_group[i]=j; + frame_to_group[i] = j; } - for (k=0;knum_frames,fmheader.num_xyz,g->degrees); - for (i=0;inum_frames;i++) + printf( "\nCompressing Frames for group %i...\n", k ); + AnimCompressInit( g->num_frames,fmheader.num_xyz,g->degrees ); + for ( i = 0; i < g->num_frames; i++ ) { - in = &g_frames[i+g->start_frame]; - for (j=0;jv[j].v[0],in->v[j].v[1],in->v[j].v[2]); + in = &g_frames[i + g->start_frame]; + for ( j = 0; j < fmheader.num_xyz; j++ ) + AnimSetFrame( i,j,in->v[j].v[0],in->v[j].v[1],in->v[j].v[2] ); } AnimCompressDoit(); - g->mat= (char *) SafeMalloc(fmheader.num_xyz*3*g->degrees*sizeof(char), "CompressFrames"); - g->ccomp=(char *) SafeMalloc(g->num_frames*g->degrees*sizeof(char), "CompressFrames"); - g->cbase=(char *) SafeMalloc(fmheader.num_xyz*3*sizeof(unsigned char), "CompressFrames"); - g->cscale=(float *) SafeMalloc(g->degrees*sizeof(float), "CompressFrames"); - g->coffset=(float *) SafeMalloc(g->degrees*sizeof(float), "CompressFrames"); - AnimCompressToBytes(g->trans,g->scale,g->mat,g->ccomp,g->cbase,g->cscale,g->coffset,g->bmin,g->bmax); + g->mat = (char *) SafeMalloc( fmheader.num_xyz * 3 * g->degrees * sizeof( char ), "CompressFrames" ); + g->ccomp = (char *) SafeMalloc( g->num_frames * g->degrees * sizeof( char ), "CompressFrames" ); + g->cbase = (char *) SafeMalloc( fmheader.num_xyz * 3 * sizeof( unsigned char ), "CompressFrames" ); + g->cscale = (float *) SafeMalloc( g->degrees * sizeof( float ), "CompressFrames" ); + g->coffset = (float *) SafeMalloc( g->degrees * sizeof( float ), "CompressFrames" ); + AnimCompressToBytes( g->trans,g->scale,g->mat,g->ccomp,g->cbase,g->cscale,g->coffset,g->bmin,g->bmax ); AnimCompressEnd(); } } -static void OptimizeVertices(void) -{ - qboolean vert_used[MAX_FM_VERTS]; - short vert_replacement[MAX_FM_VERTS]; - int i,j,k,l,pos,bit,set_pos,set_bit; - fmframe_t *in; - qboolean Found; - int num_unique; +static void OptimizeVertices( void ){ + qboolean vert_used[MAX_FM_VERTS]; + short vert_replacement[MAX_FM_VERTS]; + int i,j,k,l,pos,bit,set_pos,set_bit; + fmframe_t *in; + qboolean Found; + int num_unique; static IntListNode_t *newVertLists[NUM_CLUSTERS]; static int newNum_verts[NUM_CLUSTERS]; IntListNode_t *current, *next; - printf("Optimizing vertices..."); + printf( "Optimizing vertices..." ); - memset(vert_used, 0, sizeof(vert_used)); + memset( vert_used, 0, sizeof( vert_used ) ); - if(g_skelModel.clustered == true) - { - memset(newNum_verts, 0, sizeof(newNum_verts)); - memset(newVertLists, 0, sizeof(newVertLists)); + if ( g_skelModel.clustered == true ) { + memset( newNum_verts, 0, sizeof( newNum_verts ) ); + memset( newVertLists, 0, sizeof( newVertLists ) ); } num_unique = 0; // search for common points among all the frames - for (i=0 ; iv[j].v[0] == in->v[k].v[0] && - in->v[j].v[1] == in->v[k].v[1] && - in->v[j].v[2] == in->v[k].v[2]) - { + for ( k = 0,Found = false; k < j; k++ ) + { // starting from the beginning always ensures vert_replacement points to the first point in the array + if ( in->v[j].v[0] == in->v[k].v[0] && + in->v[j].v[1] == in->v[k].v[1] && + in->v[j].v[2] == in->v[k].v[2] ) { Found = true; vert_replacement[j] = k; break; @@ -711,10 +692,8 @@ static void OptimizeVertices(void) } - if (!Found) - { - if (!vert_used[j]) - { + if ( !Found ) { + if ( !vert_used[j] ) { num_unique++; } vert_used[j] = true; @@ -723,45 +702,44 @@ static void OptimizeVertices(void) } // recompute the light normals - for (i=0 ; iv[j].vnorm.normalsum, in->v[k].vnorm.normalsum, in->v[k].vnorm.normalsum); + VectorAdd( in->v[j].vnorm.normalsum, in->v[k].vnorm.normalsum, in->v[k].vnorm.normalsum ); in->v[k].vnorm.numnormals += in->v[j].vnorm.numnormals++; } } - for (j=0 ; jv[j].vnorm.numnormals; - if (!c) - Error ("Vertex with no triangles attached"); + if ( !c ) { + Error( "Vertex with no triangles attached" ); + } - VectorScale (in->v[j].vnorm.normalsum, 1.0/c, v); - VectorNormalize (v, v); + VectorScale( in->v[j].vnorm.normalsum, 1.0 / c, v ); + VectorNormalize( v, v ); maxdot = -999999.0; maxdotindex = -1; - for (k=0 ; k maxdot) - { + dot = DotProduct( v, avertexnormals[k] ); + if ( dot > maxdot ) { maxdot = dot; maxdotindex = k; } @@ -773,10 +751,9 @@ static void OptimizeVertices(void) // create substitution list num_unique = 0; - for(i=0;inext) + for ( l = 0, current = g_skelModel.vertLists[k]; + l < g_skelModel.new_num_verts[k + 1]; ++l, current = current->next ) { - if(current->data == i) - { + if ( current->data == i ) { IntListNode_t *current2; int m; qboolean added = false; - for(m = 0, current2 = newVertLists[k]; m < newNum_verts[k+1]; - ++m, current2 = current2->next) + for ( m = 0, current2 = newVertLists[k]; m < newNum_verts[k + 1]; + ++m, current2 = current2->next ) { - if(current2->data == vert_replacement[i]) - { + if ( current2->data == vert_replacement[i] ) { added = true; break; } } - if(!added) - { - ++newNum_verts[k+1]; + if ( !added ) { + ++newNum_verts[k + 1]; next = newVertLists[k]; - newVertLists[k] = (IntListNode_t *) SafeMalloc(sizeof(IntListNode_t), "OptimizeVertices"); + newVertLists[k] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "OptimizeVertices" ); // freed after model write out newVertLists[k]->data = vert_replacement[i]; @@ -830,48 +803,47 @@ static void OptimizeVertices(void) } // substitute - for (i=0 ; iv[vert_replacement[j]] = in->v[j]; } } - for(i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i) + for ( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i ) { IntListNode_t *toFree; current = g_skelModel.vertLists[i]; - while(current) + while ( current ) { toFree = current; current = current->next; - free(toFree); // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base + free( toFree ); // freeing of memory allocated in ReplaceClusterIndex called in Cmd_Base } g_skelModel.vertLists[i] = newVertLists[i]; - g_skelModel.new_num_verts[i+1] = newNum_verts[i+1]; + g_skelModel.new_num_verts[i + 1] = newNum_verts[i + 1]; } #ifndef NDEBUG - for(k = 0; k < numJointsInSkeleton[g_skelModel.type]; ++k) + for ( k = 0; k < numJointsInSkeleton[g_skelModel.type]; ++k ) { - for(l = 0, current = g_skelModel.vertLists[k]; - l < g_skelModel.new_num_verts[k+1]; ++l, current = current->next) + for ( l = 0, current = g_skelModel.vertLists[k]; + l < g_skelModel.new_num_verts[k + 1]; ++l, current = current->next ) { IntListNode_t *current2; int m; - for(m = l+1, current2 = current->next; m < newNum_verts[k+1]; - ++m, current2 = current2->next) + for ( m = l + 1, current2 = current->next; m < newNum_verts[k + 1]; + ++m, current2 = current2->next ) { - if(current->data == current2->data) - { - printf("Warning duplicate vertex: %d\n", current->data); + if ( current->data == current2->data ) { + printf( "Warning duplicate vertex: %d\n", current->data ); break; } } @@ -879,28 +851,27 @@ static void OptimizeVertices(void) } #endif - for(i=0;i> 3; - bit = 1 << (i & 7 ); + bit = 1 << ( i & 7 ); - for (j=0 ; j<3 ; j++) - { + for ( j = 0 ; j < 3 ; j++ ) + { set_bit = set_pos = triangles[i].index_xyz[j] = vert_replacement[triangles[i].index_xyz[j]]; set_pos >>= 3; - set_bit = 1 << (set_bit & 7); + set_bit = 1 << ( set_bit & 7 ); - for(k=0;kreferences[j].placement.origin, in->v[index].v); + VectorCopy( in->references[j].placement.origin, in->v[index].v ); index++; - VectorCopy(in->references[j].placement.direction, in->v[index].v); + VectorCopy( in->references[j].placement.direction, in->v[index].v ); index++; - VectorCopy(in->references[j].placement.up, in->v[index].v); + VectorCopy( in->references[j].placement.up, in->v[index].v ); index++; } } - fmheader.num_xyz += refnum*3; + fmheader.num_xyz += refnum * 3; } // tack on the skeletal joint verts to the regular verts - if(g_skelModel.type != SKEL_NULL) - { - fmframe_t *in; + if ( g_skelModel.type != SKEL_NULL ) { + fmframe_t *in; int index; - for (i = 0; i < fmheader.num_frames; ++i) + for ( i = 0; i < fmheader.num_frames; ++i ) { in = &g_frames[i]; index = fmheader.num_xyz; - for (j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j) + for ( j = 0 ; j < numJointsInSkeleton[g_skelModel.type]; ++j ) { - VectorCopy(in->joints[j].placement.origin, in->v[index].v); + VectorCopy( in->joints[j].placement.origin, in->v[index].v ); index++; - VectorCopy(in->joints[j].placement.direction, in->v[index].v); + VectorCopy( in->joints[j].placement.direction, in->v[index].v ); index++; - VectorCopy(in->joints[j].placement.up, in->v[index].v); + VectorCopy( in->joints[j].placement.up, in->v[index].v ); index++; } } - fmheader.num_xyz += numJointsInSkeleton[g_skelModel.type]*3; + fmheader.num_xyz += numJointsInSkeleton[g_skelModel.type] * 3; } CompressFrames(); @@ -997,247 +966,246 @@ static void OptimizeVertices(void) /* -=============== -FinishModel -=============== -*/ -void FMFinishModel (void) -{ - FILE *modelouthandle; - int i,j,length,tris,verts,bit,pos,total_tris,total_verts; - char name[1024]; - int trans_count; - - if (!fmheader.num_frames) + =============== + FinishModel + =============== + */ +void FMFinishModel( void ){ + FILE *modelouthandle; + int i,j,length,tris,verts,bit,pos,total_tris,total_verts; + char name[1024]; + int trans_count; + + if ( !fmheader.num_frames ) { return; - + } + // // copy to release directory tree if doing a release build // - if (g_release) - { - if (modelname[0]) - sprintf (name, "%s", modelname); - else - sprintf (name, "%s/tris.fm", cdpartial); - ReleaseFile (name); + if ( g_release ) { + if ( modelname[0] ) { + sprintf( name, "%s", modelname ); + } + else{ + sprintf( name, "%s/tris.fm", cdpartial ); + } + ReleaseFile( name ); - for (i=0 ; i> 3; - bit = 1 << ((j) & 7 ); - if (pmnodes[i].tris[pos] & bit) - { + pos = ( j ) >> 3; + bit = 1 << ( ( j ) & 7 ); + if ( pmnodes[i].tris[pos] & bit ) { tris++; } } - for(j=0;j> 3; - bit = 1 << ((j) & 7 ); - if (pmnodes[i].verts[pos] & bit) - { + pos = ( j ) >> 3; + bit = 1 << ( ( j ) & 7 ); + if ( pmnodes[i].verts[pos] & bit ) { verts++; } } - printf("%-33s %4d %5d\n",pmnodes[i].name,tris,verts); + printf( "%-33s %4d %5d\n",pmnodes[i].name,tris,verts ); total_tris += tris; total_verts += verts; } - printf("--------------------------------- ---- -----\n"); - printf("%-33s %4d %5d\n","TOTALS",total_tris,total_verts); + printf( "--------------------------------- ---- -----\n" ); + printf( "%-33s %4d %5d\n","TOTALS",total_tris,total_verts ); } } - fclose (modelouthandle); + fclose( modelouthandle ); // finish writing header file - H_printf("\n"); + H_printf( "\n" ); // scale_up is usefull to allow step distances to be adjusted - H_printf("#define MODEL_SCALE\t\t%f\n", scale_up); + H_printf( "#define MODEL_SCALE\t\t%f\n", scale_up ); // mesh nodes - if (fmheader.num_mesh_nodes) - { - H_printf("\n"); - H_printf("#define NUM_MESH_NODES\t\t%d\n\n",fmheader.num_mesh_nodes); - for(i=0;iindex_xyz[(startv)%3]; - strip_xyz[1] = last->index_xyz[(startv+1)%3]; - strip_xyz[2] = last->index_xyz[(startv+2)%3]; - strip_st[0] = last->index_st[(startv)%3]; - strip_st[1] = last->index_st[(startv+1)%3]; - strip_st[2] = last->index_st[(startv+2)%3]; + strip_xyz[0] = last->index_xyz[( startv ) % 3]; + strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3]; + strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3]; + strip_st[0] = last->index_st[( startv ) % 3]; + strip_st[1] = last->index_st[( startv + 1 ) % 3]; + strip_st[2] = last->index_st[( startv + 2 ) % 3]; strip_tris[0] = starttri; stripcount = 1; - m1 = last->index_xyz[(startv+2)%3]; - st1 = last->index_st[(startv+2)%3]; - m2 = last->index_xyz[(startv+1)%3]; - st2 = last->index_st[(startv+1)%3]; + m1 = last->index_xyz[( startv + 2 ) % 3]; + st1 = last->index_st[( startv + 2 ) % 3]; + m2 = last->index_xyz[( startv + 1 ) % 3]; + st2 = last->index_st[( startv + 1 ) % 3]; // look for a matching triangle nexttri: - for (j=starttri+1, check=&triangles[starttri+1] - ; j> 3; - bit = 1 << (j & 7 ); - if (!(pmnodes[node].tris[pos] & bit)) - { + bit = 1 << ( j & 7 ); + if ( !( pmnodes[node].tris[pos] & bit ) ) { continue; } - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { - if (check->index_xyz[k] != m1) + if ( check->index_xyz[k] != m1 ) { continue; - if (check->index_st[k] != st1) + } + if ( check->index_st[k] != st1 ) { continue; - if (check->index_xyz[ (k+1)%3 ] != m2) + } + if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) { continue; - if (check->index_st[ (k+1)%3 ] != st2) + } + if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) { continue; + } // this is the next part of the fan // if we can't use this triangle, this tristrip is done - if (used[j] || translucent[j] != translucent[starttri]) + if ( used[j] || translucent[j] != translucent[starttri] ) { goto done; + } // the new edge - if (stripcount & 1) - { - m2 = check->index_xyz[ (k+2)%3 ]; - st2 = check->index_st[ (k+2)%3 ]; + if ( stripcount & 1 ) { + m2 = check->index_xyz[ ( k + 2 ) % 3 ]; + st2 = check->index_st[ ( k + 2 ) % 3 ]; } else { - m1 = check->index_xyz[ (k+2)%3 ]; - st1 = check->index_st[ (k+2)%3 ]; + m1 = check->index_xyz[ ( k + 2 ) % 3 ]; + st1 = check->index_st[ ( k + 2 ) % 3 ]; } - strip_xyz[stripcount+2] = check->index_xyz[ (k+2)%3 ]; - strip_st[stripcount+2] = check->index_st[ (k+2)%3 ]; + strip_xyz[stripcount + 2] = check->index_xyz[ ( k + 2 ) % 3 ]; + strip_st[stripcount + 2] = check->index_st[ ( k + 2 ) % 3 ]; strip_tris[stripcount] = j; stripcount++; @@ -1248,82 +1216,86 @@ nexttri: done: // clear the temp used flags - for (j=starttri+1 ; jindex_xyz[(startv)%3]; - strip_xyz[1] = last->index_xyz[(startv+1)%3]; - strip_xyz[2] = last->index_xyz[(startv+2)%3]; - strip_st[0] = last->index_st[(startv)%3]; - strip_st[1] = last->index_st[(startv+1)%3]; - strip_st[2] = last->index_st[(startv+2)%3]; + strip_xyz[0] = last->index_xyz[( startv ) % 3]; + strip_xyz[1] = last->index_xyz[( startv + 1 ) % 3]; + strip_xyz[2] = last->index_xyz[( startv + 2 ) % 3]; + strip_st[0] = last->index_st[( startv ) % 3]; + strip_st[1] = last->index_st[( startv + 1 ) % 3]; + strip_st[2] = last->index_st[( startv + 2 ) % 3]; strip_tris[0] = starttri; stripcount = 1; - m1 = last->index_xyz[(startv+0)%3]; - st1 = last->index_st[(startv+0)%3]; - m2 = last->index_xyz[(startv+2)%3]; - st2 = last->index_st[(startv+2)%3]; + m1 = last->index_xyz[( startv + 0 ) % 3]; + st1 = last->index_st[( startv + 0 ) % 3]; + m2 = last->index_xyz[( startv + 2 ) % 3]; + st2 = last->index_st[( startv + 2 ) % 3]; // look for a matching triangle nexttri: - for (j=starttri+1, check=&triangles[starttri+1] - ; j> 3; - bit = 1 << (j & 7 ); - if (!(pmnodes[node].tris[pos] & bit)) - { + bit = 1 << ( j & 7 ); + if ( !( pmnodes[node].tris[pos] & bit ) ) { continue; } - for (k=0 ; k<3 ; k++) + for ( k = 0 ; k < 3 ; k++ ) { - if (check->index_xyz[k] != m1) + if ( check->index_xyz[k] != m1 ) { continue; - if (check->index_st[k] != st1) + } + if ( check->index_st[k] != st1 ) { continue; - if (check->index_xyz[ (k+1)%3 ] != m2) + } + if ( check->index_xyz[ ( k + 1 ) % 3 ] != m2 ) { continue; - if (check->index_st[ (k+1)%3 ] != st2) + } + if ( check->index_st[ ( k + 1 ) % 3 ] != st2 ) { continue; + } // this is the next part of the fan // if we can't use this triangle, this tristrip is done - if (used[j] || translucent[j] != translucent[starttri]) + if ( used[j] || translucent[j] != translucent[starttri] ) { goto done; + } // the new edge - m2 = check->index_xyz[ (k+2)%3 ]; - st2 = check->index_st[ (k+2)%3 ]; + m2 = check->index_xyz[ ( k + 2 ) % 3 ]; + st2 = check->index_st[ ( k + 2 ) % 3 ]; - strip_xyz[stripcount+2] = m2; - strip_st[stripcount+2] = st2; + strip_xyz[stripcount + 2] = m2; + strip_st[stripcount + 2] = st2; strip_tris[stripcount] = j; stripcount++; @@ -1334,9 +1306,10 @@ nexttri: done: // clear the temp used flags - for (j=starttri+1 ; j> 3; - bit = 1 << (i & 7 ); - if (!(pmnodes[l].tris[pos] & bit)) - { + bit = 1 << ( i & 7 ); + if ( !( pmnodes[l].tris[pos] & bit ) ) { continue; } // pick an unused triangle and start the trifan - if (used[i] || trans_check != translucent[i]) - { + if ( used[i] || trans_check != translucent[i] ) { continue; } bestlen = 0; - for (type = 0 ; type < 2 ; type++) - // type = 1; + for ( type = 0 ; type < 2 ; type++ ) + // type = 1; { - for (startv =0 ; startv < 3 ; startv++) + for ( startv = 0 ; startv < 3 ; startv++ ) { - if (type == 1) - len = StripLength (i, startv, fmheader.num_tris, l); - else - len = FanLength (i, startv, fmheader.num_tris, l); - if (len > bestlen) - { + if ( type == 1 ) { + len = StripLength( i, startv, fmheader.num_tris, l ); + } + else{ + len = FanLength( i, startv, fmheader.num_tris, l ); + } + if ( len > bestlen ) { besttype = type; bestlen = len; - for (j=0 ; j ady ? adx : ady; count++; - if(count > 300) - { - printf("Bad count\n"); + if ( count > 300 ) { + printf( "Bad count\n" ); return; // don't ever hang up on bad data } - + xfrac = x1; yfrac = y1; - - xstep = (float)dx/count; - ystep = (float)dy/count; - switch(LineType) + xstep = (float)dx / count; + ystep = (float)dy / count; + + switch ( LineType ) { - case LINE_NORMAL: - do - { - if(xfrac < SKINPAGE_WIDTH && yfrac < SKINPAGE_HEIGHT) - { - pic[(int)yfrac*SKINPAGE_WIDTH+(int)xfrac] = LineColor; - } - xfrac += xstep; - yfrac += ystep; - count--; - } while (count > 0); - break; - case LINE_FAT: - do + case LINE_NORMAL: + do + { + if ( xfrac < SKINPAGE_WIDTH && yfrac < SKINPAGE_HEIGHT ) { + pic[(int)yfrac * SKINPAGE_WIDTH + (int)xfrac] = LineColor; + } + xfrac += xstep; + yfrac += ystep; + count--; + } while ( count > 0 ); + break; + case LINE_FAT: + do + { + for ( u = -0.1 ; u <= 0.9 ; u += 0.999 ) { - for (u=-0.1 ; u<=0.9 ; u+=0.999) + for ( v = -0.1 ; v <= 0.9 ; v += 0.999 ) { - for (v=-0.1 ; v<=0.9 ; v+=0.999) - { - sx = xfrac+u; - sy = yfrac+v; - if(sx < SKINPAGE_WIDTH && sy < SKINPAGE_HEIGHT) - { - pic[sy*SKINPAGE_WIDTH+sx] = LineColor; - } + sx = xfrac + u; + sy = yfrac + v; + if ( sx < SKINPAGE_WIDTH && sy < SKINPAGE_HEIGHT ) { + pic[sy * SKINPAGE_WIDTH + sx] = LineColor; } } - xfrac += xstep; - yfrac += ystep; - count--; - } while (count > 0); - break; - case LINE_DOTTED: - do - { - if(count&1 && xfrac < SKINPAGE_WIDTH && - yfrac < SKINPAGE_HEIGHT) - { - pic[(int)yfrac*SKINPAGE_WIDTH+(int)xfrac] = LineColor; - } - xfrac += xstep; - yfrac += ystep; - count--; - } while (count > 0); - break; - default: - Error("Unknown %d.\n", LineType); + } + xfrac += xstep; + yfrac += ystep; + count--; + } while ( count > 0 ); + break; + case LINE_DOTTED: + do + { + if ( count & 1 && xfrac < SKINPAGE_WIDTH && + yfrac < SKINPAGE_HEIGHT ) { + pic[(int)yfrac * SKINPAGE_WIDTH + (int)xfrac] = LineColor; + } + xfrac += xstep; + yfrac += ystep; + count--; + } while ( count > 0 ); + break; + default: + Error( "Unknown %d.\n", LineType ); } } @@ -1626,22 +1594,20 @@ void DrawLine(int x1, int y1, int x2, int y2) // //========================================================================== -static void DrawCharacter(int x, int y, int character) -{ +static void DrawCharacter( int x, int y, int character ){ int r, c; char *def; - character = toupper(character); - if(character < ASCII_SPACE || character > 'Z') - { + character = toupper( character ); + if ( character < ASCII_SPACE || character > 'Z' ) { character = ASCII_SPACE; } character -= ASCII_SPACE; - for(def = CharDefs[character], r = 0; r < 5; r++) + for ( def = CharDefs[character], r = 0; r < 5; r++ ) { - for(c = 0; c < 5; c++) + for ( c = 0; c < 5; c++ ) { - pic[(y+r)*SKINPAGE_WIDTH+x+c] = *def++ == '*' ? 255 : 0; + pic[( y + r ) * SKINPAGE_WIDTH + x + c] = *def++ == '*' ? 255 : 0; } } } @@ -1652,62 +1618,58 @@ static void DrawCharacter(int x, int y, int character) // //========================================================================== -void DrawTextChar(int x, int y, char *text) -{ +void DrawTextChar( int x, int y, char *text ){ int c; - while((c = *text++) != '\0') + while ( ( c = *text++ ) != '\0' ) { - DrawCharacter(x, y, c); + DrawCharacter( x, y, c ); x += 6; } } -extern void DrawScreen(float s_scale, float t_scale, float iwidth, float iheight); +extern void DrawScreen( float s_scale, float t_scale, float iwidth, float iheight ); //========================================================================== // ExtractDigit -static int ExtractDigit(byte *pic, int x, int y) -{ - int i; - int r, c; - char digString[32]; - char *buffer; - byte backColor; - char **DigitDefs; - - backColor = pic[(SKINPAGE_HEIGHT - 1) * SKINPAGE_WIDTH]; +static int ExtractDigit( byte *pic, int x, int y ){ + int i; + int r, c; + char digString[32]; + char *buffer; + byte backColor; + char **DigitDefs; + + backColor = pic[( SKINPAGE_HEIGHT - 1 ) * SKINPAGE_WIDTH]; DigitDefs = &CharDefs['0' - ASCII_SPACE]; buffer = digString; - for(r = 0; r < 5; r++) + for ( r = 0; r < 5; r++ ) { - for(c = 0; c < 5; c++) + for ( c = 0; c < 5; c++ ) { - *buffer++ = (pic[(y + r) * SKINPAGE_WIDTH + x + c] == backColor) ? ' ' : '*'; + *buffer++ = ( pic[( y + r ) * SKINPAGE_WIDTH + x + c] == backColor ) ? ' ' : '*'; } } *buffer = '\0'; - for(i = 0; i < 10; i++) + for ( i = 0; i < 10; i++ ) { - if(strcmp(DigitDefs[i], digString) == 0) - { + if ( strcmp( DigitDefs[i], digString ) == 0 ) { return i; } } - Error("Unable to extract scaling info from skin PCX."); + Error( "Unable to extract scaling info from skin PCX." ); return 0; } //========================================================================== // ExtractNumber -int ExtractNumber(byte *pic, int x, int y) -{ - return ExtractDigit(pic, x, y) * 100 + ExtractDigit(pic, x + 6, y) * 10 + ExtractDigit(pic, x + 12, y); +int ExtractNumber( byte *pic, int x, int y ){ + return ExtractDigit( pic, x, y ) * 100 + ExtractDigit( pic, x + 6, y ) * 10 + ExtractDigit( pic, x + 12, y ); } @@ -1715,177 +1677,174 @@ int ExtractNumber(byte *pic, int x, int y) /* -============ -BuildST - -Builds the triangle_st array for the base frame and -fmheader.skinwidth / fmheader.skinheight - - FIXME: allow this to be loaded from a file for - arbitrary mappings -============ -*/ -static void BuildST (triangle_t *ptri, int numtri, qboolean DrawSkin) -{ - int backface_flag; - int i, j; - int width, height, iwidth, iheight, swidth; - float basex, basey; - float scale; - vec3_t mins, maxs; - float *pbasevert; - vec3_t vtemp1, vtemp2, normal; - float s_scale, t_scale; - float scWidth; - float scHeight; + ============ + BuildST + + Builds the triangle_st array for the base frame and + fmheader.skinwidth / fmheader.skinheight + + FIXME: allow this to be loaded from a file for + arbitrary mappings + ============ + */ +static void BuildST( triangle_t *ptri, int numtri, qboolean DrawSkin ){ + int backface_flag; + int i, j; + int width, height, iwidth, iheight, swidth; + float basex, basey; + float scale; + vec3_t mins, maxs; + float *pbasevert; + vec3_t vtemp1, vtemp2, normal; + float s_scale, t_scale; + float scWidth; + float scHeight; int skinwidth; int skinheight; // // find bounds of all the verts on the base frame // - ClearBounds (mins, maxs); + ClearBounds( mins, maxs ); backface_flag = false; - - if (ptri[0].HasUV) // if we have the uv already, we don't want to double up or scale - { + + if ( ptri[0].HasUV ) { // if we have the uv already, we don't want to double up or scale iwidth = ScaleWidth; iheight = ScaleHeight; - + t_scale = s_scale = 1.0; } else { - for (i=0 ; i 0) - { - backface_flag = true; - break; - } - } - scWidth = ScaleWidth*SCALE_ADJUST_FACTOR; - if (backface_flag) //we are doubling - scWidth /= 2; - - scHeight = ScaleHeight*SCALE_ADJUST_FACTOR; - - scale = scWidth/width; - - if(height*scale >= scHeight) - { - scale = scHeight/height; + for ( i = 0 ; i < numtri ; i++ ) + for ( j = 0 ; j < 3 ; j++ ) + AddPointToBounds( ptri[i].verts[j], mins, maxs ); + + for ( i = 0 ; i < 3 ; i++ ) + { + mins[i] = floor( mins[i] ); + maxs[i] = ceil( maxs[i] ); + } + + width = maxs[0] - mins[0]; + height = maxs[2] - mins[2]; + + for ( i = 0 ; i < numtri ; i++ ) + { + VectorSubtract( ptri[i].verts[0], ptri[i].verts[1], vtemp1 ); + VectorSubtract( ptri[i].verts[2], ptri[i].verts[1], vtemp2 ); + CrossProduct( vtemp1, vtemp2, normal ); + + if ( normal[1] > 0 ) { + backface_flag = true; + break; } - - iwidth = ceil(width*scale)+4; - iheight = ceil(height*scale)+4; - - s_scale = (float)(iwidth-4) / width; - t_scale = (float)(iheight-4) / height; - t_scale = s_scale; - } - if (DrawSkin) - { - if(backface_flag) - DrawScreen(s_scale, t_scale, iwidth*2, iheight); - else - DrawScreen(s_scale, t_scale, iwidth, iheight); - } - if (backface_flag) - skinwidth=iwidth*2; - else - skinwidth=iwidth; - skinheight=iheight; + } + scWidth = ScaleWidth * SCALE_ADJUST_FACTOR; + if ( backface_flag ) { //we are doubling + scWidth /= 2; + } + scHeight = ScaleHeight * SCALE_ADJUST_FACTOR; -/* if (!g_fixedwidth) - { // old style - scale = 8; - if (width*scale >= 150) - scale = 150.0 / width; - if (height*scale >= 190) - scale = 190.0 / height; + scale = scWidth / width; - s_scale = t_scale = scale; + if ( height * scale >= scHeight ) { + scale = scHeight / height; + } - iwidth = ceil(width*s_scale); - iheight = ceil(height*t_scale); + iwidth = ceil( width * scale ) + 4; + iheight = ceil( height * scale ) + 4; - iwidth += 4; - iheight += 4; + s_scale = (float)( iwidth - 4 ) / width; + t_scale = (float)( iheight - 4 ) / height; + t_scale = s_scale; } - else - { // new style - iwidth = g_fixedwidth / 2; - iheight = g_fixedheight; + if ( DrawSkin ) { + if ( backface_flag ) { + DrawScreen( s_scale, t_scale, iwidth * 2, iheight ); + } + else{ + DrawScreen( s_scale, t_scale, iwidth, iheight ); + } + } + if ( backface_flag ) { + skinwidth = iwidth * 2; + } + else{ + skinwidth = iwidth; + } + skinheight = iheight; - s_scale = (float)(iwidth-4) / width; - t_scale = (float)(iheight-4) / height; - }*/ + +/* if (!g_fixedwidth) + { // old style + scale = 8; + if (width*scale >= 150) + scale = 150.0 / width; + if (height*scale >= 190) + scale = 190.0 / height; + + s_scale = t_scale = scale; + + iwidth = ceil(width*s_scale); + iheight = ceil(height*t_scale); + + iwidth += 4; + iheight += 4; + } + else + { // new style + iwidth = g_fixedwidth / 2; + iheight = g_fixedheight; + + s_scale = (float)(iwidth-4) / width; + t_scale = (float)(iheight-4) / height; + }*/ // // determine which side of each triangle to map the texture to // basey = 2; - for (i=0 ; i 0) - { + if ( normal[1] > 0 ) { basex = iwidth + 2; } else { basex = 2; } - - for (j=0 ; j<3 ; j++) + + for ( j = 0 ; j < 3 ; j++ ) { pbasevert = ptri[i].verts[j]; - triangle_st[i][j][0] = Q_rint((pbasevert[0] - mins[0]) * s_scale + basex); - triangle_st[i][j][1] = Q_rint((maxs[2] - pbasevert[2]) * t_scale + basey); + triangle_st[i][j][0] = Q_rint( ( pbasevert[0] - mins[0] ) * s_scale + basex ); + triangle_st[i][j][1] = Q_rint( ( maxs[2] - pbasevert[2] ) * t_scale + basey ); } } - if (DrawSkin) - { - DrawLine(triangle_st[i][0][0], triangle_st[i][0][1], - triangle_st[i][1][0], triangle_st[i][1][1]); - DrawLine(triangle_st[i][1][0], triangle_st[i][1][1], - triangle_st[i][2][0], triangle_st[i][2][1]); - DrawLine(triangle_st[i][2][0], triangle_st[i][2][1], - triangle_st[i][0][0], triangle_st[i][0][1]); + if ( DrawSkin ) { + DrawLine( triangle_st[i][0][0], triangle_st[i][0][1], + triangle_st[i][1][0], triangle_st[i][1][1] ); + DrawLine( triangle_st[i][1][0], triangle_st[i][1][1], + triangle_st[i][2][0], triangle_st[i][2][1] ); + DrawLine( triangle_st[i][2][0], triangle_st[i][2][1], + triangle_st[i][0][0], triangle_st[i][0][1] ); } } @@ -1893,9 +1852,10 @@ static void BuildST (triangle_t *ptri, int numtri, qboolean DrawSkin) // dword alignment for each scan swidth = iwidth; - if(backface_flag) + if ( backface_flag ) { swidth *= 2; - fmheader.skinwidth = (swidth + 3) & ~3; + } + fmheader.skinwidth = ( swidth + 3 ) & ~3; fmheader.skinheight = iheight; skin_width = iwidth; @@ -1903,36 +1863,33 @@ static void BuildST (triangle_t *ptri, int numtri, qboolean DrawSkin) } -static void BuildNewST (triangle_t *ptri, int numtri, qboolean DrawSkin) -{ - int i, j; +static void BuildNewST( triangle_t *ptri, int numtri, qboolean DrawSkin ){ + int i, j; - for (i=0 ; i 1) + if ( d < -1 || d > 1 ) { goto split; + } d = lp2[1] - lp1[1]; - if (d < -1 || d > 1) + if ( d < -1 || d > 1 ) { goto split; + } d = lp3[0] - lp2[0]; - if (d < -1 || d > 1) + if ( d < -1 || d > 1 ) { goto split2; + } d = lp3[1] - lp2[1]; - if (d < -1 || d > 1) + if ( d < -1 || d > 1 ) { goto split2; + } d = lp1[0] - lp3[0]; - if (d < -1 || d > 1) + if ( d < -1 || d > 1 ) { goto split3; + } d = lp1[1] - lp3[1]; - if (d < -1 || d > 1) - { + if ( d < -1 || d > 1 ) { split3: temp = lp1; lp1 = lp3; @@ -1983,7 +1943,7 @@ split3: goto split; } - return 0; // entire tri is filled + return 0; // entire tri is filled split2: temp = lp1; @@ -1993,39 +1953,39 @@ split2: split: // split this edge - new[0] = (lp1[0] + lp2[0]) >> 1; - new[1] = (lp1[1] + lp2[1]) >> 1; + new[0] = ( lp1[0] + lp2[0] ) >> 1; + new[1] = ( lp1[1] + lp2[1] ) >> 1; // draw the point if splitting a leading edge - if (lp2[1] > lp1[1]) + if ( lp2[1] > lp1[1] ) { goto nodraw; - if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) + } + if ( ( lp2[1] == lp1[1] ) && ( lp2[0] < lp1[0] ) ) { goto nodraw; + } - if (SetPixel) - { - assert ((new[1]*BaseWidth) + new[0] < BaseWidth*BaseHeight); + if ( SetPixel ) { + assert( ( new[1] * BaseWidth ) + new[0] < BaseWidth * BaseHeight ); - if (BaseTrueColor) - { - BasePixels[((new[1]*BaseWidth) + new[0]) * 4] = 1; + if ( BaseTrueColor ) { + BasePixels[( ( new[1] * BaseWidth ) + new[0] ) * 4] = 1; } else { - BasePixels[(new[1]*BaseWidth) + new[0]] = 1; + BasePixels[( new[1] * BaseWidth ) + new[0]] = 1; } } else { - if (TransPixels) - { - if (TransPixels[(new[1]*TransWidth) + new[0]] != 255) + if ( TransPixels ) { + if ( TransPixels[( new[1] * TransWidth ) + new[0]] != 255 ) { return 1; + } } - else if (BaseTrueColor) - { - if (BasePixels[(((new[1]*BaseWidth) + new[0]) * 4) + 3] != 255) + else if ( BaseTrueColor ) { + if ( BasePixels[( ( ( new[1] * BaseWidth ) + new[0] ) * 4 ) + 3] != 255 ) { return 1; + } } else { @@ -2035,34 +1995,32 @@ split: nodraw: // recursively continue - if (CheckTransRecursiveTri(lp3, lp1, new)) + if ( CheckTransRecursiveTri( lp3, lp1, new ) ) { return 1; + } - return CheckTransRecursiveTri(lp3, new, lp2); + return CheckTransRecursiveTri( lp3, new, lp2 ); } -static void ReplaceClusterIndex(int newIndex, int oldindex, int **clusters, - IntListNode_t **vertLists, int *num_verts, int *new_num_verts) -{ +static void ReplaceClusterIndex( int newIndex, int oldindex, int **clusters, + IntListNode_t **vertLists, int *num_verts, int *new_num_verts ){ int i, j; IntListNode_t *next; - for(j = 0; j < numJointsInSkeleton[g_skelModel.type]; ++j) + for ( j = 0; j < numJointsInSkeleton[g_skelModel.type]; ++j ) { - if(!clusters[j]) - { + if ( !clusters[j] ) { continue; } - for(i = 0; i < num_verts[j+1]; ++i) + for ( i = 0; i < num_verts[j + 1]; ++i ) { - if(clusters[j][i] == oldindex) - { - ++new_num_verts[j+1]; + if ( clusters[j][i] == oldindex ) { + ++new_num_verts[j + 1]; next = vertLists[j]; - vertLists[j] = (IntListNode_t *) SafeMalloc(sizeof(IntListNode_t), "ReplaceClusterIndex"); + vertLists[j] = (IntListNode_t *) SafeMalloc( sizeof( IntListNode_t ), "ReplaceClusterIndex" ); // Currently freed in WriteJointedModelFile only vertLists[j]->data = newIndex; @@ -2072,50 +2030,50 @@ static void ReplaceClusterIndex(int newIndex, int oldindex, int **clusters, } } -#define FUDGE_EPSILON 0.002 +#define FUDGE_EPSILON 0.002 -qboolean VectorFudgeCompare (vec3_t v1, vec3_t v2) -{ - int i; - - for (i=0 ; i<3 ; i++) - if (fabs(v1[i]-v2[i]) > FUDGE_EPSILON) +qboolean VectorFudgeCompare( vec3_t v1, vec3_t v2 ){ + int i; + + for ( i = 0 ; i < 3 ; i++ ) + if ( fabs( v1[i] - v2[i] ) > FUDGE_EPSILON ) { return false; - + } + return true; } /* -================= -Cmd_Base -================= -*/ -void Cmd_FMBase (qboolean GetST) -{ - triangle_t *ptri, *st_tri; - int num_st_tris; - int i, j, k, l; - int x,y,z; + ================= + Cmd_Base + ================= + */ +void Cmd_FMBase( qboolean GetST ){ + triangle_t *ptri, *st_tri; + int num_st_tris; + int i, j, k, l; + int x,y,z; // int time1; - char file1[1024],file2[1024],trans_file[1024], stfile[1024], extension[256]; - vec3_t base_xyz[MAX_FM_VERTS]; - FILE *FH; - int pos,bit; - qboolean NewSkin; + char file1[1024],file2[1024],trans_file[1024], stfile[1024], extension[256]; + vec3_t base_xyz[MAX_FM_VERTS]; + FILE *FH; + int pos,bit; + qboolean NewSkin; - GetScriptToken (false); + GetScriptToken( false ); - if (g_skipmodel || g_release || g_archive) + if ( g_skipmodel || g_release || g_archive ) { return; + } - printf ("---------------------\n"); - sprintf (file1, "%s/%s.%s", cdarchive, token, trifileext); - printf ("%s ", file1); + printf( "---------------------\n" ); + sprintf( file1, "%s/%s.%s", cdarchive, token, trifileext ); + printf( "%s ", file1 ); - ExpandPathAndArchive (file1); + ExpandPathAndArchive( file1 ); // Use the input filepath for this one. - sprintf (file1, "%s/%s", cddir, token); + sprintf( file1, "%s/%s", cddir, token ); // time1 = FileTime (file1); // if (time1 == -1) @@ -2124,105 +2082,98 @@ void Cmd_FMBase (qboolean GetST) // // load the base triangles // - if (do3ds) - Load3DSTriangleList (file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes); - else - LoadTriangleList (file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes); + if ( do3ds ) { + Load3DSTriangleList( file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes ); + } + else{ + LoadTriangleList( file1, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes ); + } - if (g_ignoreTriUV) - { - for (i=0;i> 3; - bit = 1 << (i & 7 ); - if (!(pmnodes[l].tris[pos] & bit)) - { + bit = 1 << ( i & 7 ); + if ( !( pmnodes[l].tris[pos] & bit ) ) { continue; } - for (j=0 ; j<3 ; j++) + for ( j = 0 ; j < 3 ; j++ ) { // get the xyz index - for (k=0 ; k> 3; - bit = 1 << (k & 7); + bit = 1 << ( k & 7 ); pmnodes[l].verts[pos] |= bit; triangles[i].index_xyz[j] = k; // get the st index - for (k=0 ; k= fmheader.num_mesh_nodes) - { - Error("Node '%s' not in base list!\n", token); + if ( j >= fmheader.num_mesh_nodes ) { + Error( "Node '%s' not in base list!\n", token ); } } - free(pmnodes); + free( pmnodes ); pmnodes = newnodes; } //=============================================================== -extern char *FindFrameFile (char *frame); +extern char *FindFrameFile( char *frame ); /* -=============== -GrabFrame -=============== -*/ -void GrabFrame (char *frame) -{ - triangle_t *ptri; - int i, j; - fmtrivert_t *ptrivert; - int num_tris; - char file1[1024]; - fmframe_t *fr; - int index_xyz; - char *framefile; + =============== + GrabFrame + =============== + */ +void GrabFrame( char *frame ){ + triangle_t *ptri; + int i, j; + fmtrivert_t *ptrivert; + int num_tris; + char file1[1024]; + fmframe_t *fr; + int index_xyz; + char *framefile; // the frame 'run1' will be looked for as either // run.1 or run1.tri, so the new alias sequence save // feature an be used - framefile = FindFrameFile (frame); + framefile = FindFrameFile( frame ); - sprintf (file1, "%s/%s", cdarchive, framefile); - ExpandPathAndArchive (file1); + sprintf( file1, "%s/%s", cdarchive, framefile ); + ExpandPathAndArchive( file1 ); - sprintf (file1, "%s/%s",cddir, framefile); + sprintf( file1, "%s/%s",cddir, framefile ); - printf ("grabbing %s ", file1); + printf( "grabbing %s ", file1 ); - if (fmheader.num_frames >= MAX_FM_FRAMES) - Error ("fmheader.num_frames >= MAX_FM_FRAMES"); + if ( fmheader.num_frames >= MAX_FM_FRAMES ) { + Error( "fmheader.num_frames >= MAX_FM_FRAMES" ); + } fr = &g_frames[fmheader.num_frames]; fmheader.num_frames++; - strcpy (fr->name, frame); + strcpy( fr->name, frame ); // // load the frame // - if (do3ds) - Load3DSTriangleList (file1, &ptri, &num_tris, NULL, NULL); - else - LoadTriangleList (file1, &ptri, &num_tris, NULL, NULL); + if ( do3ds ) { + Load3DSTriangleList( file1, &ptri, &num_tris, NULL, NULL ); + } + else{ + LoadTriangleList( file1, &ptri, &num_tris, NULL, NULL ); + } - if (num_tris != fmheader.num_tris) - Error ("%s: number of triangles (%d) doesn't match base frame (%d)\n", file1, num_tris, fmheader.num_tris); + if ( num_tris != fmheader.num_tris ) { + Error( "%s: number of triangles (%d) doesn't match base frame (%d)\n", file1, num_tris, fmheader.num_tris ); + } // // allocate storage for the frame's vertices // ptrivert = fr->v; - for (i=0 ; imins, fr->maxs); + ClearBounds( fr->mins, fr->maxs ); // // store the frame's vertices in the same order as the base. This assumes the // triangles and vertices in this frame are in exactly the same order as in the // base // - for (i=0 ; imins, fr->maxs); + AddPointToBounds( ptrivert[index_xyz].v, fr->mins, fr->maxs ); - VectorAdd (ptrivert[index_xyz].vnorm.normalsum, normal, ptrivert[index_xyz].vnorm.normalsum); + VectorAdd( ptrivert[index_xyz].vnorm.normalsum, normal, ptrivert[index_xyz].vnorm.normalsum ); ptrivert[index_xyz].vnorm.numnormals++; } } @@ -2578,31 +2510,31 @@ void GrabFrame (char *frame) // calculate the vertex normals, match them to the template list, and store the // index of the best match // - for (i=0 ; i maxdot) - { + dot = DotProduct( v, avertexnormals[j] ); + if ( dot > maxdot ) { maxdot = dot; maxdotindex = j; } @@ -2611,44 +2543,40 @@ void GrabFrame (char *frame) ptrivert[i].lightnormalindex = maxdotindex; } - free (ptri); + free( ptri ); } /* -=============== -Cmd_Frame -=============== -*/ -void Cmd_FMFrame (void) -{ - while (ScriptTokenAvailable()) - { - GetScriptToken (false); - if (g_skipmodel) + =============== + Cmd_Frame + =============== + */ +void Cmd_FMFrame( void ){ + while ( ScriptTokenAvailable() ) + { + GetScriptToken( false ); + if ( g_skipmodel ) { continue; - if (g_release || g_archive) - { - fmheader.num_frames = 1; // don't skip the writeout + } + if ( g_release || g_archive ) { + fmheader.num_frames = 1; // don't skip the writeout continue; } - H_printf("#define FRAME_%-16s\t%i\n", token, fmheader.num_frames); + H_printf( "#define FRAME_%-16s\t%i\n", token, fmheader.num_frames ); - if((g_skelModel.type != SKEL_NULL) || (g_skelModel.references != REF_NULL)) - { - GrabModelTransform(token); + if ( ( g_skelModel.type != SKEL_NULL ) || ( g_skelModel.references != REF_NULL ) ) { + GrabModelTransform( token ); } - GrabFrame (token); + GrabFrame( token ); - if(g_skelModel.type != SKEL_NULL) - { - GrabSkeletalFrame(token); + if ( g_skelModel.type != SKEL_NULL ) { + GrabSkeletalFrame( token ); } - if(g_skelModel.references != REF_NULL) - { - GrabReferencedFrame(token); + if ( g_skelModel.references != REF_NULL ) { + GrabReferencedFrame( token ); } // need to add the up and dir points to the frame bounds here @@ -2658,594 +2586,588 @@ void Cmd_FMFrame (void) } /* -=============== -Cmd_Skin - -Skins aren't actually stored in the file, only a reference -is saved out to the header file. -=============== -*/ -void Cmd_FMSkin (void) -{ - byte *palette; - byte *pixels; - int width, height; - byte *cropped; - int y; - char name[1024], savename[1024], transname[1024], extension[256]; - miptex32_t *qtex32; - int size; - FILE *FH; - qboolean TrueColor; - - GetScriptToken (false); - - if (fmheader.num_skins == MAX_FM_SKINS) - Error ("fmheader.num_skins == MAX_FM_SKINS"); - - if (g_skipmodel) + =============== + Cmd_Skin + + Skins aren't actually stored in the file, only a reference + is saved out to the header file. + =============== + */ +void Cmd_FMSkin( void ){ + byte *palette; + byte *pixels; + int width, height; + byte *cropped; + int y; + char name[1024], savename[1024], transname[1024], extension[256]; + miptex32_t *qtex32; + int size; + FILE *FH; + qboolean TrueColor; + + GetScriptToken( false ); + + if ( fmheader.num_skins == MAX_FM_SKINS ) { + Error( "fmheader.num_skins == MAX_FM_SKINS" ); + } + + if ( g_skipmodel ) { return; + } - sprintf (name, "%s/%s", cdarchive, token); - strcpy (name, ExpandPathAndArchive( name ) ); + sprintf( name, "%s/%s", cdarchive, token ); + strcpy( name, ExpandPathAndArchive( name ) ); // sprintf (name, "%s/%s.lbm", cddir, token); - if (ScriptTokenAvailable()) - { - GetScriptToken (false); - sprintf (g_skins[fmheader.num_skins], "!%s", token); - sprintf (savename, "%s!%s", g_outputDir, token); - sprintf (transname, "%s!%s_a.pcx", gamedir, token); + if ( ScriptTokenAvailable() ) { + GetScriptToken( false ); + sprintf( g_skins[fmheader.num_skins], "!%s", token ); + sprintf( savename, "%s!%s", g_outputDir, token ); + sprintf( transname, "%s!%s_a.pcx", gamedir, token ); } else { - sprintf (g_skins[fmheader.num_skins], "%s/!%s", cdpartial, token); - sprintf (savename, "%s/!%s", g_outputDir, token); - sprintf (transname, "%s/!%s_a.pcx", cddir, token); + sprintf( g_skins[fmheader.num_skins], "%s/!%s", cdpartial, token ); + sprintf( savename, "%s/!%s", g_outputDir, token ); + sprintf( transname, "%s/!%s_a.pcx", cddir, token ); } fmheader.num_skins++; - if (g_skipmodel || g_release || g_archive) + if ( g_skipmodel || g_release || g_archive ) { return; + } // load the image - printf ("loading %s\n", name); - ExtractFileExtension (name, extension); - if (extension[0] == 0) - { - strcat(name, ".pcx"); + printf( "loading %s\n", name ); + ExtractFileExtension( name, extension ); + if ( extension[0] == 0 ) { + strcat( name, ".pcx" ); } - TrueColor = LoadAnyImage (name, &pixels, &palette, &width, &height); + TrueColor = LoadAnyImage( name, &pixels, &palette, &width, &height ); // RemapZero (pixels, palette, width, height); // crop it to the proper size - if (!TrueColor) - { - cropped = (byte *) SafeMalloc (fmheader.skinwidth*fmheader.skinheight, "Cmd_FMSkin"); - for (y=0 ; y= 3); -// figure out the best plane projections - DOsvdPlane ((float*)vertices, num, (float *)&n, (float *)&base); - - if (DotProduct(aveNorm,n) < 0.0f) - { - VectorScale(n, -1.0f, n); - } - VectorNormalize(n,n); - if (fabs(n[2]) < .57) - { - CrossProduct( zaxis, n, crossvect); - VectorCopy(crossvect, u); - } - else - { - CrossProduct( yaxis, n, crossvect); - VectorCopy(crossvect, u); - } - VectorNormalize(u,u); - CrossProduct( n, u, crossvect); - VectorCopy(crossvect, v); - VectorNormalize(v,v); - - num = 0; - - for ( j = 0; j < 3; j++) - { - groupMin[j] = 1e30f; - groupMax[j] = -1e30f; - } - - for ( j = 0; j < numtris; j++) - { - for ( k = 0; k < 3; k++) - { - VectorCopy(grouptris[j].verts[k],v0); - VectorSubtract(v0, base, v0); - uvw[0] = DotProduct(v0, u); - uvw[1] = DotProduct(v0, v); - uvw[2] = DotProduct(v0, n); - VectorCopy(uvw,uvs[num]); - num++; - for ( l = 0; l < 3; l++) - { - if (uvw[l] < groupMin[l]) - { - groupMin[l] = uvw[l]; - } - if (uvw[l] > groupMax[l]) - { - groupMax[l] = uvw[l]; - } - } - } - } - - xwidth = ceil(0 - groupMin[0]) + 2; // move right of origin and avoid overlap - ywidth = ceil(0 - groupMin[1]) + 2; // move "above" origin - - for ( j=0; j < numverts; j++) - { - uFinal[finalcount] = uvs[j][0] + xwidth + xbase; - vFinal[finalcount] = uvs[j][1] + ywidth; - if (uFinal[finalcount] < uvwMin[0]) - { - uvwMin[0] = uFinal[finalcount]; - } - if (uFinal[finalcount] > uvwMax[0]) - { - uvwMax[0] = uFinal[finalcount]; - } - if (vFinal[finalcount] < uvwMin[1]) - { - uvwMin[1] = vFinal[finalcount]; - } - if (vFinal[finalcount] > uvwMax[1]) - { - uvwMax[1] = vFinal[finalcount]; - } - finalcount++; - } - - fprintf(grpfile,"svdPlaned Group min: ( %f , %f )\n",groupMin[0] + xwidth + xbase, groupMin[1] + ywidth); - fprintf(grpfile,"svdPlaned Group max: ( %f , %f )\n",groupMax[0] + xwidth + xbase, groupMax[1] + ywidth); - - finalcount = finalstart; + //======================= + // NEW GEN + //======================= + + void NewGen (char *ModelFile, char *OutputName, int width, int height) + { + trigroup_t *triangles; + triangle_t *ptri; + triangle_t *grouptris; + mesh_node_t *pmnodes; + + vec3_t *vertices; + vec3_t *uvs; + vec3_t aveNorm, crossvect; + vec3_t diffvect1, diffvect2; + vec3_t v0, v1, v2; + vec3_t n, u, v; + vec3_t base, zaxis, yaxis; + vec3_t uvwMin, uvwMax; + vec3_t groupMin, groupMax; + vec3_t uvw; + + float *uFinal, *vFinal; + unsigned char *newpic; + + int finalstart = 0, finalcount = 0; + int xbase = 0, xwidth = 0, ywidth = 0; + int *todo, *done, finished; + int i, j, k, l; //counters + int groupnum, numtris, numverts, num; + int count; + FILE *grpfile; + long datasize; + + for ( i = 0; i<3; i++) + { + aveNorm[i] = 0; + uvwMin[i] = 1e30f; + uvwMax[i] = -1e30f; + } + + pmnodes = NULL; + ptri = NULL; + triangles = NULL; + + zaxis[0] = 0; + zaxis[1] = 0; + zaxis[2] = 1; + + yaxis[0] = 0; + yaxis[1] = 1; + yaxis[2] = 0; + + LoadTriangleList (ModelFile, &ptri, &fmheader.num_tris, &pmnodes, &fmheader.num_mesh_nodes); + + todo = (int*)SafeMalloc(fmheader.num_tris*sizeof(int), "NewGen"); + done = (int*)SafeMalloc(fmheader.num_tris*sizeof(int), "NewGen"); + triangles = (trigroup_t*)SafeMalloc(fmheader.num_tris*sizeof(trigroup_t), "NewGen"); + + for ( i=0; i < fmheader.num_tris; i++) + { + todo[i] = false; + done[i] = false; + triangles[i].triangle = ptri[i]; + triangles[i].group = 0; + } + + groupnum = 0; + + // transitive closure algorithm follows + // put all triangles who transitively share vertices into separate groups + + while (1) + { + for ( i = 0; i < fmheader.num_tris; i++) + { + if (!done[i]) + { + break; + } + } + if ( i == fmheader.num_tris) + { + break; + } + finished = false; + todo[i] = true; + while (!finished) + { + finished = true; + for ( i = 0; i < fmheader.num_tris; i++) + { + if (todo[i]) + { + done[i] = true; + triangles[i].group = groupnum; + todo[i] = false; + for ( j = 0; j < fmheader.num_tris; j++) + { + if ((!done[j]) && (ShareVertex(triangles[i],triangles[j]))) + { + todo[j] = true; + finished = false; + } + } + } + } + } + groupnum++; + } + uFinal = (float*)SafeMalloc(3*fmheader.num_tris*sizeof(float), "NewGen"); + vFinal = (float*)SafeMalloc(3*fmheader.num_tris*sizeof(float), "NewGen"); + + grpfile = fopen("grpdebug.txt","w"); + + + for (i = 0; i < groupnum; i++) + { + + fprintf(grpfile,"Group Number: %d\n", i); + + numtris = GetNumTris(triangles, i); // number of triangles in group i + numverts = numtris * 3; + + fprintf(grpfile,"%d triangles.\n", numtris); + + vertices = (vec3_t*)SafeMalloc(numverts*sizeof(vec3_t), "NewGen"); + uvs = (vec3_t*)SafeMalloc(numverts*sizeof(vec3_t), "NewGen"); + grouptris = (triangle_t*)SafeMalloc(numtris*sizeof(triangle_t), "NewGen"); + + for (count = 0; count < fmheader.num_tris; count++) + { + if (triangles[count].group == i) + { + fprintf(grpfile,"Triangle %d\n", count); + } + } + fprintf(grpfile,"\n"); + + + + + GetOneGroup(triangles, i, grouptris); + + num = 0; + for (j = 0; j < numtris; j++) + { + VectorCopy(grouptris[j].verts[0], v0); + VectorCopy(grouptris[j].verts[1], v1); + VectorCopy(grouptris[j].verts[2], v2); + VectorSubtract(v1, v0, diffvect1); + VectorSubtract(v2, v1, diffvect2); + CrossProduct( diffvect1, diffvect2, crossvect); + VectorAdd(aveNorm, crossvect, aveNorm); + VectorCopy(v0,vertices[num]); + num++; // FIXME + VectorCopy(v1,vertices[num]); + num++; // add routine to add only verts that + VectorCopy(v2,vertices[num]); + num++; // have not already been added + } + + assert (num >= 3); + // figure out the best plane projections + DOsvdPlane ((float*)vertices, num, (float *)&n, (float *)&base); + + if (DotProduct(aveNorm,n) < 0.0f) + { + VectorScale(n, -1.0f, n); + } + VectorNormalize(n,n); + if (fabs(n[2]) < .57) + { + CrossProduct( zaxis, n, crossvect); + VectorCopy(crossvect, u); + } + else + { + CrossProduct( yaxis, n, crossvect); + VectorCopy(crossvect, u); + } + VectorNormalize(u,u); + CrossProduct( n, u, crossvect); + VectorCopy(crossvect, v); + VectorNormalize(v,v); + + num = 0; + + for ( j = 0; j < 3; j++) + { + groupMin[j] = 1e30f; + groupMax[j] = -1e30f; + } + + for ( j = 0; j < numtris; j++) + { + for ( k = 0; k < 3; k++) + { + VectorCopy(grouptris[j].verts[k],v0); + VectorSubtract(v0, base, v0); + uvw[0] = DotProduct(v0, u); + uvw[1] = DotProduct(v0, v); + uvw[2] = DotProduct(v0, n); + VectorCopy(uvw,uvs[num]); + num++; + for ( l = 0; l < 3; l++) + { + if (uvw[l] < groupMin[l]) + { + groupMin[l] = uvw[l]; + } + if (uvw[l] > groupMax[l]) + { + groupMax[l] = uvw[l]; + } + } + } + } + + xwidth = ceil(0 - groupMin[0]) + 2; // move right of origin and avoid overlap + ywidth = ceil(0 - groupMin[1]) + 2; // move "above" origin + + for ( j=0; j < numverts; j++) + { + uFinal[finalcount] = uvs[j][0] + xwidth + xbase; + vFinal[finalcount] = uvs[j][1] + ywidth; + if (uFinal[finalcount] < uvwMin[0]) + { + uvwMin[0] = uFinal[finalcount]; + } + if (uFinal[finalcount] > uvwMax[0]) + { + uvwMax[0] = uFinal[finalcount]; + } + if (vFinal[finalcount] < uvwMin[1]) + { + uvwMin[1] = vFinal[finalcount]; + } + if (vFinal[finalcount] > uvwMax[1]) + { + uvwMax[1] = vFinal[finalcount]; + } + finalcount++; + } + + fprintf(grpfile,"svdPlaned Group min: ( %f , %f )\n",groupMin[0] + xwidth + xbase, groupMin[1] + ywidth); + fprintf(grpfile,"svdPlaned Group max: ( %f , %f )\n",groupMax[0] + xwidth + xbase, groupMax[1] + ywidth); + + finalcount = finalstart; + + for ( count = 0; count < numverts; count++) + { + fprintf(grpfile,"Vertex %d: ( %f , %f , %f )\n",count,vertices[count][0],vertices[count][1],vertices[count][2]); + fprintf(grpfile,"svdPlaned: ( %f , %f )\n",uFinal[finalcount],vFinal[finalcount++]); + } + + finalstart = finalcount; + + fprintf(grpfile,"\n"); + + free(vertices); + free(uvs); + free(grouptris); + + xbase += ceil(groupMax[0] - groupMin[0]) + 2; + + } + + fprintf(grpfile,"Global Min ( %f , %f )\n",uvwMin[0],uvwMin[1]); + fprintf(grpfile,"Global Max ( %f , %f )\n",uvwMax[0],uvwMax[1]); + + + ScaleTris(uvwMin, uvwMax, width, height, uFinal, vFinal, finalcount); + + for (k = 0; k < finalcount; k++) + { + fprintf(grpfile, "scaled vertex %d: ( %f , %f )\n",k,uFinal[k],vFinal[k]); + } + + // i've got the array of vertices in uFinal and vFinal. Now I need to write them and draw lines + + datasize = width * height*sizeof(unsigned char); + newpic = (unsigned char*)SafeMalloc(datasize, "NewGen"); + memset(newpic,0,datasize); + memset(pic_palette,0,sizeof(pic_palette)); + pic_palette[767] = pic_palette[766] = pic_palette[765] = 255; + + k = 0; + while (k < finalcount) + { + NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height); + k++; + NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height); + k++; + NewDrawLine(uFinal[k], vFinal[k], uFinal[k-2], vFinal[k-2], newpic, width, height); + k++; + fprintf(grpfile, "output tri with verts %d, %d, %d", k-2, k-1, k); + } + + WritePCXfile (OutputName, newpic, width, height, pic_palette); + + fclose(grpfile); + + free(todo); + free(done); + free(triangles); + free(newpic); + return; + } + void NewDrawLine(int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height) + { + long dx, dy; + long adx, ady; + long count; + float xfrac, yfrac, xstep, ystep; + unsigned long sx, sy; + float u, v; + + dx = x2 - x1; + dy = y2 - y1; + adx = abs(dx); + ady = abs(dy); + + count = adx > ady ? adx : ady; + count++; + + if(count > 300) + { + printf("Bad count\n"); + return; // don't ever hang up on bad data + } + + xfrac = x1; + yfrac = y1; + + xstep = (float)dx/count; + ystep = (float)dy/count; + + switch(LineType) + { + case LINE_NORMAL: + do + { + if(xfrac < width && yfrac < height) + { + picture[(long)yfrac*width+(long)xfrac] = LineColor; + } + xfrac += xstep; + yfrac += ystep; + count--; + } while (count > 0); + break; + case LINE_FAT: + do + { + for (u=-0.1 ; u<=0.9 ; u+=0.999) + { + for (v=-0.1 ; v<=0.9 ; v+=0.999) + { + sx = xfrac+u; + sy = yfrac+v; + if(sx < width && sy < height) + { + picture[sy*width+sx] = LineColor; + } + } + } + xfrac += xstep; + yfrac += ystep; + count--; + } while (count > 0); + break; + case LINE_DOTTED: + do + { + if(count&1 && xfrac < width && + yfrac < height) + { + picture[(long)yfrac*width+(long)xfrac] = LineColor; + } + xfrac += xstep; + yfrac += ystep; + count--; + } while (count > 0); + break; + default: + Error("Unknown %d.\n", LineType); + } + } + */ +void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts ){ - for ( count = 0; count < numverts; count++) - { - fprintf(grpfile,"Vertex %d: ( %f , %f , %f )\n",count,vertices[count][0],vertices[count][1],vertices[count][2]); - fprintf(grpfile,"svdPlaned: ( %f , %f )\n",uFinal[finalcount],vFinal[finalcount++]); - } - - finalstart = finalcount; - - fprintf(grpfile,"\n"); - - free(vertices); - free(uvs); - free(grouptris); - - xbase += ceil(groupMax[0] - groupMin[0]) + 2; - - } - - fprintf(grpfile,"Global Min ( %f , %f )\n",uvwMin[0],uvwMin[1]); - fprintf(grpfile,"Global Max ( %f , %f )\n",uvwMax[0],uvwMax[1]); - - - ScaleTris(uvwMin, uvwMax, width, height, uFinal, vFinal, finalcount); - - for (k = 0; k < finalcount; k++) - { - fprintf(grpfile, "scaled vertex %d: ( %f , %f )\n",k,uFinal[k],vFinal[k]); - } - - // i've got the array of vertices in uFinal and vFinal. Now I need to write them and draw lines - - datasize = width * height*sizeof(unsigned char); - newpic = (unsigned char*)SafeMalloc(datasize, "NewGen"); - memset(newpic,0,datasize); - memset(pic_palette,0,sizeof(pic_palette)); - pic_palette[767] = pic_palette[766] = pic_palette[765] = 255; - - k = 0; - while (k < finalcount) - { - NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height); - k++; - NewDrawLine(uFinal[k], vFinal[k], uFinal[k+1], vFinal[k+1], newpic, width, height); - k++; - NewDrawLine(uFinal[k], vFinal[k], uFinal[k-2], vFinal[k-2], newpic, width, height); - k++; - fprintf(grpfile, "output tri with verts %d, %d, %d", k-2, k-1, k); - } - - WritePCXfile (OutputName, newpic, width, height, pic_palette); - - fclose(grpfile); - - free(todo); - free(done); - free(triangles); - free(newpic); - return; -} -void NewDrawLine(int x1, int y1, int x2, int y2, unsigned char* picture, int width, int height) -{ - long dx, dy; - long adx, ady; - long count; - float xfrac, yfrac, xstep, ystep; - unsigned long sx, sy; - float u, v; - - dx = x2 - x1; - dy = y2 - y1; - adx = abs(dx); - ady = abs(dy); - - count = adx > ady ? adx : ady; - count++; - - if(count > 300) - { - printf("Bad count\n"); - return; // don't ever hang up on bad data - } - - xfrac = x1; - yfrac = y1; - - xstep = (float)dx/count; - ystep = (float)dy/count; - - switch(LineType) - { - case LINE_NORMAL: - do - { - if(xfrac < width && yfrac < height) - { - picture[(long)yfrac*width+(long)xfrac] = LineColor; - } - xfrac += xstep; - yfrac += ystep; - count--; - } while (count > 0); - break; - case LINE_FAT: - do - { - for (u=-0.1 ; u<=0.9 ; u+=0.999) - { - for (v=-0.1 ; v<=0.9 ; v+=0.999) - { - sx = xfrac+u; - sy = yfrac+v; - if(sx < width && sy < height) - { - picture[sy*width+sx] = LineColor; - } - } - } - xfrac += xstep; - yfrac += ystep; - count--; - } while (count > 0); - break; - case LINE_DOTTED: - do - { - if(count&1 && xfrac < width && - yfrac < height) - { - picture[(long)yfrac*width+(long)xfrac] = LineColor; - } - xfrac += xstep; - yfrac += ystep; - count--; - } while (count > 0); - break; - default: - Error("Unknown %d.\n", LineType); - } -} -*/ -void ScaleTris( vec3_t min, vec3_t max, int Width, int Height, float* u, float* v, int verts) -{ - - int i; - float hscale, vscale; - float scale; + int i; + float hscale, vscale; + float scale; hscale = max[0]; vscale = max[1]; - hscale = (Width-2) / max[0]; - vscale = (Height-2) / max[1]; + hscale = ( Width - 2 ) / max[0]; + vscale = ( Height - 2 ) / max[1]; scale = hscale; - if (scale > vscale) - { + if ( scale > vscale ) { scale = vscale; } - for ( i = 0; i 32) - { - Error ("Degrees of freedom out of range: %d",groups[num_groups].degrees); + groups[num_groups].degrees = atol( token ); + if ( groups[num_groups].degrees < 1 || groups[num_groups].degrees > 32 ) { + Error( "Degrees of freedom out of range: %d",groups[num_groups].degrees ); } } -void Cmd_FMEndGroup (void) -{ +void Cmd_FMEndGroup( void ){ groups[num_groups].num_frames = fmheader.num_frames - groups[num_groups].start_frame; - if(num_groups < MAX_GROUPS - 1) - { + if ( num_groups < MAX_GROUPS - 1 ) { num_groups++; } else { - Error("Number of compression groups exceded: %i\n", MAX_GROUPS); + Error( "Number of compression groups exceded: %i\n", MAX_GROUPS ); } } -