soft: port submodel load code from vk render

This commit is contained in:
Denis Pauk 2021-08-07 17:24:39 +03:00
parent a8b02d4725
commit 8bd39ad5dd
2 changed files with 59 additions and 45 deletions

View file

@ -161,6 +161,7 @@ typedef struct model_s
// volume occupied by the model graphics // volume occupied by the model graphics
// //
vec3_t mins, maxs; vec3_t mins, maxs;
float radius;
// //
// solid volume for clipping (sent from server) // solid volume for clipping (sent from server)
@ -174,7 +175,7 @@ typedef struct model_s
int firstmodelsurface, nummodelsurfaces; int firstmodelsurface, nummodelsurfaces;
int numsubmodels; int numsubmodels;
dmodel_t *submodels; struct model_s *submodels;
int numplanes; int numplanes;
cplane_t *planes; cplane_t *planes;
@ -212,6 +213,9 @@ typedef struct model_s
image_t *skins[MAX_MD2SKINS]; image_t *skins[MAX_MD2SKINS];
void *extradata; void *extradata;
int extradatasize; int extradatasize;
// submodules
vec3_t origin; // for sounds or lights
} model_t; } model_t;
//============================================================================ //============================================================================

View file

@ -37,9 +37,6 @@ static byte mod_novis[MAX_MAP_LEAFS/8];
static model_t mod_known[MAX_MOD_KNOWN]; static model_t mod_known[MAX_MOD_KNOWN];
static int mod_numknown; static int mod_numknown;
// the inline * models from the current map are kept seperate
static model_t mod_inline[MAX_MOD_KNOWN];
int registration_sequence; int registration_sequence;
//=============================================================================== //===============================================================================
@ -96,7 +93,7 @@ Loads in a model for the given name
================== ==================
*/ */
static model_t * static model_t *
Mod_ForName (char *name, qboolean crash) Mod_ForName (char *name, model_t *parent_model, qboolean crash)
{ {
model_t *mod; model_t *mod;
unsigned *buf; unsigned *buf;
@ -110,16 +107,16 @@ Mod_ForName (char *name, qboolean crash)
// //
// inline models are grabbed only from worldmodel // inline models are grabbed only from worldmodel
// //
if (name[0] == '*') if (name[0] == '*' && parent_model)
{ {
i = atoi(name+1); i = atoi(name+1);
if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels) if (i < 1 || i >= parent_model->numsubmodels)
{ {
ri.Sys_Error(ERR_DROP, "%s: bad inline model number", ri.Sys_Error(ERR_DROP, "%s: bad inline model number",
__func__); __func__);
} }
return &mod_inline[i]; return &parent_model->submodels[i];
} }
// //
@ -384,20 +381,38 @@ Mod_LoadVertexes (lump_t *l)
} }
} }
/*
=================
RadiusFromBounds
=================
*/
static float
RadiusFromBounds (vec3_t mins, vec3_t maxs)
{
int i;
vec3_t corner;
for (i=0 ; i<3 ; i++)
{
corner[i] = fabs(mins[i]) > fabs(maxs[i]) ? fabs(mins[i]) : fabs(maxs[i]);
}
return VectorLength (corner);
}
/* /*
================= =================
Mod_LoadSubmodels Mod_LoadSubmodels
================= =================
*/ */
static void static void
Mod_LoadSubmodels (lump_t *l) Mod_LoadSubmodels (model_t *loadmodel, byte *mod_base, lump_t *l)
{ {
dmodel_t *in; dmodel_t *in;
dmodel_t *out; model_t *out;
int i, j, count; int i, j, count;
in = (void *)(mod_base + l->fileofs); in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
{ {
ri.Sys_Error(ERR_DROP, "%s: funny lump size in %s", ri.Sys_Error(ERR_DROP, "%s: funny lump size in %s",
@ -412,15 +427,38 @@ Mod_LoadSubmodels (lump_t *l)
for ( i=0 ; i<count ; i++, in++, out++) for ( i=0 ; i<count ; i++, in++, out++)
{ {
if (i == 0)
{
// copy parent as template for first model
memcpy(out, loadmodel, sizeof(*out));
}
else
{
// copy first as template for model
memcpy(out, loadmodel->submodels, sizeof(*out));
}
Com_sprintf (out->name, sizeof(out->name), "*%d", i);
for (j=0 ; j<3 ; j++) for (j=0 ; j<3 ; j++)
{ // spread the mins / maxs by a pixel { // spread the mins / maxs by a pixel
out->mins[j] = LittleFloat (in->mins[j]) - 1; out->mins[j] = LittleFloat (in->mins[j]) - 1;
out->maxs[j] = LittleFloat (in->maxs[j]) + 1; out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
out->origin[j] = LittleFloat (in->origin[j]); out->origin[j] = LittleFloat (in->origin[j]);
} }
out->headnode = LittleLong (in->headnode);
out->firstface = LittleLong (in->firstface); out->radius = RadiusFromBounds (out->mins, out->maxs);
out->numfaces = LittleLong (in->numfaces); out->firstnode = LittleLong (in->headnode);
out->firstmodelsurface = LittleLong (in->firstface);
out->nummodelsurfaces = LittleLong (in->numfaces);
// visleafs
out->numleafs = 0;
// check limits
if (out->firstnode >= loadmodel->numnodes)
{
ri.Sys_Error(ERR_DROP, "%s: Inline model %i has bad firstnode",
__func__, i);
}
} }
} }
@ -969,7 +1007,6 @@ Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen)
{ {
int i; int i;
dheader_t *header; dheader_t *header;
dmodel_t *bm;
if (loadmodel != mod_known) if (loadmodel != mod_known)
ri.Sys_Error(ERR_DROP, "%s: Loaded a brush model after the world", __func__); ri.Sys_Error(ERR_DROP, "%s: Loaded a brush model after the world", __func__);
@ -1031,38 +1068,11 @@ Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen)
Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
Mod_LoadNodes (&header->lumps[LUMP_NODES]); Mod_LoadNodes (&header->lumps[LUMP_NODES]);
Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); Mod_LoadSubmodels (loadmodel, mod_base, &header->lumps[LUMP_MODELS]);
r_numvisleafs = 0; r_numvisleafs = 0;
R_NumberLeafs (loadmodel->nodes); R_NumberLeafs (loadmodel->nodes);
//
// set up the submodels
//
for (i=0 ; i<mod->numsubmodels ; i++)
{
model_t *starmod;
bm = &mod->submodels[i];
starmod = &mod_inline[i];
*starmod = *loadmodel;
starmod->firstmodelsurface = bm->firstface;
starmod->nummodelsurfaces = bm->numfaces;
starmod->firstnode = bm->headnode;
if (starmod->firstnode >= loadmodel->numnodes)
{
ri.Sys_Error(ERR_DROP, "%s: Inline model %i has bad firstnode",
__func__, i);
}
VectorCopy (bm->maxs, starmod->maxs);
VectorCopy (bm->mins, starmod->mins);
if (i == 0)
*loadmodel = *starmod;
}
R_InitSkyBox (); R_InitSkyBox ();
} }
@ -1325,7 +1335,7 @@ RE_RegisterModel (char *name)
{ {
model_t *mod; model_t *mod;
mod = Mod_ForName (name, false); mod = Mod_ForName (name, r_worldmodel, false);
if (mod) if (mod)
{ {
int i; int i;