/* Texture Paint - a GIMP plugin * * Copyright (C) 1998 Uwe Maurer * * This program 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. * * 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 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 #include #include #include #include "texturepaint.h" #include "model.h" #include "q1pal.h" #define MDL_VERSION 6 /* MDL (Quake I) Model */ typedef struct { gint32 ident; gint32 version; vec3_t scale; vec3_t origin; gfloat radius; vec3_t offsets; gint32 num_skins; gint32 skin_width; gint32 skin_height; gint32 num_verts; gint32 num_tris; gint32 num_frames; gint32 sync_type; gint32 flags; gfloat size; } Model1Header; typedef struct { gint32 onseam; gint32 s; gint32 t; } stvert_t; typedef struct { gint32 facesfront; gint32 v[3]; } mdl_triangle_t; typedef struct { unsigned char p[3]; unsigned char normal; } vertex_t; typedef struct { vertex_t min,max; char name[16]; } frame_t; static void destroy(Model *mdl) { g_free(mdl->tri); g_free(mdl->vertex); g_free(mdl->frames); g_free(mdl); } static void draw(Model *mdl,int frame,int nextframe,float interp) { int i,j,v; vec3_t *vertex; gfloat x,y,z; frame= (frame % mdl->numframes)*mdl->num_verts; nextframe= (nextframe % mdl->numframes)*mdl->num_verts; vertex=mdl->vertex; glBegin(GL_TRIANGLES); for (i=0;inum_tris;i++) { for (j=0;j<3;j++) { v=mdl->tri[i].v[j]; x= vertex[frame+v].x + (vertex[nextframe+v].x-vertex[frame+v].x)*interp; y= vertex[frame+v].y + (vertex[nextframe+v].y-vertex[frame+v].y)*interp; z= vertex[frame+v].z + (vertex[nextframe+v].z-vertex[frame+v].z)*interp; glTexCoord2fv(mdl->tri[i].tex[j]); glVertex3f(x,y,z); } } glEnd(); } Model *Model1Load(char *name,FILE *fp) { Model1Header header; Model *mdl; int i,k,f; gint32 dummy; guchar *texture; gint size; gint32 image_id,layer_id; GimpPixelRgn rgn; GimpDrawable *drawable; gint w,h; stvert_t *stvert; mdl_triangle_t *triangle; vertex_t *vertex; frame_t frame; gfloat x,y,z; gint v; gfloat xmin,xmax,ymax,ymin,zmax,zmin,scale; char filename[300]; fread(&header,sizeof(header),1,fp); if (strncmp((char *)&header.ident,"IDPO",4)!=0) return NULL; if (header.version!=MDL_VERSION) return NULL; mdl=g_malloc(sizeof(*mdl)); memset(mdl,0,sizeof(*mdl)); mdl->num_tris=header.num_tris; mdl->num_verts=header.num_verts; w=header.skin_width; h=header.skin_height; size=w*h; texture=g_malloc(size); image_id=-1; for (i=0;itri=g_malloc(header.num_tris*sizeof(triangle_t)); mdl->vertex=g_malloc(header.num_frames*header.num_verts*sizeof(mdl->vertex[0])); size=header.num_verts*sizeof(vertex_t); vertex=g_malloc(size); mdl->frames=g_malloc(header.num_frames*sizeof(mdl->frames[0])); mdl->numframes=header.num_frames; xmax=-G_MAXFLOAT; ymax=-G_MAXFLOAT; zmax=-G_MAXFLOAT; xmin=+G_MAXFLOAT; ymin=+G_MAXFLOAT; zmin=+G_MAXFLOAT; for (f=k=0;fframes[f].name,frame.name,16); fread(vertex,size,1,fp); for (i=0;ivertex[k].x=x; mdl->vertex[k].y=y; mdl->vertex[k].z=z; if (x>xmax) xmax=x; if (xymax) ymax=y; if (yzmax) zmax=z; if (zscale) scale=y; if (z>scale) scale=z; if (scale) scale=1/scale; else scale=1; x=(xmax+xmin)/2; y=(ymax+ymin)/2; z=(zmax+zmin)/2; for (i=0;ivertex[i].x=(mdl->vertex[i].x-x)*scale; mdl->vertex[i].y=(mdl->vertex[i].y-y)*scale; mdl->vertex[i].z=(mdl->vertex[i].z-z)*scale; } for (i=0;itri[i].v[k]=v; mdl->tri[i].tex[k][0]=x; mdl->tri[i].tex[k][1]=y; } } g_free(vertex); g_free(stvert); g_free(triangle); mdl->destroy=destroy; mdl->draw=draw; return mdl; }