summaryrefslogtreecommitdiff
path: root/source/gl_models.c
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2008-08-16 10:19:42 +0000
committerAndrey Nazarov <skuller@skuller.net>2008-08-16 10:19:42 +0000
commit1526e22e4ff29153e9c127081e8ea8d9e2f33b8c (patch)
treeb361766433d4a7b4a111865afd52803e2bbf7754 /source/gl_models.c
parente826e5f176f21cd18b3bbc22887a266835ada57c (diff)
Split some monolithic include files into smaller ones.
Use single BSP models cache for refresh and collision subsystems. Refresh libraries may not longer be dynamically loaded. Made gi.TagMalloc use separate tag namespace to avoid conflicts with engine reserverd tags. Fixed listing order of MVD channels in chooser menu. A lot of misc changes... MSVC build is definitely broken now.
Diffstat (limited to 'source/gl_models.c')
-rw-r--r--source/gl_models.c832
1 files changed, 143 insertions, 689 deletions
diff --git a/source/gl_models.c b/source/gl_models.c
index 7937512..b2ff3d5 100644
--- a/source/gl_models.c
+++ b/source/gl_models.c
@@ -19,255 +19,59 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "gl_local.h"
-
-#define Model_Malloc( size ) sys.HunkAlloc( &model->pool, size )
-
-static model_t r_models[MAX_MODELS];
-static int r_numModels;
-
-static byte ll2byte[256][256];
-
-static cvar_t *gl_override_models;
-
-static model_t *Model_Alloc( const char *name ) {
- model_t *model;
- int i;
-
- for( i = 0, model = r_models; i < r_numModels; i++, model++ ) {
- if( !model->name[0] ) {
- break;
- }
- }
-
- if( i == r_numModels ) {
- if( r_numModels == MAX_MODELS ) {
- Com_Error( ERR_DROP, "Model_Alloc: MAX_MODELS" );
- }
- r_numModels++;
- }
-
- strcpy( model->name, name );
- model->registration_sequence = registration_sequence;
- model->type = MODEL_NULL;
-
- return model;
-}
-
-static model_t *Model_Find( const char *name ) {
- model_t *model;
- aliasMesh_t *mesh;
- int i, j;
-
- for( i = 0, model = r_models; i < r_numModels; i++, model++ ) {
- if( !model->name[0] ) {
- continue;
- }
- if( !Q_stricmp( model->name, name ) ) {
- break;
- }
- }
-
- if( i == r_numModels ) {
- return NULL;
- }
-
- switch( model->type ) {
- case MODEL_ALIAS:
- for( i = 0; i < model->numMeshes; i++ ) {
- mesh = &model->meshes[i];
- for( j = 0; j < mesh->numSkins; j++ ) {
- mesh->skins[j]->registration_sequence = registration_sequence;
- }
- }
- break;
- case MODEL_SPRITE:
- for( i = 0; i < model->numFrames; i++ ) {
- model->sframes[i].image->registration_sequence = registration_sequence;
- }
- break;
- default:
- Com_Error( ERR_DROP, "Model_Find: bad model type: %d", model->type );
- break;
- }
-
- model->registration_sequence = registration_sequence;
- return model;
-}
-
-static void Model_List_f( void ) {
- int i;
- model_t *model;
- int bytes;
-
- Com_Printf( "------------------\n");
- bytes = 0;
-
- for( i = 0, model = r_models; i < r_numModels; i++, model++ ) {
- if( !model->name[0] ) {
- continue;
- }
-
- Com_Printf( "%8"PRIz" : %s\n", model->pool.cursize, model->name );
- bytes += model->pool.cursize;
- }
- Com_Printf( "Total resident: %i\n", bytes );
-}
-
-void Model_FreeUnused( void ) {
- model_t *model;
- int i;
-
- for( i = 0, model = r_models; i < r_numModels; i++, model++ ) {
- if( !model->name[0] ) {
- continue;
- }
- if( model->registration_sequence != registration_sequence ) {
- sys.HunkFree( &model->pool );
- model->name[0] = 0;
- }
- }
-}
-
-void Model_FreeAll( void ) {
- model_t *model;
- int i;
-
- for( i = 0, model = r_models; i < r_numModels; i++, model++ ) {
- if( !model->name[0] ) {
- continue;
- }
-
- sys.HunkFree( &model->pool );
- model->name[0] = 0;
- }
-
- r_numModels = 0;
-}
-
-static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length ) {
- dmdl_t header;
- daliasframe_t *src_frame;
- dtrivertx_t *src_vert;
- dtriangle_t *src_tri;
- dstvert_t *src_tc;
- aliasFrame_t *dst_frame;
- aliasVert_t *dst_vert;
- aliasMesh_t *dst_mesh;
+#include "d_md2.h"
+#include "d_md3.h"
+#include "d_sp2.h"
+
+qboolean MOD_LoadMD2( model_t *model, const void *rawdata, size_t length ) {
+ dmd2header_t header;
+ dmd2frame_t *src_frame;
+ dmd2trivertx_t *src_vert;
+ dmd2triangle_t *src_tri;
+ dmd2stvert_t *src_tc;
+ maliasframe_t *dst_frame;
+ maliasvert_t *dst_vert;
+ maliasmesh_t *dst_mesh;
uint32_t *finalIndices;
- tcoord_t *dst_tc;
+ maliastc_t *dst_tc;
int i, j, k;
- uint16_t remap[MAX_TRIANGLES*3];
- uint16_t vertIndices[MAX_TRIANGLES*3];
- uint16_t tcIndices[MAX_TRIANGLES*3];
- int numVerts, numIndices;
+ uint16_t remap[MD2_MAX_TRIANGLES*3];
+ uint16_t vertIndices[MD2_MAX_TRIANGLES*3];
+ uint16_t tcIndices[MD2_MAX_TRIANGLES*3];
+ int numverts, numindices;
char skinname[MAX_QPATH];
char *src_skin;
image_t *skin;
vec_t scaleS, scaleT;
int val;
vec3_t mins, maxs;
- const byte *rawend;
-
-#define ERR( x ) \
- Com_WPrintf( "LoadMD2: %s: " x "\n", model->name )
if( length < sizeof( header ) ) {
- ERR( "file too short" );
+ Com_WPrintf( "%s is too short\n", model->name );
return qfalse;
}
/* byte swap the header */
- header = *( dmdl_t * )rawdata;
+ header = *( dmd2header_t * )rawdata;
for( i = 0; i < sizeof( header )/4; i++ ) {
(( uint32_t * )&header)[i] = LittleLong( (( uint32_t * )&header)[i] );
}
- // check ident and version
- if( header.ident != IDALIASHEADER ) {
- ERR( "not an MD2 file" );
- return qfalse;
- }
- if( header.version != ALIAS_VERSION ) {
- ERR( "bad version" );
- return qfalse;
- }
-
- // check triangles
- if( header.num_tris < 1 || header.num_tris > MAX_TRIANGLES ) {
- ERR( "bad number of triangles" );
- return qfalse;
- }
- if( header.ofs_tris < sizeof( header ) ||
- header.ofs_tris + sizeof( dtriangle_t ) * header.num_tris > length )
- {
- ERR( "bad triangles offset" );
- return qfalse;
- }
-
- // check st
- if( header.num_st < 3 || header.num_st > MAX_VERTS ) {
- ERR( "bad number of st" );
- return qfalse;
- }
- if( header.ofs_st < sizeof( header ) ||
- header.ofs_st + sizeof( dstvert_t ) * header.num_st > length )
- {
- ERR( "bad st offset" );
- return qfalse;
- }
-
- // check xyz and frames
- if( header.num_xyz < 3 || header.num_xyz > MAX_VERTS ) {
- ERR( "bad number of xyz" );
- return qfalse;
- }
- if( header.num_frames < 1 || header.num_frames > MAX_FRAMES ) {
- ERR( "bad number of frames" );
- return qfalse;
- }
- if( header.framesize < sizeof( daliasframe_t ) + ( header.num_xyz - 1 ) * sizeof( dtrivertx_t ) ||
- header.framesize > MAX_FRAMESIZE )
- {
- ERR( "bad frame size" );
- return qfalse;
- }
- if( header.ofs_frames < sizeof( header ) ||
- header.ofs_frames + header.framesize * header.num_frames > length )
- {
- ERR( "bad frames offset" );
- return qfalse;
+ if( !MOD_ValidateMD2( model, &header, length ) ) {
+ return qfalse;
}
- // check skins
- if( header.num_skins < 0 || header.num_skins > MAX_MD2SKINS ) {
- ERR( "bad number of skins" );
- return qfalse;
- }
- if( header.num_skins && ( header.ofs_skins < sizeof( header ) ||
- header.ofs_skins + MAX_SKINNAME * header.num_skins > length ) )
- {
- ERR( "bad skins offset" );
- return qfalse;
- }
- if( header.skinwidth <= 0 || header.skinheight <= 0 ) {
- ERR( "bad skin dimensions" );
- return qfalse;
- }
-
- rawend = rawdata + length;
-
- model->type = MODEL_ALIAS;
- sys.HunkBegin( &model->pool, 0x400000 );
+ Hunk_Begin( &model->pool, 0x400000 );
/* load all triangle indices */
- src_tri = ( dtriangle_t * )( ( byte * )rawdata + header.ofs_tris );
+ src_tri = ( dmd2triangle_t * )( ( byte * )rawdata + header.ofs_tris );
for( i = 0; i < header.num_tris; i++ ) {
for( j = 0; j < 3; j++ ) {
uint16_t idx_xyz = LittleShort( src_tri->index_xyz[j] );
uint16_t idx_st = LittleShort( src_tri->index_st[j] );
- if( idx_xyz > header.num_xyz || idx_st > header.num_st ) {
- ERR( "bad indices" );
+ if( idx_xyz >= header.num_xyz || idx_st >= header.num_st ) {
+ Com_WPrintf( "%s has bad triangle indices\n", model->name );
goto fail;
}
@@ -277,68 +81,68 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length )
src_tri++;
}
- numIndices = header.num_tris * 3;
+ numindices = header.num_tris * 3;
- model->meshes = Model_Malloc( sizeof( aliasMesh_t ) );
- model->numMeshes = 1;
+ model->meshes = Model_Malloc( sizeof( maliasmesh_t ) );
+ model->nummeshes = 1;
dst_mesh = model->meshes;
- dst_mesh->indices = Model_Malloc( numIndices * sizeof( uint32_t ) );
- dst_mesh->numTris = header.num_tris;
- dst_mesh->numIndices = numIndices;
+ dst_mesh->indices = Model_Malloc( numindices * sizeof( uint32_t ) );
+ dst_mesh->numtris = header.num_tris;
+ dst_mesh->numindices = numindices;
- for( i = 0; i < numIndices; i++ ) {
+ for( i = 0; i < numindices; i++ ) {
remap[i] = 0xFFFF;
}
- numVerts = 0;
- src_tc = ( dstvert_t * )( ( byte * )rawdata + header.ofs_st );
+ numverts = 0;
+ src_tc = ( dmd2stvert_t * )( ( byte * )rawdata + header.ofs_st );
finalIndices = dst_mesh->indices;
- for( i = 0; i < numIndices; i++ ) {
+ for( i = 0; i < numindices; i++ ) {
if( remap[i] != 0xFFFF ) {
continue; /* already remapped */
}
- for( j = i + 1; j < numIndices; j++ ) {
+ for( j = i + 1; j < numindices; j++ ) {
if( vertIndices[i] == vertIndices[j] &&
( src_tc[tcIndices[i]].s == src_tc[tcIndices[j]].s &&
src_tc[tcIndices[i]].t == src_tc[tcIndices[j]].t ) )
{
/* duplicate vertex */
remap[j] = i;
- finalIndices[j] = numVerts;
+ finalIndices[j] = numverts;
}
}
/* new vertex */
remap[i] = i;
- finalIndices[i] = numVerts++;
+ finalIndices[i] = numverts++;
}
- dst_mesh->verts = Model_Malloc( numVerts * header.num_frames * sizeof( aliasVert_t ) );
- dst_mesh->tcoords = Model_Malloc( numVerts * sizeof( tcoord_t ) );
- dst_mesh->numVerts = numVerts;
+ dst_mesh->verts = Model_Malloc( numverts * header.num_frames * sizeof( maliasvert_t ) );
+ dst_mesh->tcoords = Model_Malloc( numverts * sizeof( maliastc_t ) );
+ dst_mesh->numverts = numverts;
/* load all skins */
src_skin = ( char * )rawdata + header.ofs_skins;
for( i = 0; i < header.num_skins; i++ ) {
Q_strncpyz( skinname, src_skin, sizeof( skinname ) );
- skin = R_FindImage( skinname, it_skin );
+ skin = IMG_Find( skinname, it_skin );
if( !skin ) {
skin = r_notexture;
}
dst_mesh->skins[i] = skin;
- src_skin += MAX_SKINNAME;
+ src_skin += MD2_MAX_SKINNAME;
}
- dst_mesh->numSkins = header.num_skins;
+ dst_mesh->numskins = header.num_skins;
/* load all tcoords */
- src_tc = ( dstvert_t * )( ( byte * )rawdata + header.ofs_st );
+ src_tc = ( dmd2stvert_t * )( ( byte * )rawdata + header.ofs_st );
dst_tc = dst_mesh->tcoords;
skin = dst_mesh->skins[0];
scaleS = 1.0f / header.skinwidth;
scaleT = 1.0f / header.skinheight;
- for( i = 0; i < numIndices; i++ ) {
+ for( i = 0; i < numindices; i++ ) {
if( remap[i] == i ) {
float s = ( signed short )LittleShort( src_tc[ tcIndices[i] ].s );
float t = ( signed short )LittleShort( src_tc[ tcIndices[i] ].t );
@@ -349,10 +153,10 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length )
}
/* load all frames */
- model->frames = Model_Malloc( header.num_frames * sizeof( aliasFrame_t ) );
- model->numFrames = header.num_frames;
+ model->frames = Model_Malloc( header.num_frames * sizeof( maliasframe_t ) );
+ model->numframes = header.num_frames;
- src_frame = ( daliasframe_t * )( ( byte * )rawdata + header.ofs_frames );
+ src_frame = ( dmd2frame_t * )( ( byte * )rawdata + header.ofs_frames );
dst_frame = model->frames;
for( j = 0; j < header.num_frames; j++ ) {
LittleVector( src_frame->scale, dst_frame->scale );
@@ -360,20 +164,20 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length )
/* load frame vertices */
ClearBounds( mins, maxs );
- for( i = 0; i < numIndices; i++ ) {
+ for( i = 0; i < numindices; i++ ) {
if( remap[i] == i ) {
src_vert = &src_frame->verts[ vertIndices[i] ];
- dst_vert = &dst_mesh->verts[ j * numVerts + finalIndices[i] ];
+ dst_vert = &dst_mesh->verts[ j * numverts + finalIndices[i] ];
dst_vert->pos[0] = src_vert->v[0];
dst_vert->pos[1] = src_vert->v[1];
dst_vert->pos[2] = src_vert->v[2];
k = src_vert->lightnormalindex;
if( k >= NUMVERTEXNORMALS ) {
- ERR( "bad normal index" );
+ Com_WPrintf( "%s has bad normal indices\n", model->name );
goto fail;
}
- dst_vert->normalIndex = k;
+ dst_vert->normalindex = k;
for ( k = 0; k < 3; k++ ) {
val = dst_vert->pos[k];
@@ -393,21 +197,42 @@ static qboolean Model_LoadMd2( model_t *model, const byte *rawdata, int length )
VectorAdd( mins, dst_frame->translate, dst_frame->bounds[0] );
VectorAdd( maxs, dst_frame->translate, dst_frame->bounds[1] );
- src_frame = ( daliasframe_t * )( ( byte * )src_frame + header.framesize );
+ src_frame = ( dmd2frame_t * )( ( byte * )src_frame + header.framesize );
dst_frame++;
}
- sys.HunkEnd( &model->pool );
+ Hunk_End( &model->pool );
return qtrue;
fail:
- sys.HunkFree( &model->pool );
+ Hunk_Free( &model->pool );
return qfalse;
+}
-#undef ERR
+#if USE_MD3
+static byte ll2byte[256][256];
+static qboolean ll2byte_inited;
+
+static void ll2byte_init( void ) {
+ float s[2], c[2];
+ vec3_t normal;
+ int i, j;
+
+ for( i = 0; i < 256; i++ ) {
+ for( j = 0; j < 256; j++ ) {
+ s[0] = sin( i / 255.0f );
+ c[0] = cos( i / 255.0f );
+
+ s[1] = sin( j / 255.0f );
+ c[1] = cos( j / 255.0f );
+
+ VectorSet( normal, s[0] * c[1], s[0] * s[1], c[0] );
+ ll2byte[i][j] = DirToByte( normal );
+ }
+ }
}
-static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length ) {
+qboolean MOD_LoadMD3( model_t *model, const void *rawdata, size_t length ) {
dmd3header_t header;
uint32_t offset;
dmd3frame_t *src_frame;
@@ -416,12 +241,12 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
dmd3coord_t *src_tc;
dmd3skin_t *src_skin;
uint32_t *src_idx;
- aliasFrame_t *dst_frame;
- aliasMesh_t *dst_mesh;
- aliasVert_t *dst_vert;
- tcoord_t *dst_tc;
+ maliasframe_t *dst_frame;
+ maliasmesh_t *dst_mesh;
+ maliasvert_t *dst_vert;
+ maliastc_t *dst_tc;
uint32_t *dst_idx;
- uint32_t numVerts, numTris, numSkins;
+ uint32_t numverts, numtris, numskins;
uint32_t totalVerts;
char skinname[MAX_QPATH];
image_t *skin;
@@ -429,7 +254,7 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
int i, j;
if( length < sizeof( header ) ) {
- Com_WPrintf( "%s has length < header length\n", model->name );
+ Com_WPrintf( "%s is too small to hold MD3 header\n", model->name );
return qfalse;
}
@@ -443,40 +268,30 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
Com_WPrintf( "%s is not an MD3 file\n", model->name );
return qfalse;
}
-
if( header.version != MD3_VERSION ) {
- Com_WPrintf( "%s has bad version: %d != %d\n",
+ Com_WPrintf( "%s has bad version: %d instead of %d\n",
model->name, header.version, MD3_VERSION );
return qfalse;
}
-
- if( header.num_frames < 1 ) {
- Com_WPrintf( "%s has bad number of frames: %d\n",
- model->name, header.num_frames );
- return qfalse;
- }
- if( header.num_frames > MD3_MAX_FRAMES ) {
- Com_WPrintf( "%s has too many frames: %d > %d\n",
- model->name, header.num_frames, MD3_MAX_FRAMES );
+ if( header.num_frames < 1 || header.num_frames > MD3_MAX_FRAMES ) {
+ Com_WPrintf( "%s has bad number of frames\n", model->name );
return qfalse;
}
-
- if( header.num_meshes < 1 || header.num_meshes > MD3_MAX_SURFACES ) {
+ if( header.num_meshes < 1 || header.num_meshes > MD3_MAX_MESHES ) {
Com_WPrintf( "%s has bad number of meshes\n", model->name );
return qfalse;
}
- model->type = MODEL_ALIAS;
- sys.HunkBegin( &model->pool, 0x400000 );
- model->numFrames = header.num_frames;
- model->numMeshes = header.num_meshes;
- model->meshes = Model_Malloc( sizeof( aliasMesh_t ) * header.num_meshes );
- model->frames = Model_Malloc( sizeof( aliasFrame_t ) * header.num_frames );
-
- rawend = rawdata + length;
+ Hunk_Begin( &model->pool, 0x400000 );
+ model->numframes = header.num_frames;
+ model->nummeshes = header.num_meshes;
+ model->meshes = Model_Malloc( sizeof( maliasmesh_t ) * header.num_meshes );
+ model->frames = Model_Malloc( sizeof( maliasframe_t ) * header.num_frames );
+
+ rawend = ( byte * )rawdata + length;
/* load all frames */
- src_frame = ( dmd3frame_t * )( rawdata + header.ofs_frames );
+ src_frame = ( dmd3frame_t * )( ( byte * )rawdata + header.ofs_frames );
if( ( byte * )( src_frame + header.num_frames ) > rawend ) {
Com_WPrintf( "%s has bad frames offset\n", model->name );
goto fail;
@@ -494,7 +309,7 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
}
/* load all meshes */
- src_mesh = ( dmd3mesh_t * )( rawdata + header.ofs_meshes );
+ src_mesh = ( dmd3mesh_t * )( ( byte * )rawdata + header.ofs_meshes );
dst_mesh = model->meshes;
for( i = 0; i < header.num_meshes; i++ ) {
if( ( byte * )( src_mesh + 1 ) > rawend ) {
@@ -502,49 +317,49 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
goto fail;
}
- numVerts = LittleLong( src_mesh->num_verts );
- numTris = LittleLong( src_mesh->num_tris );
+ numverts = LittleLong( src_mesh->num_verts );
+ numtris = LittleLong( src_mesh->num_tris );
- if( numVerts < 3 || numVerts > TESS_MAX_VERTICES ) {
+ if( numverts < 3 || numverts > TESS_MAX_VERTICES ) {
Com_WPrintf( "%s has bad number of vertices for mesh %d\n", model->name, i );
goto fail;
}
- if( numTris < 1 || numTris > TESS_MAX_INDICES / 3 ) {
+ if( numtris < 1 || numtris > TESS_MAX_INDICES / 3 ) {
Com_WPrintf( "%s has bad number of faces for mesh %d\n", model->name, i );
goto fail;
}
- dst_mesh->numTris = numTris;
- dst_mesh->numIndices = numTris * 3;
- dst_mesh->numVerts = numVerts;
- dst_mesh->verts = Model_Malloc( sizeof( aliasVert_t ) * numVerts * header.num_frames );
- dst_mesh->tcoords = Model_Malloc( sizeof( tcoord_t ) * numVerts );
- dst_mesh->indices = Model_Malloc( sizeof( uint32_t ) * numTris * 3 );
+ dst_mesh->numtris = numtris;
+ dst_mesh->numindices = numtris * 3;
+ dst_mesh->numverts = numverts;
+ dst_mesh->verts = Model_Malloc( sizeof( maliasvert_t ) * numverts * header.num_frames );
+ dst_mesh->tcoords = Model_Malloc( sizeof( maliastc_t ) * numverts );
+ dst_mesh->indices = Model_Malloc( sizeof( uint32_t ) * numtris * 3 );
/* load all skins */
- numSkins = LittleLong( src_mesh->num_skins );
- if( numSkins > MAX_MD2SKINS ) {
+ numskins = LittleLong( src_mesh->num_skins );
+ if( numskins > MAX_ALIAS_SKINS ) {
Com_WPrintf( "%s has bad number of skins for mesh %d\n", model->name, i );
goto fail;
}
offset = LittleLong( src_mesh->ofs_skins );
src_skin = ( dmd3skin_t * )( ( byte * )src_mesh + offset );
- if( ( byte * )( src_skin + numSkins ) > rawend ) {
+ if( ( byte * )( src_skin + numskins ) > rawend ) {
Com_WPrintf( "%s has bad skins offset for mesh %d\n", model->name, i );
goto fail;
}
- for( j = 0; j < numSkins; j++ ) {
+ for( j = 0; j < numskins; j++ ) {
Q_strncpyz( skinname, src_skin->name, sizeof( skinname ) );
- skin = R_FindImage( skinname, it_skin );
+ skin = IMG_Find( skinname, it_skin );
if( !skin ) {
skin = r_notexture;
}
dst_mesh->skins[j] = skin;
}
- dst_mesh->numSkins = numSkins;
+ dst_mesh->numskins = numskins;
/* load all vertices */
- totalVerts = numVerts * header.num_frames;
+ totalVerts = numverts * header.num_frames;
offset = LittleLong( src_mesh->ofs_verts );
src_vert = ( dmd3vertex_t * )( ( byte * )src_mesh + offset );
if( ( byte * )( src_vert + totalVerts ) > rawend ) {
@@ -557,7 +372,11 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
dst_vert->pos[1] = ( signed short )LittleShort( src_vert->point[1] );
dst_vert->pos[2] = ( signed short )LittleShort( src_vert->point[2] );
- dst_vert->normalIndex = ll2byte[src_vert->norm[0]]
+ if( !ll2byte_inited ) {
+ ll2byte_init();
+ ll2byte_inited = qtrue;
+ }
+ dst_vert->normalindex = ll2byte[src_vert->norm[0]]
[src_vert->norm[1]];
src_vert++; dst_vert++;
@@ -566,12 +385,12 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
/* load all texture coords */
offset = LittleLong( src_mesh->ofs_tcs );
src_tc = ( dmd3coord_t * )( ( byte * )src_mesh + offset );
- if( ( byte * )( src_tc + numVerts ) > rawend ) {
+ if( ( byte * )( src_tc + numverts ) > rawend ) {
Com_WPrintf( "%s has bad tcoords offset for mesh %d\n", model->name, i );
goto fail;
}
dst_tc = dst_mesh->tcoords;
- for( j = 0; j < numVerts; j++ ) {
+ for( j = 0; j < numverts; j++ ) {
dst_tc->st[0] = LittleFloat( src_tc->st[0] );
dst_tc->st[1] = LittleFloat( src_tc->st[1] );
src_tc++; dst_tc++;
@@ -580,16 +399,16 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
/* load all triangle indices */
offset = LittleLong( src_mesh->ofs_indexes );
src_idx = ( uint32_t * )( ( byte * )src_mesh + offset );
- if( ( byte * )( src_idx + numTris * 3 ) > rawend ) {
+ if( ( byte * )( src_idx + numtris * 3 ) > rawend ) {
Com_WPrintf( "%s has bad indices offset for mesh %d\n", model->name, i );
goto fail;
}
dst_idx = dst_mesh->indices;
- for( j = 0; j < numTris; j++ ) {
+ for( j = 0; j < numtris; j++ ) {
dst_idx[0] = LittleLong( src_idx[0] );
dst_idx[1] = LittleLong( src_idx[1] );
dst_idx[2] = LittleLong( src_idx[2] );
- if( dst_idx[0] >= numVerts || dst_idx[1] >= numVerts || dst_idx[2] >= numVerts ) {
+ if( dst_idx[0] >= numverts || dst_idx[1] >= numverts || dst_idx[2] >= numverts ) {
Com_WPrintf( "%s has bad indices for triangle %d in mesh %d\n", model->name, j, i );
goto fail;
}
@@ -601,398 +420,33 @@ static qboolean Model_LoadMd3( model_t *model, const byte *rawdata, int length )
dst_mesh++;
}
- sys.HunkEnd( &model->pool );
+ Hunk_End( &model->pool );
return qtrue;
fail:
- sys.HunkFree( &model->pool );
+ Hunk_Free( &model->pool );
return qfalse;
}
+#endif
-#define Model_TempAlloc( ptr, size ) \
- do { ptr = ( void * )data; data += size; offset += size; } while( 0 )
-
-static qboolean Model_WriteMd3( model_t *model, fileHandle_t f ) {
- dmd3header_t *header;
- uint32_t offset, length;
- byte *data;
- dmd3frame_t *dst_frame;
- dmd3mesh_t *dst_mesh;
- dmd3vertex_t *dst_vert;
- dmd3coord_t *dst_tc;
- dmd3skin_t *dst_skin;
- uint32_t *dst_idx;
- aliasFrame_t *src_frame;
- aliasMesh_t *src_mesh;
- aliasVert_t *src_vert;
- tcoord_t *src_tc;
- uint32_t *src_idx;
- uint32_t totalVerts;
- int i, j;
- qboolean ret;
- short pos[3];
-
- // precalculate total length
- length = sizeof( dmd3header_t ) +
- model->numFrames * sizeof( dmd3frame_t );
- src_mesh = model->meshes;
- for( i = 0; i < model->numMeshes; i++ ) {
- length += sizeof( dmd3mesh_t ) +
- src_mesh->numSkins * sizeof( dmd3skin_t ) +
- src_mesh->numVerts * model->numFrames * sizeof( dmd3vertex_t ) +
- src_mesh->numVerts * sizeof( dmd3coord_t ) +
- src_mesh->numIndices * sizeof( uint32_t );
- src_mesh++;
- }
-
- data = fs.AllocTempMem( length );
- offset = 0;
-
- // write header
- Model_TempAlloc( header, sizeof( dmd3header_t ) );
- header->ident = LittleLong( MD3_IDENT );
- header->version = LittleLong( MD3_VERSION );
- memset( header->filename, 0, sizeof( header->filename ) );
- header->flags = 0;
- header->num_frames = LittleLong( model->numFrames );
- header->num_tags = 0;
- header->num_meshes = LittleLong( model->numMeshes );
- header->num_skins = 0;
-
- // write all frames
- header->ofs_frames = LittleLong( offset );
- src_frame = model->frames;
- Model_TempAlloc( dst_frame, model->numFrames * sizeof( dmd3frame_t ) );
- for( i = 0; i < model->numFrames; i++ ) {
- LittleVector( src_frame->translate, dst_frame->translate );
-
- LittleVector( src_frame->bounds[0], dst_frame->mins );
- LittleVector( src_frame->bounds[1], dst_frame->maxs );
- dst_frame->radius = LittleFloat( src_frame->radius );
-
- memset( dst_frame->creator, 0, sizeof( dst_frame->creator ) );
-
- src_frame++; dst_frame++;
- }
-
- // write all meshes
- header->ofs_meshes = LittleLong( offset );
- src_mesh = model->meshes;
- for( i = 0; i < model->numMeshes; i++ ) {
- offset = 0;
- Model_TempAlloc( dst_mesh, sizeof( dmd3mesh_t ) );
- dst_mesh->ident = LittleLong( MD3_IDENT );
- memset( dst_mesh->name, 0, sizeof( dst_mesh->name ) );
- dst_mesh->flags = 0;
- dst_mesh->num_frames = LittleLong( model->numFrames );
- dst_mesh->num_skins = LittleLong( src_mesh->numSkins );
- dst_mesh->num_tris = LittleLong( src_mesh->numTris );
- dst_mesh->num_verts = LittleLong( src_mesh->numVerts );
-
- // write all skins
- dst_mesh->ofs_skins = LittleLong( offset );
- Model_TempAlloc( dst_skin, sizeof( dmd3skin_t ) * src_mesh->numSkins );
- for( j = 0; j < src_mesh->numSkins; j++ ) {
- memcpy( dst_skin->name, src_mesh->skins[j]->name, MAX_QPATH );
- dst_skin->unused = 0;
- dst_skin++;
- }
-
- // write all vertices
- dst_mesh->ofs_verts = LittleLong( offset );
- totalVerts = src_mesh->numVerts * model->numFrames;
- src_vert = src_mesh->verts;
- src_frame = model->frames;
- Model_TempAlloc( dst_vert, sizeof( dmd3vertex_t ) * totalVerts );
- for( j = 0; j < totalVerts; j++ ) {
- pos[0] = src_vert->pos[0] * src_frame->scale[0] / MD3_XYZ_SCALE;
- pos[1] = src_vert->pos[1] * src_frame->scale[1] / MD3_XYZ_SCALE;
- pos[2] = src_vert->pos[2] * src_frame->scale[2] / MD3_XYZ_SCALE;
-
- dst_vert->point[0] = ( signed short )LittleShort( pos[0] );
- dst_vert->point[1] = ( signed short )LittleShort( pos[1] );
- dst_vert->point[2] = ( signed short )LittleShort( pos[2] );
-
- // TODO: calc normal
-
- src_vert++; dst_vert++;
- }
-
- // write all texture coords
- dst_mesh->ofs_tcs = LittleLong( offset );
- src_tc = src_mesh->tcoords;
- Model_TempAlloc( dst_tc, sizeof( dmd3coord_t ) * src_mesh->numVerts );
- for( j = 0; j < src_mesh->numVerts; j++ ) {
- dst_tc->st[0] = LittleFloat( src_tc->st[0] );
- dst_tc->st[1] = LittleFloat( src_tc->st[1] );
- src_tc++; dst_tc++;
- }
-
- // write all triangle indices
- dst_mesh->ofs_indexes = LittleLong( offset );
- src_idx = src_mesh->indices;
- Model_TempAlloc( dst_idx, sizeof( uint32_t ) * src_mesh->numIndices );
- for( j = 0; j < src_mesh->numTris; j++ ) {
- dst_idx[0] = LittleLong( src_idx[0] );
- dst_idx[1] = LittleLong( src_idx[1] );
- dst_idx[2] = LittleLong( src_idx[2] );
- src_idx += 3; dst_idx += 3;
- }
-
- dst_mesh->meshsize = LittleLong( offset );
- }
-
- header->ofs_tags = 0;
- header->ofs_end = length;
-
- // write model to disk
- ret = qtrue;
- if( fs.Write( header, length, f ) != length ) {
- ret = qfalse;
- }
-
- fs.FreeFile( header );
-
- return ret;
-}
-
-static qboolean Model_LoadSp2( model_t *model, const byte *rawdata, int length ) {
- dsprite_t *header;
- dsprframe_t *src_frame;
- spriteFrame_t *dst_frame;
- unsigned ident, version, numframes, width, height;
- char buffer[MAX_SKINNAME];
- image_t *image;
- int i;
-
- if( length < sizeof( *header ) ) {
- Com_EPrintf( "%s has length < header length\n", model->name );
- return qfalse;
- }
-
- /* byte swap the header */
- header = ( dsprite_t * )rawdata;
- for( i = 0; i < sizeof( header )/4; i++ ) {
- (( uint32_t * )&header)[i] = LittleLong( (( uint32_t * )&header)[i] );
- }
-
- ident = LittleLong( header->ident );
- version = LittleLong( header->version );
- numframes = LittleLong( header->numframes );
-
- if( ident != IDSPRITEHEADER ) {
- Com_EPrintf( "%s is not an sp2 file\n", model->name );
- return qfalse;
- }
- if( version != SPRITE_VERSION ) {
- Com_EPrintf( "%s has bad version: %d != %d\n",
- model->name, version, ALIAS_VERSION );
- return qfalse;
- }
- if( numframes < 1 || numframes > MAX_MD2SKINS ) {
- Com_EPrintf( "%s has bad number of frames: %d\n",
- model->name, numframes );
- return qfalse;
- }
-
- model->type = MODEL_SPRITE;
- sys.HunkBegin( &model->pool, 0x10000 );
-
- model->sframes = Model_Malloc( sizeof( spriteFrame_t ) * numframes );
- model->numFrames = numframes;
-
- src_frame = header->frames;
- dst_frame = model->sframes;
- for( i = 0; i < numframes; i++ ) {
- width = LittleLong( src_frame->width );
- height = LittleLong( src_frame->height );
- if( width < 1 || height < 1 || width > MAX_TEXTURE_SIZE || height > MAX_TEXTURE_SIZE ) {
- Com_WPrintf( "%s has bad image dimensions for frame #%d: %ux%u\n",
- model->name, width, height, i );
- width = 1;
- height = 1;
- }
- dst_frame->width = width;
- dst_frame->height = height;
- dst_frame->x = LittleLong( src_frame->origin_x );
- dst_frame->y = LittleLong( src_frame->origin_y );
-
- Q_strncpyz( buffer, src_frame->name, sizeof( buffer ) );
- image = R_FindImage( buffer, it_sprite );
- if( !image ) {
- Com_DPrintf( "Couldn't find image '%s' for frame #%d for sprite '%s'\n",
- buffer, i, model->name );
- image = r_notexture;
- }
- dst_frame->image = image;
-
- dst_frame++; src_frame++;
- }
-
- sys.HunkEnd( &model->pool );
-
- return qtrue;
-}
-
-void GL_GetModelSize( qhandle_t hModel, vec3_t mins, vec3_t maxs ) {
- VectorClear( mins );
- VectorClear( maxs );
-}
+void MOD_Reference( model_t *model ) {
+ int i, j;
-qhandle_t GL_RegisterModel( const char *name ) {
- int index, length = 0;
- size_t namelen;
- model_t *model;
- byte *rawdata;
- uint32_t ident;
- qboolean success;
- char buffer[MAX_QPATH];
-
- if( name[0] == '*' ) {
- /* inline bsp model */
- index = atoi( name + 1 );
- if( index < 1 || index >= r_world.numSubmodels ) {
- Com_Error( ERR_DROP, "%s: bad inline model index: %d", __func__, index );
+ if( model->frames ) {
+ for( i = 0; i < model->nummeshes; i++ ) {
+ maliasmesh_t *mesh = &model->meshes[i];
+ for( j = 0; j < mesh->numskins; j++ ) {
+ mesh->skins[j]->registration_sequence = registration_sequence;
+ }
}
- return ~index;
- }
-
- if( !strcmp( r_world.name, name ) ) {
- /* TODO: change client code and remove this hack */
- return 0;
- }
-
- namelen = strlen( name );
- if( namelen > MAX_QPATH - 1 ) {
- Com_Error( ERR_DROP, "%s: oversize name", __func__ );
- }
-
- model = Model_Find( name );
- if( model ) {
- goto finish;
- }
-
- rawdata = NULL;
- buffer[0] = 0;
- if( gl_override_models->integer ) {
- if( namelen > 4 && !strcmp( name + namelen - 4, ".md2" ) ) {
- strcpy( buffer, name );
- buffer[namelen - 1] = '3';
- length = fs.LoadFile( buffer, ( void ** )&rawdata );
- }
- }
- if( !rawdata ) {
- length = fs.LoadFile( name, ( void ** )&rawdata );
- if( !rawdata ) {
- Com_DPrintf( "Couldn't load %s\n", name );
- return 0;
+ } else if( model->spriteframes ) {
+ for( i = 0; i < model->numframes; i++ ) {
+ model->spriteframes[i].image->registration_sequence = registration_sequence;
}
+ } else {
+ Com_Error( ERR_FATAL, "%s: bad model type", __func__ );
}
- if( length < 4 ) {
- Com_WPrintf( "LoadXXX: %s: file too short\n", name );
- return 0;
- }
-
- model = Model_Alloc( name );
-
- ident = LittleLong( *( uint32_t * )rawdata );
- switch( ident ) {
- case IDALIASHEADER:
- success = Model_LoadMd2( model, rawdata, length );
- if( success && gl_override_models->integer > 1 ) {
- fileHandle_t f;
-
- fs.FOpenFile( buffer, &f, FS_MODE_WRITE );
- if( f ) {
- Model_WriteMd3( model, f );
- fs.FCloseFile( f );
- }
- }
- break;
- case MD3_IDENT:
- success = Model_LoadMd3( model, rawdata, length );
- break;
- case IDSPRITEHEADER:
- success = Model_LoadSp2( model, rawdata, length );
- break;
- case IDBSPHEADER:
- Com_WPrintf( "LoadXXX: %s: loaded BSP model after the world\n", name );
- success = qfalse;
- break;
- default:
- Com_WPrintf( "LoadXXX: %s: unknown ident: %x\n", name, ident );
- success = qfalse;
- break;
- }
-
- fs.FreeFile( rawdata );
-
- if( !success ) {
- model->name[0] = 0;
- return 0;
- }
-
-finish:
- index = ( model - r_models ) + 1;
- return index;
-}
-
-modelType_t *GL_ModelForHandle( qhandle_t hModel ) {
- model_t *model;
- bspSubmodel_t *submodel;
-
- if( !hModel ) {
- return NULL;
- }
-
- if( hModel & 0x80000000 ) {
- hModel = ~hModel;
-
- if( hModel < 1 || hModel >= r_world.numSubmodels ) {
- Com_Error( ERR_DROP, "GL_ModelForHandle: submodel %d out of range", hModel );
- }
-
- submodel = &r_world.submodels[hModel];
- return &submodel->type;
- }
-
- if( hModel > r_numModels ) {
- Com_Error( ERR_DROP, "GL_ModelForHandle: %d out of range", hModel );
- }
- model = &r_models[ hModel - 1 ];
- if( !model->name[0] ) {
- return NULL;
- }
- return &model->type;
-
-}
-
-void GL_InitModels( void ) {
- float s[2], c[2];
- vec3_t normal;
- int i, j;
-
- for( i = 0; i < 256; i++ ) {
- for( j = 0; j < 256; j++ ) {
- s[0] = sin( i / 255.0f );
- c[0] = cos( i / 255.0f );
-
- s[1] = sin( j / 255.0f );
- c[1] = cos( j / 255.0f );
-
- VectorSet( normal, s[0] * c[1], s[0] * s[1], c[0] );
- ll2byte[i][j] = DirToByte( normal );
- }
- }
-
- gl_override_models = cvar.Get( "r_override_models", "0",
- CVAR_ARCHIVE|CVAR_FILES );
-
- cmd.AddCommand( "modellist", Model_List_f );
+ model->registration_sequence = registration_sequence;
}
-void GL_ShutdownModels( void ) {
- Model_FreeAll();
- cmd.RemoveCommand( "modellist" );
-}