doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Model_md3.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 #include "../idlib/precompiled.h"
29 #pragma hdrstop
30 
31 #include "tr_local.h"
32 #include "Model_local.h"
33 #include "Model_md3.h"
34 
35 /***********************************************************************
36 
37  idMD3Mesh
38 
39 ***********************************************************************/
40 
41 #define LL(x) x=LittleLong(x)
42 
43 /*
44 =================
45 idRenderModelMD3::InitFromFile
46 =================
47 */
48 void idRenderModelMD3::InitFromFile( const char *fileName ) {
49  int i, j;
50  md3Header_t *pinmodel;
51  md3Frame_t *frame;
52  md3Surface_t *surf;
53  md3Shader_t *shader;
54  md3Triangle_t *tri;
55  md3St_t *st;
56  md3XyzNormal_t *xyz;
57  md3Tag_t *tag;
58  void *buffer;
59  int version;
60  int size;
61 
62 
63  name = fileName;
64 
65  size = fileSystem->ReadFile( fileName, &buffer, NULL );
66  if (!size || size<0 ) {
67  return;
68  }
69 
70  pinmodel = (md3Header_t *)buffer;
71 
72  version = LittleLong (pinmodel->version);
73  if (version != MD3_VERSION) {
74  fileSystem->FreeFile( buffer );
75  common->Warning( "InitFromFile: %s has wrong version (%i should be %i)",
76  fileName, version, MD3_VERSION);
77  return;
78  }
79 
80  size = LittleLong(pinmodel->ofsEnd);
81  dataSize += size;
82  md3 = (md3Header_t *)Mem_Alloc( size );
83 
84  memcpy (md3, buffer, LittleLong(pinmodel->ofsEnd) );
85 
86  LL(md3->ident);
87  LL(md3->version);
88  LL(md3->numFrames);
89  LL(md3->numTags);
90  LL(md3->numSurfaces);
91  LL(md3->ofsFrames);
92  LL(md3->ofsTags);
93  LL(md3->ofsSurfaces);
94  LL(md3->ofsEnd);
95 
96  if ( md3->numFrames < 1 ) {
97  common->Warning( "InitFromFile: %s has no frames", fileName );
98  fileSystem->FreeFile( buffer );
99  return;
100  }
101 
102  // swap all the frames
103  frame = (md3Frame_t *) ( (byte *)md3 + md3->ofsFrames );
104  for ( i = 0 ; i < md3->numFrames ; i++, frame++) {
105  frame->radius = LittleFloat( frame->radius );
106  for ( j = 0 ; j < 3 ; j++ ) {
107  frame->bounds[0][j] = LittleFloat( frame->bounds[0][j] );
108  frame->bounds[1][j] = LittleFloat( frame->bounds[1][j] );
109  frame->localOrigin[j] = LittleFloat( frame->localOrigin[j] );
110  }
111  }
112 
113  // swap all the tags
114  tag = (md3Tag_t *) ( (byte *)md3 + md3->ofsTags );
115  for ( i = 0 ; i < md3->numTags * md3->numFrames ; i++, tag++) {
116  for ( j = 0 ; j < 3 ; j++ ) {
117  tag->origin[j] = LittleFloat( tag->origin[j] );
118  tag->axis[0][j] = LittleFloat( tag->axis[0][j] );
119  tag->axis[1][j] = LittleFloat( tag->axis[1][j] );
120  tag->axis[2][j] = LittleFloat( tag->axis[2][j] );
121  }
122  }
123 
124  // swap all the surfaces
125  surf = (md3Surface_t *) ( (byte *)md3 + md3->ofsSurfaces );
126  for ( i = 0 ; i < md3->numSurfaces ; i++) {
127 
128  LL(surf->ident);
129  LL(surf->flags);
130  LL(surf->numFrames);
131  LL(surf->numShaders);
132  LL(surf->numTriangles);
133  LL(surf->ofsTriangles);
134  LL(surf->numVerts);
135  LL(surf->ofsShaders);
136  LL(surf->ofsSt);
137  LL(surf->ofsXyzNormals);
138  LL(surf->ofsEnd);
139 
140  if ( surf->numVerts > SHADER_MAX_VERTEXES ) {
141  common->Error( "InitFromFile: %s has more than %i verts on a surface (%i)",
142  fileName, SHADER_MAX_VERTEXES, surf->numVerts );
143  }
144  if ( surf->numTriangles*3 > SHADER_MAX_INDEXES ) {
145  common->Error( "InitFromFile: %s has more than %i triangles on a surface (%i)",
146  fileName, SHADER_MAX_INDEXES / 3, surf->numTriangles );
147  }
148 
149  // change to surface identifier
150  surf->ident = 0; //SF_MD3;
151 
152  // lowercase the surface name so skin compares are faster
153  int slen = (int)strlen( surf->name );
154  for( j = 0; j < slen; j++ ) {
155  surf->name[j] = tolower( surf->name[j] );
156  }
157 
158  // strip off a trailing _1 or _2
159  // this is a crutch for q3data being a mess
160  j = strlen( surf->name );
161  if ( j > 2 && surf->name[j-2] == '_' ) {
162  surf->name[j-2] = 0;
163  }
164 
165  // register the shaders
166  shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
167  for ( j = 0 ; j < surf->numShaders ; j++, shader++ ) {
168  const idMaterial *sh;
169 
170  sh = declManager->FindMaterial( shader->name );
171  shader->shader = sh;
172  }
173 
174  // swap all the triangles
175  tri = (md3Triangle_t *) ( (byte *)surf + surf->ofsTriangles );
176  for ( j = 0 ; j < surf->numTriangles ; j++, tri++ ) {
177  LL(tri->indexes[0]);
178  LL(tri->indexes[1]);
179  LL(tri->indexes[2]);
180  }
181 
182  // swap all the ST
183  st = (md3St_t *) ( (byte *)surf + surf->ofsSt );
184  for ( j = 0 ; j < surf->numVerts ; j++, st++ ) {
185  st->st[0] = LittleFloat( st->st[0] );
186  st->st[1] = LittleFloat( st->st[1] );
187  }
188 
189  // swap all the XyzNormals
190  xyz = (md3XyzNormal_t *) ( (byte *)surf + surf->ofsXyzNormals );
191  for ( j = 0 ; j < surf->numVerts * surf->numFrames ; j++, xyz++ )
192  {
193  xyz->xyz[0] = LittleShort( xyz->xyz[0] );
194  xyz->xyz[1] = LittleShort( xyz->xyz[1] );
195  xyz->xyz[2] = LittleShort( xyz->xyz[2] );
196 
197  xyz->normal = LittleShort( xyz->normal );
198  }
199 
200 
201  // find the next surface
202  surf = (md3Surface_t *)( (byte *)surf + surf->ofsEnd );
203  }
204 
205  fileSystem->FreeFile( buffer );
206 }
207 
208 /*
209 =================
210 idRenderModelMD3::IsDynamicModel
211 =================
212 */
214  return DM_CACHED;
215 }
216 
217 /*
218 =================
219 idRenderModelMD3::LerpMeshVertexes
220 =================
221 */
222 void idRenderModelMD3::LerpMeshVertexes ( srfTriangles_t *tri, const struct md3Surface_s *surf, const float backlerp, const int frame, const int oldframe ) const {
223  short *oldXyz, *newXyz;
224  float oldXyzScale, newXyzScale;
225  int vertNum;
226  int numVerts;
227 
228  newXyz = (short *)((byte *)surf + surf->ofsXyzNormals) + (frame * surf->numVerts * 4);
229 
230  newXyzScale = MD3_XYZ_SCALE * (1.0 - backlerp);
231 
232  numVerts = surf->numVerts;
233 
234  if ( backlerp == 0 ) {
235  //
236  // just copy the vertexes
237  //
238  for (vertNum=0 ; vertNum < numVerts ; vertNum++, newXyz += 4 ) {
239 
240  idDrawVert *outvert = &tri->verts[tri->numVerts];
241 
242  outvert->xyz.x = newXyz[0] * newXyzScale;
243  outvert->xyz.y = newXyz[1] * newXyzScale;
244  outvert->xyz.z = newXyz[2] * newXyzScale;
245 
246  tri->numVerts++;
247  }
248  } else {
249  //
250  // interpolate and copy the vertexes
251  //
252  oldXyz = (short *)((byte *)surf + surf->ofsXyzNormals) + (oldframe * surf->numVerts * 4);
253 
254  oldXyzScale = MD3_XYZ_SCALE * backlerp;
255 
256  for (vertNum=0 ; vertNum < numVerts ; vertNum++, oldXyz += 4, newXyz += 4 ) {
257 
258  idDrawVert *outvert = &tri->verts[tri->numVerts];
259 
260  // interpolate the xyz
261  outvert->xyz.x = oldXyz[0] * oldXyzScale + newXyz[0] * newXyzScale;
262  outvert->xyz.y = oldXyz[1] * oldXyzScale + newXyz[1] * newXyzScale;
263  outvert->xyz.z = oldXyz[2] * oldXyzScale + newXyz[2] * newXyzScale;
264 
265  tri->numVerts++;
266  }
267  }
268 }
269 
270 /*
271 =============
272 idRenderModelMD3::InstantiateDynamicModel
273 =============
274 */
275 idRenderModel *idRenderModelMD3::InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) {
276  int i, j;
277  float backlerp;
278  int * triangles;
279  float * texCoords;
280  int indexes;
281  int numVerts;
282  md3Surface_t * surface;
283  int frame, oldframe;
284  idRenderModelStatic *staticModel;
285 
286  if ( cachedModel ) {
287  delete cachedModel;
288  cachedModel = NULL;
289  }
290 
291  staticModel = new idRenderModelStatic;
292  staticModel->bounds.Clear();
293 
294  surface = (md3Surface_t *) ((byte *)md3 + md3->ofsSurfaces);
295 
296  // TODO: these need set by an entity
297  frame = ent->shaderParms[SHADERPARM_MD3_FRAME]; // probably want to keep frames < 1000 or so
298  oldframe = ent->shaderParms[SHADERPARM_MD3_LASTFRAME];
299  backlerp = ent->shaderParms[SHADERPARM_MD3_BACKLERP];
300 
301  for( i = 0; i < md3->numSurfaces; i++ ) {
302 
304  R_AllocStaticTriSurfVerts( tri, surface->numVerts );
305  R_AllocStaticTriSurfIndexes( tri, surface->numTriangles * 3 );
306  tri->bounds.Clear();
307 
308  modelSurface_t surf;
309 
310  surf.geometry = tri;
311 
312  md3Shader_t* shaders = (md3Shader_t *) ((byte *)surface + surface->ofsShaders);
313  surf.shader = shaders->shader;
314 
315  LerpMeshVertexes( tri, surface, backlerp, frame, oldframe );
316 
317  triangles = (int *) ((byte *)surface + surface->ofsTriangles);
318  indexes = surface->numTriangles * 3;
319  for (j = 0 ; j < indexes ; j++) {
320  tri->indexes[j] = triangles[j];
321  }
322  tri->numIndexes += indexes;
323 
324  texCoords = (float *) ((byte *)surface + surface->ofsSt);
325 
326  numVerts = surface->numVerts;
327  for ( j = 0; j < numVerts; j++ ) {
328  idDrawVert *stri = &tri->verts[j];
329  stri->st[0] = texCoords[j*2+0];
330  stri->st[1] = texCoords[j*2+1];
331  }
332 
333  R_BoundTriSurf( tri );
334 
335  staticModel->AddSurface( surf );
336  staticModel->bounds.AddPoint( surf.geometry->bounds[0] );
337  staticModel->bounds.AddPoint( surf.geometry->bounds[1] );
338 
339  // find the next surface
340  surface = (md3Surface_t *)( (byte *)surface + surface->ofsEnd );
341  }
342 
343  return staticModel;
344 }
345 
346 /*
347 =====================
348 idRenderModelMD3::Bounds
349 =====================
350 */
351 
353  idBounds ret;
354 
355  ret.Clear();
356 
357  if (!ent || !md3) {
358  // just give it the editor bounds
359  ret.AddPoint(idVec3(-10,-10,-10));
360  ret.AddPoint(idVec3( 10, 10, 10));
361  return ret;
362  }
363 
364  md3Frame_t *frame = (md3Frame_t *)( (byte *)md3 + md3->ofsFrames );
365 
366  ret.AddPoint( frame->bounds[0] );
367  ret.AddPoint( frame->bounds[1] );
368 
369  return ret;
370 }
371 
char name[MAX_Q3PATH]
Definition: exporter.h:305
int version
Definition: exporter.h:324
const int SHADERPARM_MD3_BACKLERP
Definition: RenderWorld.h:61
int numTriangles
Definition: exporter.h:294
int ofsXyzNormals
Definition: Model_md3.h:102
int numVerts
Definition: Model.h:98
short xyz[3]
Definition: exporter.h:318
const idMaterial * shader
Definition: Model_md3.h:109
void LerpMeshVertexes(srfTriangles_t *tri, const struct md3Surface_s *surf, const float backlerp, const int frame, const int oldframe) const
Definition: Model_md3.cpp:222
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
idVec3 xyz
Definition: DrawVert.h:42
float z
Definition: Vector.h:320
case const int
Definition: Callbacks.cpp:52
int ofsXyzNormals
Definition: exporter.h:299
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
const idMaterial * shader
Definition: Model.h:146
Definition: Vector.h:316
short normal
Definition: exporter.h:319
int numFrames
Definition: exporter.h:289
void Clear(void)
Definition: Bounds.h:201
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
srfTriangles_t * R_AllocStaticTriSurf(void)
Definition: tr_trisurf.cpp:523
#define SHADER_MAX_VERTEXES
Definition: exporter.h:253
float x
Definition: Vector.h:318
int i
Definition: process.py:33
virtual void FreeFile(void *buffer)=0
int ofsSurfaces
Definition: Model_md3.h:141
virtual void InitFromFile(const char *fileName)
Definition: Model_md3.cpp:48
int numShaders
Definition: exporter.h:291
idVec3 bounds[2]
Definition: exporter.h:261
int numSurfaces
Definition: Model_md3.h:135
int ofsEnd
Definition: exporter.h:340
struct version_s version
int ofsFrames
Definition: Model_md3.h:139
bool AddPoint(const idVec3 &v)
Definition: Bounds.h:226
idVec2 st
Definition: DrawVert.h:43
idVec3 origin
Definition: exporter.h:269
virtual idBounds Bounds(const struct renderEntity_s *ent) const
Definition: Model_md3.cpp:352
idBounds bounds
Definition: Model.h:87
idCommon * common
Definition: Common.cpp:206
float radius
Definition: exporter.h:263
#define NULL
Definition: Lib.h:88
srfTriangles_t * geometry
Definition: Model.h:147
virtual idRenderModel * InstantiateDynamicModel(const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel)
Definition: Model_md3.cpp:275
float y
Definition: Vector.h:319
char name[MAX_Q3PATH]
Definition: exporter.h:286
GLuint buffer
Definition: glext.h:3108
#define MD3_VERSION
Definition: exporter.h:238
#define SHADER_MAX_INDEXES
Definition: exporter.h:254
void R_BoundTriSurf(srfTriangles_t *tri)
Definition: tr_trisurf.cpp:704
float st[2]
Definition: exporter.h:314
int LittleLong(int l)
Definition: Lib.cpp:281
struct md3Header_s * md3
Definition: Model_local.h:218
const int SHADERPARM_MD3_FRAME
Definition: RenderWorld.h:59
idDeclManager * declManager
const int SHADERPARM_MD3_LASTFRAME
Definition: RenderWorld.h:60
int numVerts
Definition: Model_md3.h:95
short LittleShort(short l)
Definition: Lib.cpp:279
int indexes[3]
Definition: exporter.h:310
unsigned char byte
Definition: Lib.h:75
dynamicModel_t
Definition: Model.h:150
const GLcharARB * name
Definition: glext.h:3629
GLfloat * st
Definition: qgl.h:89
GLsizeiptr size
Definition: glext.h:3112
idVec3 localOrigin
Definition: exporter.h:262
glIndex_t * indexes
Definition: Model.h:102
float LittleFloat(float l)
Definition: Lib.cpp:283
void R_AllocStaticTriSurfIndexes(srfTriangles_t *tri, int numIndexes)
Definition: tr_trisurf.cpp:565
void * Mem_Alloc(const int size)
Definition: Heap.cpp:1067
GLint j
Definition: qgl.h:264
int ofsTriangles
Definition: exporter.h:295
int numIndexes
Definition: Model.h:101
#define MD3_XYZ_SCALE
Definition: exporter.h:250
virtual void Error(const char *fmt,...) id_attribute((format(printf
int ofsShaders
Definition: exporter.h:297
int numFrames
Definition: Model_md3.h:133
void R_AllocStaticTriSurfVerts(srfTriangles_t *tri, int numVerts)
Definition: tr_trisurf.cpp:555
virtual dynamicModel_t IsDynamicModel() const
Definition: Model_md3.cpp:213
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
float shaderParms[MAX_ENTITY_SHADER_PARMS]
Definition: RenderWorld.h:127
#define LL(x)
Definition: Model_md3.cpp:41
idDrawVert * verts
Definition: Model.h:99
idVec3 axis[3]
Definition: exporter.h:270
virtual void AddSurface(modelSurface_t surface)
Definition: Model.cpp:355
int numVerts
Definition: exporter.h:292