mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-03-22 10:52:09 +00:00
Move BSPX lighting code to shared code
This commit is contained in:
parent
4a3dbb22d9
commit
21ceb16de4
10 changed files with 725 additions and 633 deletions
5
Makefile
5
Makefile
|
@ -997,6 +997,7 @@ REFGL1_OBJS_ := \
|
|||
src/client/refresh/gl1/gl1_surf.o \
|
||||
src/client/refresh/gl1/gl1_warp.o \
|
||||
src/client/refresh/gl1/gl1_sdl.o \
|
||||
src/client/refresh/files/light.o \
|
||||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/pcx.o \
|
||||
|
@ -1030,6 +1031,7 @@ REFGL3_OBJS_ := \
|
|||
src/client/refresh/gl3/gl3_surf.o \
|
||||
src/client/refresh/gl3/gl3_warp.o \
|
||||
src/client/refresh/gl3/gl3_shaders.o \
|
||||
src/client/refresh/files/light.o \
|
||||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/pcx.o \
|
||||
|
@ -1069,6 +1071,7 @@ REFGL4_OBJS_ := \
|
|||
src/client/refresh/gl4/gl4_surf.o \
|
||||
src/client/refresh/gl4/gl4_warp.o \
|
||||
src/client/refresh/gl4/gl4_shaders.o \
|
||||
src/client/refresh/files/light.o \
|
||||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/pcx.o \
|
||||
|
@ -1109,6 +1112,7 @@ REFSOFT_OBJS_ := \
|
|||
src/client/refresh/soft/sw_scan.o \
|
||||
src/client/refresh/soft/sw_sprite.o \
|
||||
src/client/refresh/soft/sw_surf.o \
|
||||
src/client/refresh/files/light.o \
|
||||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/pcx.o \
|
||||
|
@ -1149,6 +1153,7 @@ REFVK_OBJS_ := \
|
|||
src/client/refresh/vk/vk_warp.o \
|
||||
src/client/refresh/vk/vk_util.o \
|
||||
src/client/refresh/vk/volk/volk.o \
|
||||
src/client/refresh/files/light.o \
|
||||
src/client/refresh/files/surf.o \
|
||||
src/client/refresh/files/models.o \
|
||||
src/client/refresh/files/pcx.o \
|
||||
|
|
94
src/client/refresh/files/light.c
Normal file
94
src/client/refresh/files/light.c
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Light logic
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#include "../ref_shared.h"
|
||||
|
||||
static int
|
||||
BSPX_LightGridSingleValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles, int x, int y, int z, vec3_t res_diffuse)
|
||||
{
|
||||
int i;
|
||||
unsigned int node;
|
||||
struct bspxlgsamp_s *samp;
|
||||
|
||||
node = grid->rootnode;
|
||||
while (!(node & LGNODE_LEAF))
|
||||
{
|
||||
struct bspxlgnode_s *n;
|
||||
if (node & LGNODE_MISSING)
|
||||
return 0; //failure
|
||||
n = grid->nodes + node;
|
||||
node = n->child[
|
||||
((x>=n->mid[0])<<2)|
|
||||
((y>=n->mid[1])<<1)|
|
||||
((z>=n->mid[2])<<0)];
|
||||
}
|
||||
|
||||
{
|
||||
struct bspxlgleaf_s *leaf = &grid->leafs[node & ~LGNODE_LEAF];
|
||||
x -= leaf->mins[0];
|
||||
y -= leaf->mins[1];
|
||||
z -= leaf->mins[2];
|
||||
if (x >= leaf->size[0] ||
|
||||
y >= leaf->size[1] ||
|
||||
z >= leaf->size[2])
|
||||
return 0; //sample we're after is out of bounds...
|
||||
|
||||
i = x + leaf->size[0]*(y + leaf->size[1]*z);
|
||||
samp = leaf->rgbvalues + i;
|
||||
|
||||
//no hdr support
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (samp->map[i].style == ((byte)(~0u)))
|
||||
break; //no more
|
||||
res_diffuse[0] += samp->map[i].rgb[0] * lightstyles[samp->map[i].style].rgb[0] / 255.0;
|
||||
res_diffuse[1] += samp->map[i].rgb[1] * lightstyles[samp->map[i].style].rgb[1] / 255.0;
|
||||
res_diffuse[2] += samp->map[i].rgb[2] * lightstyles[samp->map[i].style].rgb[2] / 255.0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
BSPX_LightGridValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles, const vec3_t point, vec3_t res_diffuse)
|
||||
{
|
||||
int tile[3];
|
||||
int i;
|
||||
int s;
|
||||
|
||||
VectorSet(res_diffuse, 0, 0, 0); //assume worst
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
tile[i] = (point[i] - grid->mins[i]) * grid->gridscale[i];
|
||||
|
||||
for (i = 0, s = 0; i < 8; i++)
|
||||
s += BSPX_LightGridSingleValue(grid, lightstyles,
|
||||
tile[0]+!!(i&1),
|
||||
tile[1]+!!(i&2),
|
||||
tile[2]+!!(i&4), res_diffuse);
|
||||
|
||||
VectorScale(res_diffuse, 1.0/s, res_diffuse); //average the successful ones
|
||||
}
|
|
@ -2054,3 +2054,154 @@ Mod_LoadBSPX(int filesize, const byte *mod_base)
|
|||
// success
|
||||
return xheader;
|
||||
}
|
||||
|
||||
/* Need to clean */
|
||||
struct rctx_s {
|
||||
const byte *data;
|
||||
int ofs, size;
|
||||
};
|
||||
|
||||
static byte ReadByte(struct rctx_s *ctx)
|
||||
{
|
||||
if (ctx->ofs >= ctx->size)
|
||||
{
|
||||
ctx->ofs++;
|
||||
return 0;
|
||||
}
|
||||
return ctx->data[ctx->ofs++];
|
||||
}
|
||||
|
||||
static int ReadInt(struct rctx_s *ctx)
|
||||
{
|
||||
int r = (int)ReadByte(ctx)<<0;
|
||||
r|= (int)ReadByte(ctx)<<8;
|
||||
r|= (int)ReadByte(ctx)<<16;
|
||||
r|= (int)ReadByte(ctx)<<24;
|
||||
return r;
|
||||
}
|
||||
|
||||
static float ReadFloat(struct rctx_s *ctx)
|
||||
{
|
||||
union {float f; int i;} u;
|
||||
u.i = ReadInt(ctx);
|
||||
return u.f;
|
||||
}
|
||||
|
||||
bspxlightgrid_t*
|
||||
BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base)
|
||||
{
|
||||
vec3_t step, mins;
|
||||
int size[3];
|
||||
bspxlightgrid_t *grid;
|
||||
unsigned int numstyles, numnodes, numleafs, rootnode;
|
||||
unsigned int nodestart, leafsamps = 0, i, j, k, s;
|
||||
struct bspxlgsamp_s *samp;
|
||||
struct rctx_s ctx = {0};
|
||||
|
||||
ctx.data = Mod_LoadBSPXFindLump(bspx_header, "LIGHTGRID_OCTREE", &ctx.size, mod_base);
|
||||
if (!ctx.data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
step[j] = ReadFloat(&ctx);
|
||||
for (j = 0; j < 3; j++)
|
||||
size[j] = ReadInt(&ctx);
|
||||
for (j = 0; j < 3; j++)
|
||||
mins[j] = ReadFloat(&ctx);
|
||||
|
||||
numstyles = ReadByte(&ctx); //urgh, misaligned the entire thing
|
||||
rootnode = ReadInt(&ctx);
|
||||
numnodes = ReadInt(&ctx);
|
||||
nodestart = ctx.ofs;
|
||||
ctx.ofs += (3+8)*4*numnodes;
|
||||
numleafs = ReadInt(&ctx);
|
||||
for (i = 0; i < numleafs; i++)
|
||||
{
|
||||
unsigned int lsz[3];
|
||||
ctx.ofs += 3*4;
|
||||
for (j = 0; j < 3; j++)
|
||||
lsz[j] = ReadInt(&ctx);
|
||||
j = lsz[0]*lsz[1]*lsz[2];
|
||||
leafsamps += j;
|
||||
while (j --> 0)
|
||||
{ //this loop is annonying, memcpy dreams...
|
||||
s = ReadByte(&ctx);
|
||||
if (s == 255)
|
||||
continue;
|
||||
ctx.ofs += s*4;
|
||||
}
|
||||
}
|
||||
|
||||
grid = Hunk_Alloc(sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps);
|
||||
memset(grid, 0xcc, sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps);
|
||||
grid->leafs = (void*)(grid+1);
|
||||
grid->nodes = (void*)(grid->leafs + numleafs);
|
||||
samp = (void*)(grid->nodes+numnodes);
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->gridscale[j] = 1/step[j]; //prefer it as a multiply
|
||||
VectorCopy(mins, grid->mins);
|
||||
VectorCopy(size, grid->count);
|
||||
grid->numnodes = numnodes;
|
||||
grid->numleafs = numleafs;
|
||||
grid->rootnode = rootnode;
|
||||
(void)numstyles;
|
||||
|
||||
//rewind to the nodes. *sigh*
|
||||
ctx.ofs = nodestart;
|
||||
for (i = 0; i < numnodes; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->nodes[i].mid[j] = ReadInt(&ctx);
|
||||
for (j = 0; j < 8; j++)
|
||||
grid->nodes[i].child[j] = ReadInt(&ctx);
|
||||
}
|
||||
ctx.ofs += 4;
|
||||
for (i = 0; i < numleafs; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->leafs[i].mins[j] = ReadInt(&ctx);
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->leafs[i].size[j] = ReadInt(&ctx);
|
||||
|
||||
grid->leafs[i].rgbvalues = samp;
|
||||
|
||||
j = grid->leafs[i].size[0]*grid->leafs[i].size[1]*grid->leafs[i].size[2];
|
||||
while (j --> 0)
|
||||
{
|
||||
s = ReadByte(&ctx);
|
||||
if (s == 0xff)
|
||||
memset(samp, 0xff, sizeof(*samp));
|
||||
else
|
||||
{
|
||||
for (k = 0; k < s; k++)
|
||||
{
|
||||
if (k >= 4)
|
||||
ReadInt(&ctx);
|
||||
else
|
||||
{
|
||||
samp->map[k].style = ReadByte(&ctx);
|
||||
samp->map[k].rgb[0] = ReadByte(&ctx);
|
||||
samp->map[k].rgb[1] = ReadByte(&ctx);
|
||||
samp->map[k].rgb[2] = ReadByte(&ctx);
|
||||
}
|
||||
}
|
||||
for (; k < 4; k++)
|
||||
{
|
||||
samp->map[k].style = (byte)~0u;
|
||||
samp->map[k].rgb[0] =
|
||||
samp->map[k].rgb[1] =
|
||||
samp->map[k].rgb[2] = 0;
|
||||
}
|
||||
}
|
||||
samp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.ofs != ctx.size)
|
||||
grid = NULL;
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
|
|
@ -29,12 +29,12 @@
|
|||
#define NUMVERTEXNORMALS 162
|
||||
#define SHADEDOT_QUANT 16
|
||||
|
||||
float r_avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||
static float r_avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||
#include "../constants/anorms.h"
|
||||
};
|
||||
|
||||
/* precalculated dot products for quantized angles */
|
||||
float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
|
||||
static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
|
||||
#include "../constants/anormtab.h"
|
||||
};
|
||||
|
||||
|
@ -376,9 +376,9 @@ R_DrawAliasShadowCommand(entity_t *currententity, int *order, int *order_end,
|
|||
point[1] -= shadevector[1] * (point[2] + lheight);
|
||||
point[2] = height;
|
||||
|
||||
vtx[index_vtx++] = point [ 0 ];
|
||||
vtx[index_vtx++] = point [ 1 ];
|
||||
vtx[index_vtx++] = point [ 2 ];
|
||||
vtx[index_vtx++] = point[0];
|
||||
vtx[index_vtx++] = point[1];
|
||||
vtx[index_vtx++] = point[2];
|
||||
|
||||
order += 3;
|
||||
}
|
||||
|
@ -673,7 +673,8 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
|
|||
{
|
||||
if (r_worldmodel->grid)
|
||||
{
|
||||
BSPX_LightGridValue(r_worldmodel->grid, currententity->origin, shadelight);
|
||||
BSPX_LightGridValue(r_worldmodel->grid, r_newrefdef.lightstyles,
|
||||
currententity->origin, shadelight);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -732,12 +733,13 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
|
|||
{
|
||||
/* bonus items will pulse with time */
|
||||
float scale;
|
||||
float min;
|
||||
|
||||
scale = 0.1 * sin(r_newrefdef.time * 7);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
float min;
|
||||
|
||||
min = shadelight[i] * 0.8;
|
||||
shadelight[i] += scale;
|
||||
|
||||
|
@ -951,4 +953,3 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel)
|
|||
|
||||
glColor4f(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ static YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8];
|
|||
|
||||
#define MAX_MOD_KNOWN 512
|
||||
static model_t mod_known[MAX_MOD_KNOWN];
|
||||
static int mod_numknown;
|
||||
static int mod_numknown = 0;
|
||||
static int mod_max = 0;
|
||||
|
||||
int registration_sequence;
|
||||
|
@ -1161,7 +1161,7 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
|||
return mod;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
Mod_Free(model_t *mod)
|
||||
{
|
||||
Hunk_Free(mod->extradata);
|
||||
|
@ -1272,220 +1272,3 @@ RI_EndRegistration(void)
|
|||
|
||||
R_FreeUnusedImages();
|
||||
}
|
||||
|
||||
/* Need to clean */
|
||||
struct rctx_s {
|
||||
const byte *data;
|
||||
int ofs, size;
|
||||
};
|
||||
|
||||
static byte ReadByte(struct rctx_s *ctx)
|
||||
{
|
||||
if (ctx->ofs >= ctx->size)
|
||||
{
|
||||
ctx->ofs++;
|
||||
return 0;
|
||||
}
|
||||
return ctx->data[ctx->ofs++];
|
||||
}
|
||||
|
||||
static int ReadInt(struct rctx_s *ctx)
|
||||
{
|
||||
int r = (int)ReadByte(ctx)<<0;
|
||||
r|= (int)ReadByte(ctx)<<8;
|
||||
r|= (int)ReadByte(ctx)<<16;
|
||||
r|= (int)ReadByte(ctx)<<24;
|
||||
return r;
|
||||
}
|
||||
|
||||
static float ReadFloat(struct rctx_s *ctx)
|
||||
{
|
||||
union {float f; int i;} u;
|
||||
u.i = ReadInt(ctx);
|
||||
return u.f;
|
||||
}
|
||||
|
||||
bspxlightgrid_t*
|
||||
BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base)
|
||||
{
|
||||
vec3_t step, mins;
|
||||
int size[3];
|
||||
bspxlightgrid_t *grid;
|
||||
unsigned int numstyles, numnodes, numleafs, rootnode;
|
||||
unsigned int nodestart, leafsamps = 0, i, j, k, s;
|
||||
struct bspxlgsamp_s *samp;
|
||||
struct rctx_s ctx = {0};
|
||||
|
||||
ctx.data = Mod_LoadBSPXFindLump(bspx_header, "LIGHTGRID_OCTREE", &ctx.size, mod_base);
|
||||
if (!ctx.data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
step[j] = ReadFloat(&ctx);
|
||||
for (j = 0; j < 3; j++)
|
||||
size[j] = ReadInt(&ctx);
|
||||
for (j = 0; j < 3; j++)
|
||||
mins[j] = ReadFloat(&ctx);
|
||||
|
||||
numstyles = ReadByte(&ctx); //urgh, misaligned the entire thing
|
||||
rootnode = ReadInt(&ctx);
|
||||
numnodes = ReadInt(&ctx);
|
||||
nodestart = ctx.ofs;
|
||||
ctx.ofs += (3+8)*4*numnodes;
|
||||
numleafs = ReadInt(&ctx);
|
||||
for (i = 0; i < numleafs; i++)
|
||||
{
|
||||
unsigned int lsz[3];
|
||||
ctx.ofs += 3*4;
|
||||
for (j = 0; j < 3; j++)
|
||||
lsz[j] = ReadInt(&ctx);
|
||||
j = lsz[0]*lsz[1]*lsz[2];
|
||||
leafsamps += j;
|
||||
while (j --> 0)
|
||||
{ //this loop is annonying, memcpy dreams...
|
||||
s = ReadByte(&ctx);
|
||||
if (s == 255)
|
||||
continue;
|
||||
ctx.ofs += s*4;
|
||||
}
|
||||
}
|
||||
|
||||
grid = Hunk_Alloc(sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps);
|
||||
memset(grid, 0xcc, sizeof(*grid) + sizeof(*grid->leafs)*numleafs + sizeof(*grid->nodes)*numnodes + sizeof(struct bspxlgsamp_s)*leafsamps);
|
||||
grid->leafs = (void*)(grid+1);
|
||||
grid->nodes = (void*)(grid->leafs + numleafs);
|
||||
samp = (void*)(grid->nodes+numnodes);
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->gridscale[j] = 1/step[j]; //prefer it as a multiply
|
||||
VectorCopy(mins, grid->mins);
|
||||
VectorCopy(size, grid->count);
|
||||
grid->numnodes = numnodes;
|
||||
grid->numleafs = numleafs;
|
||||
grid->rootnode = rootnode;
|
||||
(void)numstyles;
|
||||
|
||||
//rewind to the nodes. *sigh*
|
||||
ctx.ofs = nodestart;
|
||||
for (i = 0; i < numnodes; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->nodes[i].mid[j] = ReadInt(&ctx);
|
||||
for (j = 0; j < 8; j++)
|
||||
grid->nodes[i].child[j] = ReadInt(&ctx);
|
||||
}
|
||||
ctx.ofs += 4;
|
||||
for (i = 0; i < numleafs; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->leafs[i].mins[j] = ReadInt(&ctx);
|
||||
for (j = 0; j < 3; j++)
|
||||
grid->leafs[i].size[j] = ReadInt(&ctx);
|
||||
|
||||
grid->leafs[i].rgbvalues = samp;
|
||||
|
||||
j = grid->leafs[i].size[0]*grid->leafs[i].size[1]*grid->leafs[i].size[2];
|
||||
while (j --> 0)
|
||||
{
|
||||
s = ReadByte(&ctx);
|
||||
if (s == 0xff)
|
||||
memset(samp, 0xff, sizeof(*samp));
|
||||
else
|
||||
{
|
||||
for (k = 0; k < s; k++)
|
||||
{
|
||||
if (k >= 4)
|
||||
ReadInt(&ctx);
|
||||
else
|
||||
{
|
||||
samp->map[k].style = ReadByte(&ctx);
|
||||
samp->map[k].rgb[0] = ReadByte(&ctx);
|
||||
samp->map[k].rgb[1] = ReadByte(&ctx);
|
||||
samp->map[k].rgb[2] = ReadByte(&ctx);
|
||||
}
|
||||
}
|
||||
for (; k < 4; k++)
|
||||
{
|
||||
samp->map[k].style = (byte)~0u;
|
||||
samp->map[k].rgb[0] =
|
||||
samp->map[k].rgb[1] =
|
||||
samp->map[k].rgb[2] = 0;
|
||||
}
|
||||
}
|
||||
samp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.ofs != ctx.size)
|
||||
grid = NULL;
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
static int
|
||||
BSPX_LightGridSingleValue(bspxlightgrid_t *grid, int x, int y, int z, vec3_t res_diffuse)
|
||||
{
|
||||
int i;
|
||||
unsigned int node;
|
||||
struct bspxlgsamp_s *samp;
|
||||
|
||||
node = grid->rootnode;
|
||||
while (!(node & LGNODE_LEAF))
|
||||
{
|
||||
struct bspxlgnode_s *n;
|
||||
if (node & LGNODE_MISSING)
|
||||
return 0; //failure
|
||||
n = grid->nodes + node;
|
||||
node = n->child[
|
||||
((x>=n->mid[0])<<2)|
|
||||
((y>=n->mid[1])<<1)|
|
||||
((z>=n->mid[2])<<0)];
|
||||
}
|
||||
|
||||
{
|
||||
struct bspxlgleaf_s *leaf = &grid->leafs[node & ~LGNODE_LEAF];
|
||||
x -= leaf->mins[0];
|
||||
y -= leaf->mins[1];
|
||||
z -= leaf->mins[2];
|
||||
if (x >= leaf->size[0] ||
|
||||
y >= leaf->size[1] ||
|
||||
z >= leaf->size[2])
|
||||
return 0; //sample we're after is out of bounds...
|
||||
|
||||
i = x + leaf->size[0]*(y + leaf->size[1]*z);
|
||||
samp = leaf->rgbvalues + i;
|
||||
|
||||
//no hdr support
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (samp->map[i].style == ((byte)(~0u)))
|
||||
break; //no more
|
||||
res_diffuse[0] += samp->map[i].rgb[0] * r_newrefdef.lightstyles[samp->map[i].style].rgb[0] / 255.0;
|
||||
res_diffuse[1] += samp->map[i].rgb[1] * r_newrefdef.lightstyles[samp->map[i].style].rgb[1] / 255.0;
|
||||
res_diffuse[2] += samp->map[i].rgb[2] * r_newrefdef.lightstyles[samp->map[i].style].rgb[2] / 255.0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
BSPX_LightGridValue(bspxlightgrid_t *grid, const vec3_t point, vec3_t res_diffuse)
|
||||
{
|
||||
int tile[3];
|
||||
int i;
|
||||
int s;
|
||||
|
||||
VectorSet(res_diffuse, 0, 0, 0); //assume worst
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
tile[i] = (point[i] - grid->mins[i]) * grid->gridscale[i];
|
||||
|
||||
for (i = 0, s = 0; i < 8; i++)
|
||||
s += BSPX_LightGridSingleValue(grid, tile[0]+!!(i&1),
|
||||
tile[1]+!!(i&2),
|
||||
tile[2]+!!(i&4), res_diffuse);
|
||||
|
||||
VectorScale(res_diffuse, 1.0/s, res_diffuse); //average the successful ones
|
||||
}
|
||||
|
|
|
@ -29,41 +29,6 @@
|
|||
|
||||
#include "../../ref_model.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t gridscale;
|
||||
unsigned int count[3];
|
||||
vec3_t mins;
|
||||
unsigned int styles;
|
||||
|
||||
unsigned int rootnode;
|
||||
|
||||
unsigned int numnodes;
|
||||
struct bspxlgnode_s
|
||||
{ //this uses an octtree to trim samples.
|
||||
int mid[3];
|
||||
unsigned int child[8];
|
||||
#define LGNODE_LEAF (1u<<31)
|
||||
#define LGNODE_MISSING (1u<<30)
|
||||
} *nodes;
|
||||
unsigned int numleafs;
|
||||
struct bspxlgleaf_s
|
||||
{
|
||||
int mins[3];
|
||||
int size[3];
|
||||
struct bspxlgsamp_s
|
||||
{
|
||||
struct
|
||||
{
|
||||
byte style;
|
||||
byte rgb[3];
|
||||
} map[4];
|
||||
} *rgbvalues;
|
||||
} *leafs;
|
||||
} bspxlightgrid_t;
|
||||
bspxlightgrid_t* BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base);
|
||||
void BSPX_LightGridValue(bspxlightgrid_t *grid, const vec3_t point, vec3_t res_diffuse);
|
||||
|
||||
/* Whole model */
|
||||
|
||||
typedef struct model_s
|
||||
|
@ -149,6 +114,5 @@ int Hunk_End(void);
|
|||
void Hunk_Free(void *base);
|
||||
|
||||
void Mod_FreeAll(void);
|
||||
void Mod_Free(model_t *mod);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -179,6 +179,50 @@ typedef struct mleaf_s
|
|||
int key; /* BSP sequence number for leaf's contents */
|
||||
} mleaf_t;
|
||||
|
||||
/* BSPX Light octtree */
|
||||
#define LGNODE_LEAF (1u<<31)
|
||||
#define LGNODE_MISSING (1u<<30)
|
||||
|
||||
/* this uses an octtree to trim samples. */
|
||||
typedef struct bspxlgnode_s
|
||||
{
|
||||
int mid[3];
|
||||
unsigned int child[8];
|
||||
} bspxlgnode_t;
|
||||
|
||||
typedef struct bspxlglightstyle_s
|
||||
{
|
||||
byte style;
|
||||
byte rgb[3];
|
||||
} bspxlglightstyle_t;
|
||||
|
||||
typedef struct bspxlgsamp_s
|
||||
{
|
||||
bspxlglightstyle_t map[4];
|
||||
} bspxlgsamp_t;
|
||||
|
||||
typedef struct bspxlgleaf_s
|
||||
{
|
||||
int mins[3];
|
||||
int size[3];
|
||||
bspxlgsamp_t *rgbvalues;
|
||||
} bspxlgleaf_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t gridscale;
|
||||
unsigned int count[3];
|
||||
vec3_t mins;
|
||||
unsigned int styles;
|
||||
|
||||
unsigned int rootnode;
|
||||
|
||||
unsigned int numnodes;
|
||||
bspxlgnode_t *nodes;
|
||||
unsigned int numleafs;
|
||||
bspxlgleaf_t *leafs;
|
||||
} bspxlightgrid_t;
|
||||
|
||||
/* Shared models func */
|
||||
typedef struct image_s* (*findimage_t)(const char *name, imagetype_t type);
|
||||
extern void *Mod_LoadAliasModel (const char *mod_name, const void *buffer, int modfilelen,
|
||||
|
@ -237,4 +281,9 @@ extern void R_SetFrustum(vec3_t vup, vec3_t vpn, vec3_t vright, vec3_t r_origin,
|
|||
float fov_x, float fov_y, cplane_t *frustum);
|
||||
extern void R_BoundPoly(int numverts, float *verts, vec3_t mins, vec3_t maxs);
|
||||
|
||||
/* Lights logic */
|
||||
extern bspxlightgrid_t *BSPX_LightGridLoad(const bspx_header_t *bspx_header, const byte *mod_base);
|
||||
extern void BSPX_LightGridValue(const bspxlightgrid_t *grid, const lightstyle_t *lightstyles,
|
||||
const vec3_t point, vec3_t res_diffuse);
|
||||
|
||||
#endif /* SRC_CLIENT_REFRESH_REF_SHARED_H_ */
|
||||
|
|
|
@ -54,91 +54,86 @@ BRUSH MODELS
|
|||
|
||||
typedef struct model_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
char name[MAX_QPATH];
|
||||
|
||||
int registration_sequence;
|
||||
int registration_sequence;
|
||||
|
||||
modtype_t type;
|
||||
int numframes;
|
||||
modtype_t type;
|
||||
int numframes;
|
||||
|
||||
int flags;
|
||||
int flags;
|
||||
|
||||
//
|
||||
// volume occupied by the model graphics
|
||||
//
|
||||
vec3_t mins, maxs;
|
||||
float radius;
|
||||
/* volume occupied by the model graphics */
|
||||
vec3_t mins, maxs;
|
||||
float radius;
|
||||
|
||||
//
|
||||
// solid volume for clipping
|
||||
//
|
||||
qboolean clipbox;
|
||||
vec3_t clipmins, clipmaxs;
|
||||
/* solid volume for clipping */
|
||||
qboolean clipbox;
|
||||
vec3_t clipmins, clipmaxs;
|
||||
|
||||
//
|
||||
// brush model
|
||||
//
|
||||
int firstmodelsurface, nummodelsurfaces;
|
||||
int lightmap; // only for submodels
|
||||
/* brush model */
|
||||
int firstmodelsurface, nummodelsurfaces;
|
||||
int lightmap; /* only for submodels */
|
||||
|
||||
int numsubmodels;
|
||||
struct model_s *submodels;
|
||||
int numsubmodels;
|
||||
struct model_s *submodels;
|
||||
|
||||
int numplanes;
|
||||
cplane_t *planes;
|
||||
int numplanes;
|
||||
cplane_t *planes;
|
||||
|
||||
int numleafs; // number of visible leafs, not counting 0
|
||||
mleaf_t *leafs;
|
||||
int numleafs; /* number of visible leafs, not counting 0 */
|
||||
mleaf_t *leafs;
|
||||
|
||||
int numvertexes;
|
||||
mvertex_t *vertexes;
|
||||
int numvertexes;
|
||||
mvertex_t *vertexes;
|
||||
|
||||
int numedges;
|
||||
medge_t *edges;
|
||||
int numedges;
|
||||
medge_t *edges;
|
||||
|
||||
int numnodes;
|
||||
int firstnode;
|
||||
mnode_t *nodes;
|
||||
int numnodes;
|
||||
int firstnode;
|
||||
mnode_t *nodes;
|
||||
|
||||
int numtexinfo;
|
||||
mtexinfo_t *texinfo;
|
||||
int numtexinfo;
|
||||
mtexinfo_t *texinfo;
|
||||
|
||||
int numsurfaces;
|
||||
msurface_t *surfaces;
|
||||
int numsurfaces;
|
||||
msurface_t *surfaces;
|
||||
|
||||
int numsurfedges;
|
||||
int *surfedges;
|
||||
int numsurfedges;
|
||||
int *surfedges;
|
||||
|
||||
int nummarksurfaces;
|
||||
msurface_t **marksurfaces;
|
||||
int nummarksurfaces;
|
||||
msurface_t **marksurfaces;
|
||||
|
||||
dvis_t *vis;
|
||||
dvis_t *vis;
|
||||
|
||||
byte *lightdata;
|
||||
byte *lightdata;
|
||||
|
||||
// for alias models and skins
|
||||
image_t *skins[MAX_MD2SKINS];
|
||||
/* for alias models and skins */
|
||||
image_t *skins[MAX_MD2SKINS];
|
||||
|
||||
int extradatasize;
|
||||
void *extradata;
|
||||
int extradatasize;
|
||||
void *extradata;
|
||||
|
||||
// submodules
|
||||
vec3_t origin; // for sounds or lights
|
||||
|
||||
/* octree */
|
||||
bspxlightgrid_t *grid;
|
||||
} model_t;
|
||||
|
||||
//============================================================================
|
||||
void Mod_Init(void);
|
||||
const byte *Mod_ClusterPVS(int cluster, const model_t *model);
|
||||
|
||||
void Mod_Init (void);
|
||||
const byte *Mod_ClusterPVS (int cluster, const model_t *model);
|
||||
void Mod_Modellist_f(void);
|
||||
|
||||
void Mod_Modellist_f (void);
|
||||
void *Hunk_Begin(int maxsize);
|
||||
void *Hunk_Alloc(int size);
|
||||
int Hunk_End(void);
|
||||
void Hunk_Free(void *base);
|
||||
|
||||
void *Hunk_Begin (int maxsize);
|
||||
void *Hunk_Alloc (int size);
|
||||
int Hunk_End (void);
|
||||
void Hunk_Free (void *base);
|
||||
|
||||
void Mod_FreeAll (void);
|
||||
void Mod_FreeAll(void);
|
||||
void Mod_FreeModelsKnown (void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,23 +20,15 @@
|
|||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Triangle model functions
|
||||
* Mesh handling
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
ALIAS MODELS
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
|
||||
#define NUMVERTEXNORMALS 162
|
||||
#define NUMVERTEXNORMALS 162
|
||||
#define SHADEDOT_QUANT 16
|
||||
|
||||
static float r_avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||
#include "../constants/anorms.h"
|
||||
|
@ -64,20 +56,18 @@ polyvert_t *verts_buffer = NULL;
|
|||
lmappolyvert_t *lmappolyverts_buffer = NULL;
|
||||
static drawinfo_t *drawInfo[2] = {NULL, NULL};
|
||||
static modelvert *vertList[2] = {NULL, NULL};
|
||||
static vec4_t *s_lerped = NULL;
|
||||
static vec3_t *shadowverts = NULL;
|
||||
static int verts_count = 0;
|
||||
|
||||
vec3_t shadevector;
|
||||
float shadelight[3];
|
||||
|
||||
// precalculated dot products for quantized angles
|
||||
#define SHADEDOT_QUANT 16
|
||||
/* precalculated dot products for quantized angles */
|
||||
static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
|
||||
#include "../constants/anormtab.h"
|
||||
};
|
||||
|
||||
float *shadedots = r_avertexnormal_dots[0];
|
||||
static vec4_t *s_lerped = NULL;
|
||||
vec3_t shadevector;
|
||||
float shadelight[3];
|
||||
float *shadedots = r_avertexnormal_dots[0];
|
||||
|
||||
// correction matrix with "hacked depth" for models with RF_DEPTHHACK flag set
|
||||
static float r_vulkan_correction_dh[16] = {
|
||||
|
@ -244,34 +234,39 @@ void Mesh_Free (void)
|
|||
}
|
||||
|
||||
|
||||
static void Vk_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts,
|
||||
static void
|
||||
Vk_LerpVerts(int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts,
|
||||
float *lerp, const float move[3], const float frontv[3], const float backv[3],
|
||||
entity_t *currententity )
|
||||
entity_t *currententity)
|
||||
{
|
||||
int i;
|
||||
|
||||
//PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM
|
||||
if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
|
||||
if (currententity->flags &
|
||||
(RF_SHELL_RED | RF_SHELL_GREEN |
|
||||
RF_SHELL_BLUE | RF_SHELL_DOUBLE |
|
||||
RF_SHELL_HALF_DAM))
|
||||
{
|
||||
for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4 )
|
||||
for (i = 0; i < nverts; i++, v++, ov++, lerp += 4)
|
||||
{
|
||||
float *normal = r_avertexnormals[verts[i].lightnormalindex];
|
||||
|
||||
lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0] + normal[0] * POWERSUIT_SCALE;
|
||||
lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1] + normal[1] * POWERSUIT_SCALE;
|
||||
lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2] + normal[2] * POWERSUIT_SCALE;
|
||||
lerp[0] = move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0] +
|
||||
normal[0] * POWERSUIT_SCALE;
|
||||
lerp[1] = move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1] +
|
||||
normal[1] * POWERSUIT_SCALE;
|
||||
lerp[2] = move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2] +
|
||||
normal[2] * POWERSUIT_SCALE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4)
|
||||
for (i = 0; i < nverts; i++, v++, ov++, lerp += 4)
|
||||
{
|
||||
lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0];
|
||||
lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1];
|
||||
lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2];
|
||||
lerp[0] = move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0];
|
||||
lerp[1] = move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1];
|
||||
lerp[2] = move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -298,10 +293,11 @@ Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_e
|
|||
|
||||
while (1)
|
||||
{
|
||||
int count;
|
||||
int count;
|
||||
|
||||
// get the vertex count and primitive type
|
||||
/* get the vertex count and primitive type */
|
||||
count = *order++;
|
||||
|
||||
if (!count || order >= order_end)
|
||||
{
|
||||
break; /* done */
|
||||
|
@ -325,7 +321,8 @@ Vk_DrawAliasFrameLerpCommands (entity_t *currententity, int *order, int *order_e
|
|||
drawInfo[pipelineIdx][pipeCounters[pipelineIdx]].vertexCount = count;
|
||||
maxTriangleFanIdxCnt = max(maxTriangleFanIdxCnt, ((count - 2) * 3));
|
||||
|
||||
if (currententity->flags & (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE))
|
||||
if (currententity->flags &
|
||||
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE))
|
||||
{
|
||||
meshUbo.textured = 0;
|
||||
do
|
||||
|
@ -469,57 +466,61 @@ FIXME: batch lerp all vertexes
|
|||
=============
|
||||
*/
|
||||
static void
|
||||
Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin,
|
||||
Vk_DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp, image_t *skin,
|
||||
float *modelMatrix, int leftHandOffset, int translucentIdx, entity_t *currententity)
|
||||
{
|
||||
daliasframe_t *frame, *oldframe;
|
||||
dtrivertx_t *v, *ov, *verts;
|
||||
int *order;
|
||||
float frontlerp;
|
||||
float alpha;
|
||||
vec3_t move, delta, vectors[3];
|
||||
vec3_t frontv, backv;
|
||||
int i;
|
||||
float *lerp;
|
||||
daliasframe_t *frame, *oldframe;
|
||||
dtrivertx_t *v, *ov, *verts;
|
||||
int *order;
|
||||
float frontlerp;
|
||||
float alpha;
|
||||
vec3_t move, delta, vectors[3];
|
||||
vec3_t frontv, backv;
|
||||
int i;
|
||||
float *lerp;
|
||||
int num_mesh_nodes;
|
||||
short *mesh_nodes;
|
||||
|
||||
frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
|
||||
+ currententity->frame * paliashdr->framesize);
|
||||
+ currententity->frame * paliashdr->framesize);
|
||||
verts = v = frame->verts;
|
||||
|
||||
oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
|
||||
+ currententity->oldframe * paliashdr->framesize);
|
||||
+ currententity->oldframe * paliashdr->framesize);
|
||||
ov = oldframe->verts;
|
||||
|
||||
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
|
||||
|
||||
if (currententity->flags & RF_TRANSLUCENT)
|
||||
{
|
||||
alpha = currententity->alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = 1.0;
|
||||
}
|
||||
|
||||
frontlerp = 1.0 - backlerp;
|
||||
|
||||
// move should be the delta back to the previous frame * backlerp
|
||||
/* move should be the delta back to the previous frame * backlerp */
|
||||
VectorSubtract(currententity->oldorigin, currententity->origin, delta);
|
||||
AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
|
||||
AngleVectors(currententity->angles, vectors[0], vectors[1], vectors[2]);
|
||||
|
||||
move[0] = DotProduct(delta, vectors[0]); // forward
|
||||
move[1] = -DotProduct(delta, vectors[1]); // left
|
||||
move[2] = DotProduct(delta, vectors[2]); // up
|
||||
move[0] = DotProduct(delta, vectors[0]); /* forward */
|
||||
move[1] = -DotProduct(delta, vectors[1]); /* left */
|
||||
move[2] = DotProduct(delta, vectors[2]); /* up */
|
||||
|
||||
VectorAdd (move, oldframe->translate, move);
|
||||
VectorAdd(move, oldframe->translate, move);
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
move[i] = backlerp*move[i] + frontlerp*frame->translate[i];
|
||||
move[i] = backlerp * move[i] + frontlerp * frame->translate[i];
|
||||
}
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
frontv[i] = frontlerp*frame->scale[i];
|
||||
backv[i] = backlerp*oldframe->scale[i];
|
||||
frontv[i] = frontlerp * frame->scale[i];
|
||||
backv[i] = backlerp * oldframe->scale[i];
|
||||
}
|
||||
|
||||
if (Mesh_VertsRealloc(paliashdr->num_xyz))
|
||||
|
@ -529,7 +530,7 @@ Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin,
|
|||
|
||||
lerp = s_lerped[0];
|
||||
|
||||
Vk_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv, currententity );
|
||||
Vk_LerpVerts(paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv, currententity );
|
||||
|
||||
num_mesh_nodes = (paliashdr->ofs_skins - sizeof(dmdl_t)) / sizeof(short) / 2;
|
||||
mesh_nodes = (short *)((char*)paliashdr + sizeof(dmdl_t));
|
||||
|
@ -554,13 +555,8 @@ Vk_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp, image_t *skin,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
Vk_DrawAliasShadow
|
||||
=============
|
||||
*/
|
||||
static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum,
|
||||
static void
|
||||
Vk_DrawAliasShadow(int *order, int *order_end, int posenum,
|
||||
float *modelMatrix, entity_t *currententity)
|
||||
{
|
||||
vec3_t point;
|
||||
|
@ -579,8 +575,7 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum,
|
|||
|
||||
while (1)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
int i, count;
|
||||
|
||||
i = 0;
|
||||
// get the vertex count and primitive type
|
||||
|
@ -612,11 +607,11 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum,
|
|||
ri.Sys_Error(ERR_FATAL, "%s: can't allocate memory", __func__);
|
||||
}
|
||||
|
||||
// normals and vertexes come from the frame list
|
||||
memcpy( point, s_lerped[order[2]], sizeof( point ) );
|
||||
/* normals and vertexes come from the frame list */
|
||||
memcpy(point, s_lerped[order[2]], sizeof(point));
|
||||
|
||||
point[0] -= shadevector[0]*(point[2]+lheight);
|
||||
point[1] -= shadevector[1]*(point[2]+lheight);
|
||||
point[0] -= shadevector[0] * (point[2] + lheight);
|
||||
point[1] -= shadevector[1] * (point[2] + lheight);
|
||||
point[2] = height;
|
||||
|
||||
shadowverts[i][0] = point[0];
|
||||
|
@ -625,7 +620,8 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum,
|
|||
|
||||
order += 3;
|
||||
i++;
|
||||
} while (--count);
|
||||
}
|
||||
while (--count);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
|
@ -653,142 +649,158 @@ static void Vk_DrawAliasShadow (int *order, int *order_end, int posenum,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** R_CullAliasModel
|
||||
*/
|
||||
static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e, model_t *currentmodel )
|
||||
static qboolean
|
||||
R_CullAliasModel(vec3_t bbox[8], entity_t *e, model_t *currentmodel )
|
||||
{
|
||||
int i;
|
||||
vec3_t mins, maxs;
|
||||
dmdl_t *paliashdr;
|
||||
vec3_t vectors[3];
|
||||
vec3_t thismins, oldmins, thismaxs, oldmaxs;
|
||||
vec3_t mins, maxs;
|
||||
dmdl_t *paliashdr;
|
||||
vec3_t vectors[3];
|
||||
vec3_t thismins, oldmins, thismaxs, oldmaxs;
|
||||
daliasframe_t *pframe, *poldframe;
|
||||
vec3_t angles;
|
||||
|
||||
paliashdr = (dmdl_t *)currentmodel->extradata;
|
||||
|
||||
if ( ( e->frame >= paliashdr->num_frames ) || ( e->frame < 0 ) )
|
||||
if (!paliashdr)
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s %s: no such frame %d\n",
|
||||
__func__, currentmodel->name, e->frame);
|
||||
R_Printf(PRINT_ALL, "%s %s: Model is not fully loaded\n",
|
||||
__func__, currentmodel->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((e->frame >= paliashdr->num_frames) || (e->frame < 0))
|
||||
{
|
||||
R_Printf(PRINT_DEVELOPER, "%s %s: no such frame %d\n",
|
||||
__func__, currentmodel->name, e->frame);
|
||||
e->frame = 0;
|
||||
}
|
||||
if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) )
|
||||
|
||||
if ((e->oldframe >= paliashdr->num_frames) || (e->oldframe < 0))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "%s %s: no such oldframe %d\n",
|
||||
__func__, currentmodel->name, e->oldframe);
|
||||
R_Printf(PRINT_DEVELOPER, "%s %s: no such oldframe %d\n",
|
||||
__func__, currentmodel->name, e->oldframe);
|
||||
e->oldframe = 0;
|
||||
}
|
||||
|
||||
pframe = ( daliasframe_t * ) ( ( byte * ) paliashdr +
|
||||
paliashdr->ofs_frames +
|
||||
e->frame * paliashdr->framesize);
|
||||
pframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames +
|
||||
e->frame * paliashdr->framesize);
|
||||
|
||||
poldframe = ( daliasframe_t * ) ( ( byte * ) paliashdr +
|
||||
paliashdr->ofs_frames +
|
||||
e->oldframe * paliashdr->framesize);
|
||||
poldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames +
|
||||
e->oldframe * paliashdr->framesize);
|
||||
|
||||
/*
|
||||
** compute axially aligned mins and maxs
|
||||
*/
|
||||
if ( pframe == poldframe )
|
||||
/* compute axially aligned mins and maxs */
|
||||
if (pframe == poldframe)
|
||||
{
|
||||
for ( i = 0; i < 3; i++ )
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
mins[i] = pframe->translate[i];
|
||||
maxs[i] = mins[i] + pframe->scale[i]*255;
|
||||
maxs[i] = mins[i] + pframe->scale[i] * 255;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < 3; i++ )
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
thismins[i] = pframe->translate[i];
|
||||
thismaxs[i] = thismins[i] + pframe->scale[i]*255;
|
||||
thismaxs[i] = thismins[i] + pframe->scale[i] * 255;
|
||||
|
||||
oldmins[i] = poldframe->translate[i];
|
||||
oldmaxs[i] = oldmins[i] + poldframe->scale[i]*255;
|
||||
oldmins[i] = poldframe->translate[i];
|
||||
oldmaxs[i] = oldmins[i] + poldframe->scale[i] * 255;
|
||||
|
||||
if ( thismins[i] < oldmins[i] )
|
||||
if (thismins[i] < oldmins[i])
|
||||
{
|
||||
mins[i] = thismins[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
mins[i] = oldmins[i];
|
||||
}
|
||||
|
||||
if ( thismaxs[i] > oldmaxs[i] )
|
||||
if (thismaxs[i] > oldmaxs[i])
|
||||
{
|
||||
maxs[i] = thismaxs[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
maxs[i] = oldmaxs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** compute a full bounding box
|
||||
*/
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
vec3_t tmp;
|
||||
|
||||
if ( i & 1 )
|
||||
tmp[0] = mins[0];
|
||||
else
|
||||
tmp[0] = maxs[0];
|
||||
|
||||
if ( i & 2 )
|
||||
tmp[1] = mins[1];
|
||||
else
|
||||
tmp[1] = maxs[1];
|
||||
|
||||
if ( i & 4 )
|
||||
tmp[2] = mins[2];
|
||||
else
|
||||
tmp[2] = maxs[2];
|
||||
|
||||
VectorCopy( tmp, bbox[i] );
|
||||
}
|
||||
|
||||
/*
|
||||
** rotate the bounding box
|
||||
*/
|
||||
VectorCopy( e->angles, angles );
|
||||
angles[YAW] = -angles[YAW];
|
||||
AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
|
||||
|
||||
for ( i = 0; i < 8; i++ )
|
||||
/* compute a full bounding box */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
vec3_t tmp;
|
||||
|
||||
VectorCopy( bbox[i], tmp );
|
||||
if (i & 1)
|
||||
{
|
||||
tmp[0] = mins[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp[0] = maxs[0];
|
||||
}
|
||||
|
||||
bbox[i][0] = DotProduct( vectors[0], tmp );
|
||||
bbox[i][1] = -DotProduct( vectors[1], tmp );
|
||||
bbox[i][2] = DotProduct( vectors[2], tmp );
|
||||
if (i & 2)
|
||||
{
|
||||
tmp[1] = mins[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp[1] = maxs[1];
|
||||
}
|
||||
|
||||
VectorAdd( e->origin, bbox[i], bbox[i] );
|
||||
if (i & 4)
|
||||
{
|
||||
tmp[2] = mins[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp[2] = maxs[2];
|
||||
}
|
||||
|
||||
VectorCopy(tmp, bbox[i]);
|
||||
}
|
||||
|
||||
/* rotate the bounding box */
|
||||
VectorCopy(e->angles, angles);
|
||||
angles[YAW] = -angles[YAW];
|
||||
AngleVectors(angles, vectors[0], vectors[1], vectors[2]);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
vec3_t tmp;
|
||||
|
||||
VectorCopy(bbox[i], tmp);
|
||||
|
||||
bbox[i][0] = DotProduct(vectors[0], tmp);
|
||||
bbox[i][1] = -DotProduct(vectors[1], tmp);
|
||||
bbox[i][2] = DotProduct(vectors[2], tmp);
|
||||
|
||||
VectorAdd(e->origin, bbox[i], bbox[i]);
|
||||
}
|
||||
|
||||
{
|
||||
int p, f, aggregatemask = ~0;
|
||||
|
||||
for ( p = 0; p < 8; p++ )
|
||||
for (p = 0; p < 8; p++)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
for ( f = 0; f < 4; f++ )
|
||||
for (f = 0; f < 4; f++)
|
||||
{
|
||||
float dp = DotProduct( frustum[f].normal, bbox[p] );
|
||||
|
||||
if ( ( dp - frustum[f].dist ) < 0 )
|
||||
if ((dp - frustum[f].dist ) < 0)
|
||||
{
|
||||
mask |= ( 1 << f );
|
||||
mask |= (1 << f);
|
||||
}
|
||||
}
|
||||
|
||||
aggregatemask &= mask;
|
||||
}
|
||||
|
||||
if ( aggregatemask )
|
||||
if (aggregatemask)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -797,100 +809,129 @@ static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e, model_t *currentm
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_DrawAliasModel
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_DrawAliasModel (entity_t *currententity, model_t *currentmodel)
|
||||
void
|
||||
R_DrawAliasModel(entity_t *currententity, model_t *currentmodel)
|
||||
{
|
||||
int i;
|
||||
int leftHandOffset = 0;
|
||||
dmdl_t *paliashdr;
|
||||
float an;
|
||||
float prev_viewproj[16];
|
||||
int i;
|
||||
int leftHandOffset = 0;
|
||||
dmdl_t *paliashdr;
|
||||
float an;
|
||||
float prev_viewproj[16];
|
||||
|
||||
if ( !( currententity->flags & RF_WEAPONMODEL ) )
|
||||
if (!(currententity->flags & RF_WEAPONMODEL))
|
||||
{
|
||||
vec3_t bbox[8];
|
||||
vec3_t bbox[8];
|
||||
|
||||
if ( R_CullAliasModel( bbox, currententity, currentmodel ) )
|
||||
if (R_CullAliasModel( bbox, currententity, currentmodel))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( currententity->flags & RF_WEAPONMODEL )
|
||||
if (currententity->flags & RF_WEAPONMODEL)
|
||||
{
|
||||
if ( r_lefthand->value == 2 )
|
||||
if (r_lefthand->value == 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
paliashdr = (dmdl_t *)currentmodel->extradata;
|
||||
|
||||
//
|
||||
// get lighting information
|
||||
//
|
||||
// PMM - rewrote, reordered to handle new shells & mixing
|
||||
// PMM - 3.20 code .. replaced with original way of doing it to keep mod authors happy
|
||||
//
|
||||
if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
|
||||
/* get lighting information */
|
||||
if (currententity->flags &
|
||||
(RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED |
|
||||
RF_SHELL_BLUE | RF_SHELL_DOUBLE))
|
||||
{
|
||||
VectorClear (shadelight);
|
||||
VectorClear(shadelight);
|
||||
|
||||
if (currententity->flags & RF_SHELL_HALF_DAM)
|
||||
{
|
||||
shadelight[0] = 0.56;
|
||||
shadelight[1] = 0.59;
|
||||
shadelight[2] = 0.45;
|
||||
shadelight[0] = 0.56;
|
||||
shadelight[1] = 0.59;
|
||||
shadelight[2] = 0.45;
|
||||
}
|
||||
if ( currententity->flags & RF_SHELL_DOUBLE )
|
||||
|
||||
if (currententity->flags & RF_SHELL_DOUBLE)
|
||||
{
|
||||
shadelight[0] = 0.9;
|
||||
shadelight[1] = 0.7;
|
||||
}
|
||||
if ( currententity->flags & RF_SHELL_RED )
|
||||
|
||||
if (currententity->flags & RF_SHELL_RED)
|
||||
{
|
||||
shadelight[0] = 1.0;
|
||||
if ( currententity->flags & RF_SHELL_GREEN )
|
||||
}
|
||||
|
||||
if (currententity->flags & RF_SHELL_GREEN)
|
||||
{
|
||||
shadelight[1] = 1.0;
|
||||
if ( currententity->flags & RF_SHELL_BLUE )
|
||||
}
|
||||
|
||||
if (currententity->flags & RF_SHELL_BLUE)
|
||||
{
|
||||
shadelight[2] = 1.0;
|
||||
}
|
||||
}
|
||||
else if ( currententity->flags & RF_FULLBRIGHT )
|
||||
else if (currententity->flags & RF_FULLBRIGHT)
|
||||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
shadelight[i] = 1.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_LightPoint(currententity->origin, shadelight, currententity);
|
||||
|
||||
// player lighting hack for communication back to server
|
||||
// big hack!
|
||||
if ( currententity->flags & RF_WEAPONMODEL )
|
||||
if (r_worldmodel->grid)
|
||||
{
|
||||
// pick the greatest component, which should be the same
|
||||
// as the mono value returned by software
|
||||
BSPX_LightGridValue(r_worldmodel->grid, r_newrefdef.lightstyles,
|
||||
currententity->origin, shadelight);
|
||||
}
|
||||
else
|
||||
{
|
||||
R_LightPoint(currententity->origin, shadelight, currententity);
|
||||
}
|
||||
|
||||
/* player lighting hack for communication back to server */
|
||||
if (currententity->flags & RF_WEAPONMODEL)
|
||||
{
|
||||
/* pick the greatest component, which should be
|
||||
the same as the mono value returned by software */
|
||||
if (shadelight[0] > shadelight[1])
|
||||
{
|
||||
if (shadelight[0] > shadelight[2])
|
||||
r_lightlevel->value = 150*shadelight[0];
|
||||
{
|
||||
r_lightlevel->value = 150 * shadelight[0];
|
||||
}
|
||||
else
|
||||
r_lightlevel->value = 150*shadelight[2];
|
||||
{
|
||||
r_lightlevel->value = 150 * shadelight[2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shadelight[1] > shadelight[2])
|
||||
r_lightlevel->value = 150*shadelight[1];
|
||||
{
|
||||
r_lightlevel->value = 150 * shadelight[1];
|
||||
}
|
||||
else
|
||||
r_lightlevel->value = 150*shadelight[2];
|
||||
{
|
||||
r_lightlevel->value = 150 * shadelight[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( currententity->flags & RF_MINLIGHT )
|
||||
if (currententity->flags & RF_MINLIGHT)
|
||||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (shadelight[i] > 0.1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 3)
|
||||
{
|
||||
shadelight[0] = 0.1;
|
||||
|
@ -899,50 +940,49 @@ void R_DrawAliasModel (entity_t *currententity, model_t *currentmodel)
|
|||
}
|
||||
}
|
||||
|
||||
if ( currententity->flags & RF_GLOW )
|
||||
{ // bonus items will pulse with time
|
||||
float scale;
|
||||
if (currententity->flags & RF_GLOW)
|
||||
{
|
||||
/* bonus items will pulse with time */
|
||||
float scale;
|
||||
|
||||
scale = 0.1 * sin(r_newrefdef.time*7);
|
||||
for (i=0 ; i<3 ; i++)
|
||||
scale = 0.1 * sin(r_newrefdef.time * 7);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
float min;
|
||||
|
||||
min = shadelight[i] * 0.8;
|
||||
shadelight[i] += scale;
|
||||
|
||||
if (shadelight[i] < min)
|
||||
{
|
||||
shadelight[i] = min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================
|
||||
// PGM ir goggles color override
|
||||
if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
|
||||
/* ir goggles color override */
|
||||
if (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags &
|
||||
RF_IR_VISIBLE)
|
||||
{
|
||||
shadelight[0] = 1.0;
|
||||
shadelight[1] = 0.0;
|
||||
shadelight[2] = 0.0;
|
||||
}
|
||||
// PGM
|
||||
// =================
|
||||
|
||||
shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
|
||||
shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] *
|
||||
(SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
|
||||
|
||||
an = currententity->angles[1]/180*M_PI;
|
||||
an = currententity->angles[1] / 180 * M_PI;
|
||||
shadevector[0] = cos(-an);
|
||||
shadevector[1] = sin(-an);
|
||||
shadevector[2] = 1;
|
||||
VectorNormalize (shadevector);
|
||||
|
||||
//
|
||||
// locate the proper data
|
||||
//
|
||||
VectorNormalize(shadevector);
|
||||
|
||||
/* locate the proper data */
|
||||
c_alias_polys += paliashdr->num_tris;
|
||||
|
||||
//
|
||||
// draw all the triangles
|
||||
//
|
||||
/* draw all the triangles */
|
||||
if (currententity->flags & RF_DEPTHHACK || r_newrefdef.rdflags & RDF_NOWORLDMODEL) { // hack the depth range to prevent view model from poking into walls
|
||||
float r_proj_aspect = (float)r_newrefdef.width / r_newrefdef.height;
|
||||
float r_proj_fovy = r_newrefdef.fov_y;
|
||||
|
|
|
@ -23,19 +23,18 @@
|
|||
* Model loading and caching. Includes the .bsp file format
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include "header/local.h"
|
||||
|
||||
YQ2_ALIGNAS_TYPE(int) static byte mod_novis[MAX_MAP_LEAFS/8];
|
||||
static YQ2_ALIGNAS_TYPE(int) byte mod_novis[MAX_MAP_LEAFS / 8];
|
||||
|
||||
#define MAX_MOD_KNOWN 512
|
||||
static model_t *models_known;
|
||||
static int mod_numknown = 0;
|
||||
static int mod_loaded = 0;
|
||||
static int mod_max = 0;
|
||||
static int models_known_max = 0;
|
||||
#define MAX_MOD_KNOWN 512
|
||||
static model_t *models_known;
|
||||
static int mod_numknown = 0;
|
||||
static int mod_max = 0;
|
||||
static int mod_loaded = 0;
|
||||
static int models_known_max = 0;
|
||||
|
||||
int registration_sequence;
|
||||
|
||||
|
@ -160,7 +159,7 @@ Mod_LoadSubmodels(model_t *loadmodel, const byte *mod_base, const lump_t *l)
|
|||
* Fills in s->texturemins[] and s->extents[]
|
||||
*/
|
||||
static void
|
||||
CalcSurfaceExtents(model_t *loadmodel, msurface_t *s)
|
||||
Mod_CalcSurfaceExtents(model_t *loadmodel, msurface_t *s)
|
||||
{
|
||||
float mins[2], maxs[2], val;
|
||||
int i;
|
||||
|
@ -510,7 +509,7 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
|
|||
out->lmvlen[0] = 1.0f;
|
||||
out->lmvlen[1] = 1.0f;
|
||||
|
||||
CalcSurfaceExtents(loadmodel, out);
|
||||
Mod_CalcSurfaceExtents(loadmodel, out);
|
||||
|
||||
lightofs = in->lightofs;
|
||||
}
|
||||
|
@ -633,7 +632,7 @@ Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
|
|||
out->lmvlen[0] = 1.0f;
|
||||
out->lmvlen[1] = 1.0f;
|
||||
|
||||
CalcSurfaceExtents(loadmodel, out);
|
||||
Mod_CalcSurfaceExtents(loadmodel, out);
|
||||
|
||||
lightofs = in->lightofs;
|
||||
}
|
||||
|
@ -900,6 +899,9 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
|
|||
((int *)header)[i] = LittleLong(((int *)header)[i]);
|
||||
}
|
||||
|
||||
/* check for BSPX extensions */
|
||||
bspx_header = Mod_LoadBSPX(modfilelen, (byte*)header);
|
||||
|
||||
// calculate the needed hunksize from the lumps
|
||||
int hunkSize = 0;
|
||||
hunkSize += calcLumpHunkSize(&header->lumps[LUMP_VERTEXES], sizeof(dvertex_t), sizeof(mvertex_t));
|
||||
|
@ -943,8 +945,10 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
|
|||
mod->extradata = Hunk_Begin(hunkSize);
|
||||
mod->type = mod_brush;
|
||||
|
||||
/* check for BSPX extensions */
|
||||
bspx_header = Mod_LoadBSPX(modfilelen, (byte*)header);
|
||||
if (bspx_header)
|
||||
{
|
||||
mod->grid = BSPX_LightGridLoad(bspx_header, mod_base);
|
||||
}
|
||||
|
||||
/* load into heap */
|
||||
Mod_LoadVertexes(mod->name, &mod->vertexes, &mod->numvertexes, mod_base,
|
||||
|
@ -996,69 +1000,73 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
|
|||
mod->numframes = 2; /* regular and alternate animation */
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
==================
|
||||
Mod_ForName
|
||||
|
||||
Loads in a model for the given name
|
||||
==================
|
||||
*/
|
||||
* Loads in a model for the given name
|
||||
*/
|
||||
static model_t *
|
||||
Mod_ForName (const char *name, model_t *parent_model, qboolean crash)
|
||||
Mod_ForName(const char *name, model_t *parent_model, qboolean crash)
|
||||
{
|
||||
model_t *mod;
|
||||
void *buf;
|
||||
int i, modfilelen;
|
||||
model_t *mod;
|
||||
void *buf;
|
||||
int i, modfilelen;
|
||||
|
||||
if (!name[0])
|
||||
{
|
||||
ri.Sys_Error(ERR_DROP, "%s: NULL name", __func__);
|
||||
}
|
||||
|
||||
//
|
||||
// inline models are grabbed only from worldmodel
|
||||
//
|
||||
/* inline models are grabbed only from worldmodel */
|
||||
if (name[0] == '*' && parent_model)
|
||||
{
|
||||
i = atoi(name+1);
|
||||
i = (int)strtol(name + 1, (char **)NULL, 10);
|
||||
|
||||
if (i < 1 || i >= parent_model->numsubmodels)
|
||||
ri.Sys_Error (ERR_DROP, "bad inline model number");
|
||||
{
|
||||
ri.Sys_Error(ERR_DROP, "%s: bad inline model number",
|
||||
__func__);
|
||||
}
|
||||
|
||||
return &parent_model->submodels[i];
|
||||
}
|
||||
|
||||
//
|
||||
// search the currently loaded models
|
||||
//
|
||||
for (i=0 , mod=models_known ; i<mod_numknown ; i++, mod++)
|
||||
/* search the currently loaded models */
|
||||
for (i = 0, mod = models_known; i < mod_numknown; i++, mod++)
|
||||
{
|
||||
if (!mod->name[0])
|
||||
{
|
||||
continue;
|
||||
if (!strcmp (mod->name, name) )
|
||||
}
|
||||
|
||||
if (!strcmp(mod->name, name))
|
||||
{
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// find a free model slot spot
|
||||
//
|
||||
for (i=0 , mod=models_known ; i<mod_numknown ; i++, mod++)
|
||||
/* find a free model slot spot */
|
||||
for (i = 0, mod = models_known; i < mod_numknown; i++, mod++)
|
||||
{
|
||||
if (!mod->name[0])
|
||||
break; // free spot
|
||||
{
|
||||
break; /* free spot */
|
||||
}
|
||||
}
|
||||
|
||||
if (i == mod_numknown)
|
||||
{
|
||||
if (mod_numknown == models_known_max)
|
||||
{
|
||||
ri.Sys_Error(ERR_DROP, "%s: mod_numknown == models_known_max", __func__);
|
||||
}
|
||||
|
||||
mod_numknown++;
|
||||
}
|
||||
strcpy (mod->name, name);
|
||||
|
||||
//
|
||||
// load the file
|
||||
//
|
||||
strcpy(mod->name, name);
|
||||
|
||||
/* load the file */
|
||||
modfilelen = Mod_LoadFile (mod->name, &buf);
|
||||
|
||||
if (!buf)
|
||||
{
|
||||
if (crash)
|
||||
|
@ -1071,7 +1079,8 @@ Mod_ForName (const char *name, model_t *parent_model, qboolean crash)
|
|||
{
|
||||
R_Printf(PRINT_ALL, "%s: Can't load %s\n", __func__, mod->name);
|
||||
}
|
||||
memset (mod->name, 0, sizeof(mod->name));
|
||||
|
||||
memset(mod->name, 0, sizeof(mod->name));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1086,59 +1095,58 @@ Mod_ForName (const char *name, model_t *parent_model, qboolean crash)
|
|||
// fill it in
|
||||
//
|
||||
|
||||
// call the apropriate loader
|
||||
|
||||
/* call the apropriate loader */
|
||||
switch (LittleLong(*(unsigned *)buf))
|
||||
{
|
||||
case DKMHEADER:
|
||||
/* fall through */
|
||||
case RAVENFMHEADER:
|
||||
/* fall through */
|
||||
case IDALIASHEADER:
|
||||
/* fall through */
|
||||
case IDMDLHEADER:
|
||||
{
|
||||
mod->extradata = Mod_LoadAliasModel(mod->name, buf, modfilelen,
|
||||
mod->mins, mod->maxs,
|
||||
(struct image_s **)mod->skins, (findimage_t)Vk_FindImage,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
case DKMHEADER:
|
||||
/* fall through */
|
||||
case RAVENFMHEADER:
|
||||
/* fall through */
|
||||
case IDALIASHEADER:
|
||||
/* fall through */
|
||||
case IDMDLHEADER:
|
||||
{
|
||||
ri.Sys_Error(ERR_DROP, "%s: Failed to load %s",
|
||||
__func__, mod->name);
|
||||
}
|
||||
};
|
||||
break;
|
||||
mod->extradata = Mod_LoadAliasModel(mod->name, buf, modfilelen,
|
||||
mod->mins, mod->maxs,
|
||||
(struct image_s **)mod->skins, (findimage_t)Vk_FindImage,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
{
|
||||
ri.Sys_Error(ERR_DROP, "%s: Failed to load %s",
|
||||
__func__, mod->name);
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
case IDSPRITEHEADER:
|
||||
{
|
||||
mod->extradata = Mod_LoadSP2(mod->name, buf, modfilelen,
|
||||
(struct image_s **)mod->skins, (findimage_t)Vk_FindImage,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
case IDSPRITEHEADER:
|
||||
{
|
||||
ri.Sys_Error(ERR_DROP, "%s: Failed to load %s",
|
||||
__func__, mod->name);
|
||||
mod->extradata = Mod_LoadSP2(mod->name, buf, modfilelen,
|
||||
(struct image_s **)mod->skins, (findimage_t)Vk_FindImage,
|
||||
&(mod->type));
|
||||
if (!mod->extradata)
|
||||
{
|
||||
ri.Sys_Error(ERR_DROP, "%s: Failed to load %s",
|
||||
__func__, mod->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case IDBSPHEADER:
|
||||
/* fall through */
|
||||
case QBSPHEADER:
|
||||
Mod_LoadBrushModel(mod, buf, modfilelen);
|
||||
break;
|
||||
case IDBSPHEADER:
|
||||
/* fall through */
|
||||
case QBSPHEADER:
|
||||
Mod_LoadBrushModel(mod, buf, modfilelen);
|
||||
break;
|
||||
|
||||
default:
|
||||
ri.Sys_Error(ERR_DROP, "%s: unknown fileid for %s",
|
||||
__func__, mod->name);
|
||||
break;
|
||||
default:
|
||||
ri.Sys_Error(ERR_DROP, "%s: unknown fileid for %s",
|
||||
__func__, mod->name);
|
||||
break;
|
||||
}
|
||||
|
||||
mod->radius = Mod_RadiusFromBounds(mod->mins, mod->maxs);
|
||||
if (mod->extradata)
|
||||
{
|
||||
mod->extradatasize = Hunk_End ();
|
||||
mod->extradatasize = Hunk_End();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1165,8 +1173,8 @@ Mod_Free(model_t *mod)
|
|||
R_Printf(PRINT_ALL, "%s: Unload %s[%d]\n", __func__, mod->name, mod_loaded);
|
||||
}
|
||||
|
||||
Hunk_Free (mod->extradata);
|
||||
memset (mod, 0, sizeof(*mod));
|
||||
Hunk_Free(mod->extradata);
|
||||
memset(mod, 0, sizeof(*mod));
|
||||
mod_loaded --;
|
||||
if (mod_loaded < 0)
|
||||
{
|
||||
|
@ -1175,19 +1183,21 @@ Mod_Free(model_t *mod)
|
|||
}
|
||||
|
||||
void
|
||||
Mod_FreeAll (void)
|
||||
Mod_FreeAll(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<mod_numknown ; i++)
|
||||
for (i = 0; i < mod_numknown; i++)
|
||||
{
|
||||
if (models_known[i].extradatasize)
|
||||
Mod_Free (&models_known[i]);
|
||||
{
|
||||
Mod_Free(&models_known[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Mod_FreeModelsKnown (void)
|
||||
Mod_FreeModelsKnown(void)
|
||||
{
|
||||
free(models_known);
|
||||
models_known = NULL;
|
||||
|
@ -1197,7 +1207,7 @@ Mod_FreeModelsKnown (void)
|
|||
* Specifies the model that will be used as the world
|
||||
*/
|
||||
void
|
||||
RE_BeginRegistration (const char *model)
|
||||
RE_BeginRegistration(const char *model)
|
||||
{
|
||||
char fullname[MAX_QPATH];
|
||||
cvar_t *flushmap;
|
||||
|
@ -1321,10 +1331,10 @@ Mod_Modellist_f (void)
|
|||
}
|
||||
|
||||
void
|
||||
RE_EndRegistration (void)
|
||||
RE_EndRegistration(void)
|
||||
{
|
||||
int i;
|
||||
model_t *mod;
|
||||
int i;
|
||||
model_t *mod;
|
||||
|
||||
if (Mod_HasFreeSpace() && Vk_ImageHasFreeSpace())
|
||||
{
|
||||
|
@ -1346,5 +1356,5 @@ RE_EndRegistration (void)
|
|||
}
|
||||
}
|
||||
|
||||
Vk_FreeUnusedImages ();
|
||||
Vk_FreeUnusedImages();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue