From 4b03014f14b7275c799bcf7727c7339727180459 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 27 Nov 2002 00:22:15 +0000 Subject: [PATCH] changed format of aliasvertex_t to use floats (hopefully this is a speedup, it sure bloats memory use - 36 bytes each, compared to 4 bytes in mdl/md2) corrected scale for md3 vertices mentioned in header (md3 is still not supported yet) added some unfinished mesh structures to begin support for md3 git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2655 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_models.c | 62 +++++++++++------------- model_alias.c | 129 ++++++++++++++++++++++++++++++++++++++++--------- model_alias.h | 67 +++++++++++++++++++++++-- model_shared.h | 2 + 4 files changed, 201 insertions(+), 59 deletions(-) diff --git a/gl_models.c b/gl_models.c index 8a8e3fab..b382588f 100644 --- a/gl_models.c +++ b/gl_models.c @@ -52,7 +52,7 @@ void GL_Models_Init(void) void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float *normals, float *svectors, float *tvectors) { int i, vertcount; - float vlerp1, nlerp1, vlerp2, nlerp2, vlerp3, nlerp3, vlerp4, nlerp4; + float lerp1, lerp2, lerp3, lerp4; const aliasvertex_t *verts1, *verts2, *verts3, *verts4; if (vertices == NULL) @@ -64,31 +64,27 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * vertcount = ent->model->numverts; verts1 = ent->model->mdlmd2data_pose + ent->frameblend[0].frame * vertcount; - vlerp1 = ent->frameblend[0].lerp * (1.0f / 16.0f); - nlerp1 = ent->frameblend[0].lerp * (1.0f / 127.0f); + lerp1 = ent->frameblend[0].lerp; if (ent->frameblend[1].lerp) { verts2 = ent->model->mdlmd2data_pose + ent->frameblend[1].frame * vertcount; - vlerp2 = ent->frameblend[1].lerp * (1.0f / 16.0f); - nlerp2 = ent->frameblend[1].lerp * (1.0f / 127.0f); + lerp2 = ent->frameblend[1].lerp; if (ent->frameblend[2].lerp) { verts3 = ent->model->mdlmd2data_pose + ent->frameblend[2].frame * vertcount; - vlerp3 = ent->frameblend[2].lerp * (1.0f / 16.0f); - nlerp3 = ent->frameblend[2].lerp * (1.0f / 127.0f); + lerp3 = ent->frameblend[2].lerp; if (ent->frameblend[3].lerp) { verts4 = ent->model->mdlmd2data_pose + ent->frameblend[3].frame * vertcount; - vlerp4 = ent->frameblend[3].lerp * (1.0f / 16.0f); - nlerp4 = ent->frameblend[3].lerp * (1.0f / 127.0f); + lerp4 = ent->frameblend[3].lerp; // generate vertices if (svectors != NULL) { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++, verts4++) { - VectorMAMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vlerp4, verts4->origin, vertices); - VectorMAMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, nlerp4, verts4->normal, normals); - VectorMAMAMAM(nlerp1, verts1->svector, nlerp2, verts2->svector, nlerp3, verts3->svector, nlerp4, verts4->svector, svectors); + VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices); + VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normals); + VectorMAMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, lerp4, verts4->svector, svectors); CrossProduct(svectors, normals, tvectors); } } @@ -96,13 +92,13 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++, verts4++) { - VectorMAMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vlerp4, verts4->origin, vertices); - VectorMAMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, nlerp4, verts4->normal, normals); + VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices); + VectorMAMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, lerp4, verts4->normal, normals); } } else for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++, verts4++) - VectorMAMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vlerp4, verts4->origin, vertices); + VectorMAMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, lerp4, verts4->origin, vertices); } else { @@ -111,9 +107,9 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++, verts3++) { - VectorMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vertices); - VectorMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, normals); - VectorMAMAM(nlerp1, verts1->svector, nlerp2, verts2->svector, nlerp3, verts3->svector, svectors); + VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices); + VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normals); + VectorMAMAM(lerp1, verts1->svector, lerp2, verts2->svector, lerp3, verts3->svector, svectors); CrossProduct(svectors, normals, tvectors); } } @@ -121,13 +117,13 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++, verts3++) { - VectorMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vertices); - VectorMAMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, nlerp3, verts3->normal, normals); + VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices); + VectorMAMAM(lerp1, verts1->normal, lerp2, verts2->normal, lerp3, verts3->normal, normals); } } else for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++, verts3++) - VectorMAMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vlerp3, verts3->origin, vertices); + VectorMAMAM(lerp1, verts1->origin, lerp2, verts2->origin, lerp3, verts3->origin, vertices); } } else @@ -137,9 +133,9 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++, verts2++) { - VectorMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vertices); - VectorMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, normals); - VectorMAM(nlerp1, verts1->svector, nlerp2, verts2->svector, svectors); + VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices); + VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normals); + VectorMAM(lerp1, verts1->svector, lerp2, verts2->svector, svectors); CrossProduct(svectors, normals, tvectors); } } @@ -147,13 +143,13 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++, verts2++) { - VectorMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vertices); - VectorMAM(nlerp1, verts1->normal, nlerp2, verts2->normal, normals); + VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices); + VectorMAM(lerp1, verts1->normal, lerp2, verts2->normal, normals); } } else for (i = 0;i < vertcount;i++, vertices += 4, verts1++, verts2++) - VectorMAM(vlerp1, verts1->origin, vlerp2, verts2->origin, vertices); + VectorMAM(lerp1, verts1->origin, lerp2, verts2->origin, vertices); } } else @@ -163,9 +159,9 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, svectors += 4, tvectors += 4, verts1++) { - VectorM(vlerp1, verts1->origin, vertices); - VectorM(nlerp1, verts1->normal, normals); - VectorM(nlerp1, verts1->svector, svectors); + VectorM(lerp1, verts1->origin, vertices); + VectorM(lerp1, verts1->normal, normals); + VectorM(lerp1, verts1->svector, svectors); CrossProduct(svectors, normals, tvectors); } } @@ -173,13 +169,13 @@ void R_Model_Alias_GetVerts(const entity_render_t *ent, float *vertices, float * { for (i = 0;i < vertcount;i++, vertices += 4, normals += 4, verts1++) { - VectorM(vlerp1, verts1->origin, vertices); - VectorM(nlerp1, verts1->normal, normals); + VectorM(lerp1, verts1->origin, vertices); + VectorM(lerp1, verts1->normal, normals); } } else for (i = 0;i < vertcount;i++, vertices += 4, verts1++) - VectorM(vlerp1, verts1->origin, vertices); + VectorM(lerp1, verts1->origin, vertices); } } diff --git a/model_alias.c b/model_alias.c index a9e83348..a2d3d5e0 100644 --- a/model_alias.c +++ b/model_alias.c @@ -64,11 +64,6 @@ static void Mod_ConvertAliasVerts (int inverts, vec3_t scale, vec3_t translate, if (modelradius < dist) modelradius = dist; - VectorScale(temp, 16.0f, temp); - temp[0] = bound(-32768, temp[0], 32767); - temp[1] = bound(-32768, temp[1], 32767); - temp[2] = bound(-32768, temp[2], 32767); - j = vertremap[i]; // not onseam if (j >= 0) VectorCopy(temp, out[j].origin); @@ -82,16 +77,16 @@ static void Mod_BuildAliasVertexTextureVectors(int numtriangles, const int *elem { int i; for (i = 0;i < numverts;i++) - VectorScale(vertices[i].origin, (1.0f / 16.0f), &vertexbuffer[i * 4]); + VectorCopy(vertices[i].origin, &vertexbuffer[i * 4]); Mod_BuildTextureVectorsAndNormals(numverts, numtriangles, vertexbuffer, texcoords, elements, svectorsbuffer, tvectorsbuffer, normalsbuffer); for (i = 0;i < numverts;i++) { - vertices[i].normal[0] = normalsbuffer[i * 4 + 0] * 127.0f; - vertices[i].normal[1] = normalsbuffer[i * 4 + 1] * 127.0f; - vertices[i].normal[2] = normalsbuffer[i * 4 + 2] * 127.0f; - vertices[i].svector[0] = svectorsbuffer[i * 4 + 0] * 127.0f; - vertices[i].svector[1] = svectorsbuffer[i * 4 + 1] * 127.0f; - vertices[i].svector[2] = svectorsbuffer[i * 4 + 2] * 127.0f; + vertices[i].normal[0] = normalsbuffer[i * 4 + 0]; + vertices[i].normal[1] = normalsbuffer[i * 4 + 1]; + vertices[i].normal[2] = normalsbuffer[i * 4 + 2]; + vertices[i].svector[0] = svectorsbuffer[i * 4 + 0]; + vertices[i].svector[1] = svectorsbuffer[i * 4 + 1]; + vertices[i].svector[2] = svectorsbuffer[i * 4 + 2]; } } @@ -212,6 +207,104 @@ static int Mod_LoadInternalSkin (char *basename, qbyte *skindata, int width, int return true; } +void Mod_BuildMDLMD2MeshInfo(void) +{ + int i; + aliasmesh_t *mesh; + aliasskin_t *skin; + aliaslayer_t *layer; + skinframe_t *skinframe; + + loadmodel->mdlmd2data_triangleneighbors = Mem_Alloc(loadmodel->mempool, loadmodel->numtris * sizeof(int[3])); + Mod_ValidateElements(loadmodel->mdlmd2data_indices, loadmodel->numtris, loadmodel->numverts, __FILE__, __LINE__); + Mod_BuildTriangleNeighbors(loadmodel->mdlmd2data_triangleneighbors, loadmodel->mdlmd2data_indices, loadmodel->numtris); + + loadmodel->mdlmd2num_meshes = 1; + mesh = loadmodel->mdlmd2data_meshes = Mem_Alloc(loadmodel->mempool, loadmodel->mdlmd2num_meshes * sizeof(aliasmesh_t)); + mesh->num_skins = 0; + mesh->num_frames = 0; + for (i = 0;i < loadmodel->numframes;i++) + mesh->num_frames += loadmodel->animscenes[i].framecount; + for (i = 0;i < loadmodel->numskins;i++) + mesh->num_skins += loadmodel->skinscenes[i].framecount; + mesh->num_triangles = loadmodel->numtris; + mesh->num_vertices = loadmodel->numverts; + mesh->data_skins = Mem_Alloc(loadmodel->mempool, mesh->num_skins * sizeof(aliasskin_t)); + mesh->data_elements = loadmodel->mdlmd2data_indices; + mesh->data_neighbors = loadmodel->mdlmd2data_triangleneighbors; + mesh->data_texcoords = loadmodel->mdlmd2data_texcoords; + mesh->data_vertices = loadmodel->mdlmd2data_pose; + for (i = 0, skin = mesh->data_skins, skinframe = loadmodel->skinframes;i < mesh->num_skins;i++, skin++, skinframe++) + { + skin->flags = 0; + // fog texture only exists if some pixels are transparent... + if (skinframe->fog != NULL) + skin->flags |= ALIASSKIN_TRANSPARENT; + // fog and gloss layers always exist + skin->num_layers = 2; + if (skinframe->glow != NULL) + skin->num_layers++; + if (skinframe->merged != NULL) + skin->num_layers++; + if (skinframe->base != NULL) + skin->num_layers++; + if (skinframe->pants != NULL) + skin->num_layers++; + if (skinframe->shirt != NULL) + skin->num_layers++; + layer = skin->data_layers = Mem_Alloc(loadmodel->mempool, skin->num_layers * sizeof(aliaslayer_t)); + if (skinframe->glow != NULL) + { + layer->flags = ALIASLAYER_REALTIME_NODRAW; + layer->texture = skinframe->glow; + layer++; + } + if (skinframe->merged != NULL) + { + layer->flags = ALIASLAYER_COLORMAP_NODRAW | ALIASLAYER_DIFFUSE; + if (skinframe->glow != NULL) + layer->flags |= ALIASLAYER_ADD; + layer->texture = skinframe->merged; + layer->nmap = skinframe->nmap; + layer++; + } + if (skinframe->base != NULL) + { + layer->flags = ALIASLAYER_COLORMAP_DRAW | ALIASLAYER_DIFFUSE; + if (skinframe->glow != NULL) + layer->flags |= ALIASLAYER_ADD; + layer->texture = skinframe->base; + layer->nmap = skinframe->nmap; + layer++; + } + if (skinframe->pants != NULL) + { + layer->flags = ALIASLAYER_COLORMAP_DRAW | ALIASLAYER_COLORMAP_DIFFUSE_SHIRT; + if (skinframe->glow != NULL || skinframe->base != NULL) + layer->flags |= ALIASLAYER_ADD; + layer->texture = skinframe->pants; + layer->nmap = skinframe->nmap; + layer++; + } + if (skinframe->shirt != NULL) + { + layer->flags = ALIASLAYER_COLORMAP_DRAW | ALIASLAYER_COLORMAP_DIFFUSE_SHIRT; + if (skinframe->glow != NULL || skinframe->base != NULL || skinframe->pants != NULL) + layer->flags |= ALIASLAYER_ADD; + layer->texture = skinframe->shirt; + layer->nmap = skinframe->nmap; + layer++; + } + layer->flags = ALIASLAYER_REALTIME_DRAW | ALIASLAYER_SPECULAR; + layer->texture = skinframe->gloss; + layer->nmap = skinframe->nmap; + layer++; + layer->flags = ALIASLAYER_REALTIME_NODRAW | ALIASLAYER_FOG; + layer->texture = skinframe->fog; + layer++; + } +} + #define BOUNDI(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%d exceeds %d - %d)\n", loadmodel->name, VALUE, MIN, MAX); #define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX); extern void R_Model_Alias_Draw(entity_render_t *ent); @@ -498,9 +591,7 @@ void Mod_LoadAliasModel (model_t *mod, void *buffer) loadmodel->radius = modelradius; loadmodel->radius2 = modelradius * modelradius; - loadmodel->mdlmd2data_triangleneighbors = Mem_Alloc(loadmodel->mempool, loadmodel->numtris * sizeof(int[3])); - Mod_ValidateElements(loadmodel->mdlmd2data_indices, loadmodel->numtris, loadmodel->numverts, __FILE__, __LINE__); - Mod_BuildTriangleNeighbors(loadmodel->mdlmd2data_triangleneighbors, loadmodel->mdlmd2data_indices, loadmodel->numtris); + Mod_BuildMDLMD2MeshInfo(); } static void Mod_MD2_ConvertVerts (vec3_t scale, vec3_t translate, trivertx_t *v, aliasvertex_t *out, int *vertremap) @@ -528,10 +619,6 @@ static void Mod_MD2_ConvertVerts (vec3_t scale, vec3_t translate, trivertx_t *v, dist += temp[2]*temp[2]; if (modelradius < dist) modelradius = dist; - VectorScale(temp, 16.0f, temp); - temp[0] = bound(-32768, temp[0], 32767); - temp[1] = bound(-32768, temp[1], 32767); - temp[2] = bound(-32768, temp[2], 32767); VectorCopy(temp, out[i].origin); } } @@ -762,9 +849,7 @@ void Mod_LoadQ2AliasModel (model_t *mod, void *buffer) loadmodel->radius = modelradius; loadmodel->radius2 = modelradius * modelradius; - loadmodel->mdlmd2data_triangleneighbors = Mem_Alloc(loadmodel->mempool, loadmodel->numtris * sizeof(int[3])); - Mod_ValidateElements(loadmodel->mdlmd2data_indices, loadmodel->numtris, loadmodel->numverts, __FILE__, __LINE__); - Mod_BuildTriangleNeighbors(loadmodel->mdlmd2data_triangleneighbors, loadmodel->mdlmd2data_indices, loadmodel->numtris); + Mod_BuildMDLMD2MeshInfo(); } extern void R_Model_Zymotic_DrawSky(entity_render_t *ent); diff --git a/model_alias.h b/model_alias.h index be50dcd2..40526831 100644 --- a/model_alias.h +++ b/model_alias.h @@ -144,7 +144,7 @@ extern void Mod_AliasInit(void); #define MD3NAME 64 #define MD3FRAMENAME 16 -// the origin is at 1/16th scale +// the origin is at 1/64th scale // the pitch and yaw are encoded as 8 bits each typedef struct md3vertex_s { @@ -229,11 +229,70 @@ md3modelheader_t; // LordHavoc: all quake series 'alias' models (mdl, md2, md3) are converted to this vertex format typedef struct aliasvertex_s { - short origin[3]; - signed char normal[3]; - signed char svector[3]; + // location + float origin[3]; + // surface normal + float normal[3]; + // S texture vector + float svector[3]; } aliasvertex_t; +// this layer is fog +#define ALIASLAYER_FOG 1 +// alpha blending +#define ALIASLAYER_ALPHA 2 +// additive blending +#define ALIASLAYER_ADD 4 +// apply diffuse lighting +#define ALIASLAYER_DIFFUSE 8 +// apply specular lighting +#define ALIASLAYER_SPECULAR 16 +// tint with pants color +#define ALIASLAYER_COLORMAP_DIFFUSE_PANTS 32 +// tint with shirt color +#define ALIASLAYER_COLORMAP_DIFFUSE_SHIRT 64 +// don't draw this layer if colormap is used +#define ALIASLAYER_COLORMAP_NODRAW 128 +// only draw this layer if colormap is used +#define ALIASLAYER_COLORMAP_DRAW 256 +// don't draw this layer for realtime lighting passes +#define ALIASLAYER_REALTIME_NODRAW 512 +// only draw this layer for realtime lighting passes +#define ALIASLAYER_REALTIME_DRAW 1024 + +typedef struct aliaslayer_s +{ + int flags; + rtexture_t *texture; + rtexture_t *nmap; +} +aliaslayer_t; + +// indicates this skin is transparent +#define ALIASSKIN_TRANSPARENT 1 + +typedef struct aliasskin_s +{ + int flags; + int num_layers; + aliaslayer_t *data_layers; +} +aliasskin_t; + +typedef struct aliasmesh_s +{ + int num_skins; + int num_triangles; + int num_frames; + int num_vertices; + aliasskin_t *data_skins; + int *data_elements; + int *data_neighbors; + float *data_texcoords; + aliasvertex_t *data_vertices; +} +aliasmesh_t; + #endif diff --git a/model_shared.h b/model_shared.h index 509cff36..21fe6b52 100644 --- a/model_shared.h +++ b/model_shared.h @@ -231,10 +231,12 @@ typedef struct model_s animscene_t *animscenes; // [numframes] // Q1 and Q2 models are the same after loading + int mdlmd2num_meshes; int *mdlmd2data_indices; float *mdlmd2data_texcoords; aliasvertex_t *mdlmd2data_pose; int *mdlmd2data_triangleneighbors; + aliasmesh_t *mdlmd2data_meshes; // for Zymotic models int zymnum_verts; -- 2.39.2