Gave terrain limited thickness, re-added support for holes with clipping.
fixed potential vid_restart/particle crash. fixed a win32 consize resize bug when alt-tabbing. added a hack to assume stepping behaviour for monsters on mvdsv servers. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4085 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
60d490fce6
commit
f15532d525
6 changed files with 296 additions and 254 deletions
|
@ -433,6 +433,11 @@ void CLQW_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboole
|
|||
if (i & RENDER_EXTERIORMODEL)
|
||||
to->flags |= Q2RF_EXTERNALMODEL;
|
||||
}
|
||||
if (!(cls.fteprotocolextensions & PEXT_DPFLAGS))
|
||||
{
|
||||
if (to->frame)
|
||||
to->dpflags |= RENDER_STEP;
|
||||
}
|
||||
if (morebits & U_TAGINFO)
|
||||
{
|
||||
to->tagentity = MSG_ReadShort();
|
||||
|
@ -878,7 +883,7 @@ void CL_ParsePacketEntities (qboolean delta)
|
|||
{
|
||||
cl.oldgametime = cl.gametime;
|
||||
cl.oldgametimemark = cl.gametimemark;
|
||||
cl.gametime = realtime;
|
||||
cl.gametime = realtime;//cl.frames[newpacket].senttime - cl.frames[(newpacket-1)&UPDATE_MASK].senttime;
|
||||
cl.gametimemark = realtime;
|
||||
}
|
||||
|
||||
|
@ -2857,6 +2862,18 @@ void CL_LinkPacketEntities (void)
|
|||
CLQ1_AddShadow(ent);
|
||||
CLQ1_AddPowerupShell(ent, false, state->effects);
|
||||
|
||||
if (r_torch.ival && ent->keynum <= cl.allocated_client_slots)
|
||||
{
|
||||
dlight_t *dl;
|
||||
dl = CL_NewDlight(ent->keynum, ent->origin, 300, r_torch.ival, 0.9, 0.9, 0.6);
|
||||
dl->flags |= LFLAG_SHADOWMAP|LFLAG_FLASHBLEND;
|
||||
dl->fov = 90;
|
||||
angles[0] *= 3;
|
||||
// angles[1] += sin(realtime)*8;
|
||||
// angles[0] += cos(realtime*1.13)*5;
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
}
|
||||
|
||||
// add automatic particle trails
|
||||
if (!model || (!(model->flags&~MF_ROTATE) && model->particletrail<0 && model->particleeffect<0 && state->u.q1.traileffectnum==0))
|
||||
continue;
|
||||
|
|
|
@ -662,8 +662,8 @@ void CL_CalcClientTime(void)
|
|||
|
||||
oldst = cl.servertime;
|
||||
|
||||
max = cl.gametime;// - 5;
|
||||
min = cl.oldgametime;// - 5;
|
||||
max = cl.gametime;
|
||||
min = cl.oldgametime;
|
||||
|
||||
cl.servertime += host_frametime;
|
||||
|
||||
|
@ -1028,7 +1028,10 @@ fixedorg:
|
|||
if (cl.gametime == cl.servertime)
|
||||
f = 0;
|
||||
else
|
||||
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);//f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
|
||||
{
|
||||
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);
|
||||
//f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
|
||||
}
|
||||
if (f<0)
|
||||
f=0;
|
||||
if (f>1)
|
||||
|
@ -1039,8 +1042,8 @@ fixedorg:
|
|||
// calculate origin
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
lrp[i] = to->playerstate[cl.playernum[pnum]].origin[i] +
|
||||
f * (from->playerstate[cl.playernum[pnum]].origin[i] - to->playerstate[cl.playernum[pnum]].origin[i]);
|
||||
lrp[i] = to->playerstate[spec_track[pnum]].origin[i] +
|
||||
f * (from->playerstate[spec_track[pnum]].origin[i] - to->playerstate[cl.playernum[pnum]].origin[i]);
|
||||
|
||||
lrpv[i] = to->playerstate[spec_track[pnum]].velocity[i] +
|
||||
f * (from->playerstate[spec_track[pnum]].velocity[i] - to->playerstate[spec_track[pnum]].velocity[i]);
|
||||
|
|
|
@ -172,6 +172,7 @@ void P_InitParticleSystem(void)
|
|||
|
||||
void P_Shutdown(void)
|
||||
{
|
||||
CL_ClearLerpEntsParticleState();
|
||||
if (pe)
|
||||
{
|
||||
pe->ShutdownParticles();
|
||||
|
|
|
@ -338,6 +338,7 @@ cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shado
|
|||
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
|
||||
cvar_t r_shadow_shadowmapping = SCVARF ("debug_r_shadow_shadowmapping", "0", 0);
|
||||
cvar_t r_sun_dir = SCVAR ("r_sun_dir", "0.2 0.5 0.8");
|
||||
cvar_t r_sun_colour = SCVARF ("r_sun_colour", "0 0 0", CVAR_ARCHIVE);
|
||||
cvar_t r_waterstyle = CVARF ("r_waterstyle", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
|
||||
|
@ -590,6 +591,7 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&r_shadow_realtime_dlight, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_shadow_realtime_dlight_shadows, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_shadow_realtime_world_lightmaps, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_shadow_shadowmapping, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_sun_dir, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_sun_colour, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_waterstyle, GRAPHICALNICETIES);
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include "pr_common.h"
|
||||
|
||||
//#define STRICTEDGES //strict (ugly) grid
|
||||
#define TERRAINTHICKNESS 16
|
||||
|
||||
//heightmaps work thusly:
|
||||
//there is one raw heightmap file
|
||||
//the file is split to 4*4 sections.
|
||||
|
@ -134,7 +137,25 @@ typedef struct heightmap_s {
|
|||
static void ted_dorelight(heightmap_t *hm);
|
||||
|
||||
|
||||
|
||||
#ifndef SERVERONLY
|
||||
static texid_t Terr_LoadTexture(char *name)
|
||||
{
|
||||
extern texid_t missing_texture;
|
||||
texid_t id;
|
||||
if (*name)
|
||||
{
|
||||
id = R_LoadHiResTexture(name, NULL, 0);
|
||||
if (!TEXVALID(id))
|
||||
{
|
||||
id = missing_texture;
|
||||
Con_Printf("Unable to load texture %s\n", name);
|
||||
}
|
||||
}
|
||||
else
|
||||
id = missing_texture;
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Terr_LoadSectionTextures(hmsection_t *s)
|
||||
{
|
||||
|
@ -144,10 +165,10 @@ static void Terr_LoadSectionTextures(hmsection_t *s)
|
|||
//CL_CheckOrEnqueDownloadFile(s->texname[1], NULL, 0);
|
||||
//CL_CheckOrEnqueDownloadFile(s->texname[2], NULL, 0);
|
||||
//CL_CheckOrEnqueDownloadFile(s->texname[3], NULL, 0);
|
||||
s->textures.base = *s->texname[0]?R_LoadHiResTexture(s->texname[0], NULL, 0):missing_texture;
|
||||
s->textures.upperoverlay = *s->texname[1]?R_LoadHiResTexture(s->texname[1], NULL, 0):missing_texture;
|
||||
s->textures.loweroverlay = *s->texname[2]?R_LoadHiResTexture(s->texname[2], NULL, 0):missing_texture;
|
||||
s->textures.fullbright = *s->texname[3]?R_LoadHiResTexture(s->texname[3], NULL, 0):missing_texture;
|
||||
s->textures.base = Terr_LoadTexture(s->texname[0]);
|
||||
s->textures.upperoverlay = Terr_LoadTexture(s->texname[1]);
|
||||
s->textures.loweroverlay = Terr_LoadTexture(s->texname[2]);
|
||||
s->textures.fullbright = Terr_LoadTexture(s->texname[3]);
|
||||
s->textures.bump = *s->texname[0]?R_LoadHiResTexture(va("%s_norm", s->texname[0]), NULL, 0):r_nulltex;
|
||||
s->textures.specular = *s->texname[0]?R_LoadHiResTexture(va("%s_spec", s->texname[0]), NULL, 0):r_nulltex;
|
||||
#endif
|
||||
|
@ -293,7 +314,10 @@ static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, in
|
|||
#ifndef SERVERONLY
|
||||
s->numents = ds->numents;
|
||||
s->maxents = s->numents;
|
||||
if (s->maxents)
|
||||
s->ents = malloc(sizeof(*s->ents) * s->maxents);
|
||||
else
|
||||
s->ents = NULL;
|
||||
if (!s->ents)
|
||||
s->numents = s->maxents = 0;
|
||||
memset(s->ents, 0, sizeof(*s->ents) * s->maxents);
|
||||
|
@ -416,18 +440,19 @@ static hmsection_t *Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, in
|
|||
return s;
|
||||
}
|
||||
|
||||
static void Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy)
|
||||
static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy)
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
dsection_t ds;
|
||||
dsmesh_t dm;
|
||||
char *fname;
|
||||
unsigned char *lm;
|
||||
vfsfile_t *f;
|
||||
int nothing = 0;
|
||||
int i;
|
||||
//if its invalid or doesn't contain all the data...
|
||||
if (!s || s->lightmap < 0)
|
||||
return;
|
||||
return true;
|
||||
|
||||
memset(&ds, 0, sizeof(ds));
|
||||
memset(&dm, 0, sizeof(dm));
|
||||
|
@ -465,7 +490,15 @@ static void Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy)
|
|||
ds.numents = s->numents;
|
||||
ds.entsofs = sizeof(ds);
|
||||
|
||||
f = FS_OpenVFS(Terr_DiskSectionName(hm, sx, sy), "wb", FS_GAMEONLY);
|
||||
fname = Terr_DiskSectionName(hm, sx, sy);
|
||||
FS_CreatePath(fname, FS_GAMEONLY);
|
||||
|
||||
f = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf("Failed to open %s\n", fname);
|
||||
return false;
|
||||
}
|
||||
VFS_WRITE(f, &ds, sizeof(ds));
|
||||
for (i = 0; i < s->numents; i++)
|
||||
{
|
||||
|
@ -490,6 +523,7 @@ static void Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy)
|
|||
}
|
||||
VFS_CLOSE(f);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*convienience function*/
|
||||
|
@ -540,13 +574,15 @@ int HeightMap_Save(heightmap_t *hm)
|
|||
if (!s)
|
||||
continue;
|
||||
if (s->flags & TSF_EDITED)
|
||||
{
|
||||
if (Terr_SaveSection(hm, s, x, y))
|
||||
{
|
||||
s->flags &= ~TSF_EDITED;
|
||||
Terr_SaveSection(hm, s, x, y);
|
||||
sectionssaved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sectionssaved;
|
||||
}
|
||||
|
@ -574,6 +610,7 @@ void Terr_DestroySection(heightmap_t *hm, hmsection_t *s)
|
|||
}
|
||||
#endif
|
||||
|
||||
free(s->ents);
|
||||
free(s->mesh.xyz_array);
|
||||
free(s->mesh.indexes);
|
||||
#endif
|
||||
|
@ -797,7 +834,10 @@ void Terr_RebuildMesh(hmsection_t *s, int x, int y)
|
|||
{
|
||||
for (vy = 0; vy < SECTHEIGHTSIZE-1; vy++)
|
||||
{
|
||||
#ifndef STRICTEDGES
|
||||
float d1,d2;
|
||||
#endif
|
||||
|
||||
#if SECTHEIGHTSIZE >= 4
|
||||
int holebit;
|
||||
|
||||
|
@ -809,9 +849,9 @@ void Terr_RebuildMesh(hmsection_t *s, int x, int y)
|
|||
#endif
|
||||
v = vx + vy*(SECTHEIGHTSIZE);
|
||||
|
||||
#ifndef STRICTEDGES
|
||||
d1 = fabs(mesh->xyz_array[v][2] - mesh->xyz_array[v+1+SECTHEIGHTSIZE][2]);
|
||||
d2 = fabs(mesh->xyz_array[v+1][2] - mesh->xyz_array[v+SECTHEIGHTSIZE][2]);
|
||||
#if 1
|
||||
if (d1 < d2)
|
||||
{
|
||||
mesh->indexes[mesh->numindexes++] = v+0;
|
||||
|
@ -821,8 +861,8 @@ void Terr_RebuildMesh(hmsection_t *s, int x, int y)
|
|||
mesh->indexes[mesh->numindexes++] = v+1+SECTHEIGHTSIZE;
|
||||
mesh->indexes[mesh->numindexes++] = v+SECTHEIGHTSIZE;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
#endif
|
||||
{
|
||||
mesh->indexes[mesh->numindexes++] = v+0;
|
||||
mesh->indexes[mesh->numindexes++] = v+1;
|
||||
|
@ -1198,115 +1238,37 @@ typedef struct {
|
|||
int contents;
|
||||
} hmtrace_t;
|
||||
|
||||
//sx,sy are the tile coord
|
||||
//note that tile SECTHEIGHTSIZE-1 does not exist, as the last sample overlaps the first sample of the next section
|
||||
void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
|
||||
static void Heightmap_Trace_Brush(hmtrace_t *tr, vec4_t *planes, int numplanes)
|
||||
{
|
||||
vec3_t d[2];
|
||||
vec3_t p[4];
|
||||
vec4_t n[5];
|
||||
int t, i;
|
||||
|
||||
qboolean startout, endout;
|
||||
qboolean startout;
|
||||
float *enterplane;
|
||||
float enterfrac, exitfrac, nearfrac=0;
|
||||
float enterdist=0;
|
||||
float dist, d1, d2, f;
|
||||
int sx, sy;
|
||||
hmsection_t *s;
|
||||
|
||||
if (tx < 0 || tx >= CHUNKLIMIT*(SECTHEIGHTSIZE-1))
|
||||
return;
|
||||
if (ty < 0 || ty >= CHUNKLIMIT*(SECTHEIGHTSIZE-1))
|
||||
return;
|
||||
s = Terr_GetSection(tr->hm, tx/(SECTHEIGHTSIZE-1), ty/(SECTHEIGHTSIZE-1), true);
|
||||
|
||||
sx = tx;
|
||||
sy = ty;
|
||||
|
||||
tx = tx % (SECTHEIGHTSIZE-1);
|
||||
ty = ty % (SECTHEIGHTSIZE-1);
|
||||
|
||||
VectorSet(p[0], tr->htilesize*(sx+0), tr->htilesize*(sy+0), s->heights[(tx+0)+(ty+0)*SECTHEIGHTSIZE]);
|
||||
VectorSet(p[1], tr->htilesize*(sx+1), tr->htilesize*(sy+0), s->heights[(tx+1)+(ty+0)*SECTHEIGHTSIZE]);
|
||||
VectorSet(p[2], tr->htilesize*(sx+0), tr->htilesize*(sy+1), s->heights[(tx+0)+(ty+1)*SECTHEIGHTSIZE]);
|
||||
VectorSet(p[3], tr->htilesize*(sx+1), tr->htilesize*(sy+1), s->heights[(tx+1)+(ty+1)*SECTHEIGHTSIZE]);
|
||||
// DebugDrawQuadH(p[0][0], p[0][1], p[3][0], p[3][1], p[0][2], 0, 0, 0.2);
|
||||
|
||||
for (t = 0; t < 2; t++)
|
||||
{
|
||||
/*generate the brush (in world space*/
|
||||
if (t == 0)
|
||||
{
|
||||
// continue;
|
||||
VectorSubtract(p[1], p[0], d[0]);
|
||||
VectorSubtract(p[2], p[0], d[1]);
|
||||
//left-most
|
||||
Vector4Set(n[0], -1, 0, 0, -tr->htilesize*(sx+0));
|
||||
//top-most
|
||||
Vector4Set(n[1], 0, -1, 0, -tr->htilesize*(sy+0));
|
||||
//bottom-right
|
||||
VectorSet(n[2], 0.70710678118654752440084436210485, 0.70710678118654752440084436210485, 0);
|
||||
n[2][3] = DotProduct(n[2], p[1]);
|
||||
//top
|
||||
VectorNormalize(d[0]);
|
||||
VectorNormalize(d[1]);
|
||||
CrossProduct(d[0], d[1], n[3]);
|
||||
VectorNormalize(n[3]);
|
||||
n[3][3] = DotProduct(n[3], p[1]);
|
||||
//down
|
||||
Vector4Set(n[4], 0, 0, -1, 0);
|
||||
n[4][3] = DotProduct(n[3], p[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// continue;
|
||||
VectorSubtract(p[3], p[2], d[0]);
|
||||
VectorSubtract(p[3], p[1], d[1]);
|
||||
|
||||
//right-most
|
||||
Vector4Set(n[0], 1, 0, 0, tr->htilesize*(sx+1));
|
||||
//bottom-most
|
||||
Vector4Set(n[1], 0, 1, 0, tr->htilesize*(sy+1));
|
||||
//top-left
|
||||
VectorSet(n[2], -0.70710678118654752440084436210485, -0.70710678118654752440084436210485, 0);
|
||||
n[2][3] = DotProduct(n[2], p[1]);
|
||||
//top
|
||||
VectorNormalize(d[0]);
|
||||
VectorNormalize(d[1]);
|
||||
CrossProduct(d[0], d[1], n[3]);
|
||||
VectorNormalize(n[3]);
|
||||
n[3][3] = DotProduct(n[3], p[1]);
|
||||
//down
|
||||
Vector4Set(n[4], 0, 0, -1, 0);
|
||||
n[4][3] = DotProduct(n[3], p[1]);
|
||||
}
|
||||
double enterfrac, exitfrac, nearfrac=0;
|
||||
double enterdist=0;
|
||||
double dist, d1, d2, f;
|
||||
int i;
|
||||
|
||||
startout = false;
|
||||
endout = false;
|
||||
enterplane= NULL;
|
||||
enterfrac = -1;
|
||||
exitfrac = 10;
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < numplanes; i++)
|
||||
{
|
||||
/*calculate the distance based upon the shape of the object we're tracing for*/
|
||||
dist = n[i][3];
|
||||
dist = planes[i][3];
|
||||
|
||||
|
||||
d1 = DotProduct (tr->start, n[i]) - dist;
|
||||
d2 = DotProduct (tr->end, n[i]) - dist;
|
||||
d1 = DotProduct (tr->start, planes[i]) - dist;
|
||||
d2 = DotProduct (tr->end, planes[i]) - dist;
|
||||
|
||||
//if we're fully outside any plane, then we cannot possibly enter the brush, skip to the next one
|
||||
if (d1 > 0 && d2 >= d1)
|
||||
goto nextbrush;
|
||||
|
||||
if (d1 > 0)
|
||||
startout = true;
|
||||
if (d2 > 0)
|
||||
endout = true;
|
||||
|
||||
//if we're fully outside any plane, then we cannot possibly enter the brush, skip to the next one
|
||||
if (d1 > 0 && d2 >= 0)
|
||||
goto nextbrush;
|
||||
|
||||
//if we're fully inside the plane, then whatever is happening is not relevent for this plane
|
||||
if (d1 < 0 && d2 <= 0)
|
||||
if (d1 <= 0 && d2 <= 0)
|
||||
continue;
|
||||
|
||||
f = (d1) / (d1-d2);
|
||||
|
@ -1317,7 +1279,7 @@ void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
|
|||
{
|
||||
enterfrac = f;
|
||||
nearfrac = (d1 - (0.03125)) / (d1-d2);
|
||||
enterplane = n[i];
|
||||
enterplane = planes[i];
|
||||
enterdist = dist;
|
||||
}
|
||||
}
|
||||
|
@ -1351,83 +1313,150 @@ void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
|
|||
nextbrush:
|
||||
;
|
||||
}
|
||||
#if 0
|
||||
float normf = 0.70710678118654752440084436210485;
|
||||
float pd, sd, ed, bd;
|
||||
int tris, x, y;
|
||||
vec3_t closest;
|
||||
vec3_t point;
|
||||
|
||||
//sx,sy are the tile coord
|
||||
//note that tile SECTHEIGHTSIZE-1 does not exist, as the last sample overlaps the first sample of the next section
|
||||
static void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
|
||||
{
|
||||
vec3_t d[2];
|
||||
vec3_t p[4];
|
||||
vec4_t n[5];
|
||||
int t;
|
||||
|
||||
pd = normf*(x+y);
|
||||
sd = normf*tr->start[0]+normf*tr->start[1];
|
||||
ed = normf*tr->end[0]+normf*tr->end[1];
|
||||
bd = normf*tr->maxs[0]+normf*tr->maxs[1]; //assume mins is this but negative
|
||||
//see which of the two triangles in the square it travels over.
|
||||
|
||||
tris = 0;
|
||||
if (sd<=pd || ed<=pd)
|
||||
tris |= 1;
|
||||
if (sd>=pd || ed>=pd)
|
||||
tris |= 2;
|
||||
|
||||
point[0] = sx+1;
|
||||
point[1] = sy;
|
||||
point[2] = s->heights[sx+1+sy*tr->hm->terrainsize];
|
||||
|
||||
if (tris & 1)
|
||||
{ //triangle with 0, 0
|
||||
vec3_t norm;
|
||||
float d1, d2, dc;
|
||||
|
||||
x = tr->hm->heights[(sx+1)+(sy+0)*tr->hm->terrainsize] - tr->hm->heights[(sx+0)+(sy+0)*tr->hm->terrainsize];
|
||||
y = tr->hm->heights[(sx+0)+(sy+1)*tr->hm->terrainsize] - tr->hm->heights[(sx+0)+(sy+0)*tr->hm->terrainsize];
|
||||
|
||||
norm[0] = (-x)/tr->hm->terrainscale;
|
||||
norm[1] = (-y)/tr->hm->terrainscale;
|
||||
norm[2] = 1.0f/(float)sqrt(norm[0]*norm[0] + norm[1]*norm[1] + 1);
|
||||
Closest(closest, norm, tr->mins, tr->maxs);
|
||||
dc = DotProduct(norm, closest) - DotProduct(norm, point);
|
||||
d1 = DotProduct(norm, tr->start) + dc;
|
||||
d2 = DotProduct(norm, tr->end) + dc;
|
||||
|
||||
if (d1>=0 && d2<=0)
|
||||
{ //intersects
|
||||
tr->contents = FTECONTENTS_SOLID;
|
||||
|
||||
d1 = (d1-d2)/(d1+d2);
|
||||
d2 = 1-d1;
|
||||
|
||||
tr->impact[0] = tr->end[0]*d1+tr->start[0]*d2;
|
||||
tr->impact[1] = tr->end[1]*d1+tr->start[1]*d2;
|
||||
tr->impact[2] = tr->end[2]*d1+tr->start[2]*d2;
|
||||
}
|
||||
}
|
||||
if (tris & 2)
|
||||
{ //triangle with 1, 1
|
||||
vec3_t norm;
|
||||
float d1, d2, dc;
|
||||
norm[0] = (-x)/tr->hm->terrainscale;
|
||||
norm[1] = (-y)/tr->hm->terrainscale;
|
||||
norm[2] = 1.0f/(float)sqrt(norm[0]*norm[0] + norm[1]*norm[1] + 1);
|
||||
Closest(closest, norm, tr->mins, tr->maxs);
|
||||
dc = DotProduct(norm, closest) - DotProduct(norm, point);
|
||||
d1 = DotProduct(norm, tr->start) + dc;
|
||||
d2 = DotProduct(norm, tr->end) + dc;
|
||||
|
||||
if (d1>=0 && d2<=0)
|
||||
{ //intersects
|
||||
tr->contents = FTECONTENTS_SOLID;
|
||||
|
||||
d1 = (d1-d2)/(d1+d2);
|
||||
d2 = 1-d1;
|
||||
|
||||
tr->impact[0] = tr->end[0]*d1+tr->start[0]*d2;
|
||||
tr->impact[1] = tr->end[1]*d1+tr->start[1]*d2;
|
||||
tr->impact[2] = tr->end[2]*d1+tr->start[2]*d2;
|
||||
}
|
||||
}
|
||||
#ifndef STRICTEDGES
|
||||
float d1, d2;
|
||||
#endif
|
||||
int sx, sy;
|
||||
hmsection_t *s;
|
||||
unsigned int holebit;
|
||||
|
||||
if (tx < 0 || tx >= CHUNKLIMIT*(SECTHEIGHTSIZE-1))
|
||||
return;
|
||||
if (ty < 0 || ty >= CHUNKLIMIT*(SECTHEIGHTSIZE-1))
|
||||
return;
|
||||
s = Terr_GetSection(tr->hm, tx/(SECTHEIGHTSIZE-1), ty/(SECTHEIGHTSIZE-1), true);
|
||||
|
||||
sx = tx - CHUNKBIAS*(SECTHEIGHTSIZE-1);
|
||||
sy = ty - CHUNKBIAS*(SECTHEIGHTSIZE-1);
|
||||
|
||||
tx = tx % (SECTHEIGHTSIZE-1);
|
||||
ty = ty % (SECTHEIGHTSIZE-1);
|
||||
|
||||
holebit = 1u<<(tx/(SECTHEIGHTSIZE>>2) + (ty/(SECTHEIGHTSIZE>>2))*4);
|
||||
if (!s || (s->holes & holebit))
|
||||
return; //no collision with holes
|
||||
|
||||
VectorSet(p[0], tr->htilesize*(sx+0), tr->htilesize*(sy+0), s->heights[(tx+0)+(ty+0)*SECTHEIGHTSIZE]);
|
||||
VectorSet(p[1], tr->htilesize*(sx+1), tr->htilesize*(sy+0), s->heights[(tx+1)+(ty+0)*SECTHEIGHTSIZE]);
|
||||
VectorSet(p[2], tr->htilesize*(sx+0), tr->htilesize*(sy+1), s->heights[(tx+0)+(ty+1)*SECTHEIGHTSIZE]);
|
||||
VectorSet(p[3], tr->htilesize*(sx+1), tr->htilesize*(sy+1), s->heights[(tx+1)+(ty+1)*SECTHEIGHTSIZE]);
|
||||
|
||||
#ifndef STRICTEDGES
|
||||
d1 = fabs(p[0][2] - p[3][2]);
|
||||
d2 = fabs(p[1][2] - p[2][2]);
|
||||
if (d1 < d2)
|
||||
{
|
||||
for (t = 0; t < 2; t++)
|
||||
{
|
||||
/*generate the brush (in world space*/
|
||||
if (t == 0)
|
||||
{
|
||||
VectorSubtract(p[3], p[2], d[0]);
|
||||
VectorSubtract(p[2], p[0], d[1]);
|
||||
//left-most
|
||||
Vector4Set(n[0], -1, 0, 0, -tr->htilesize*(sx+0));
|
||||
//bottom-most
|
||||
Vector4Set(n[1], 0, 1, 0, tr->htilesize*(sy+1));
|
||||
//top-right
|
||||
VectorSet(n[2], 0.70710678118654752440084436210485, -0.70710678118654752440084436210485, 0);
|
||||
n[2][3] = DotProduct(n[2], p[0]);
|
||||
//top
|
||||
VectorNormalize(d[0]);
|
||||
VectorNormalize(d[1]);
|
||||
CrossProduct(d[0], d[1], n[3]);
|
||||
VectorNormalize(n[3]);
|
||||
n[3][3] = DotProduct(n[3], p[0]);
|
||||
//down
|
||||
VectorNegate(n[3], n[4]);
|
||||
n[4][3] = DotProduct(n[4], p[0]) - n[4][2]*TERRAINTHICKNESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSubtract(p[1], p[0], d[0]);
|
||||
VectorSubtract(p[3], p[1], d[1]);
|
||||
|
||||
//right-most
|
||||
Vector4Set(n[0], 1, 0, 0, tr->htilesize*(sx+1));
|
||||
//top-most
|
||||
Vector4Set(n[1], 0, -1, 0, -tr->htilesize*(sy+0));
|
||||
//bottom-left
|
||||
VectorSet(n[2], -0.70710678118654752440084436210485, 0.70710678118654752440084436210485, 0);
|
||||
n[2][3] = DotProduct(n[2], p[0]);
|
||||
//top
|
||||
VectorNormalize(d[0]);
|
||||
VectorNormalize(d[1]);
|
||||
CrossProduct(d[0], d[1], n[3]);
|
||||
VectorNormalize(n[3]);
|
||||
n[3][3] = DotProduct(n[3], p[0]);
|
||||
//down
|
||||
VectorNegate(n[3], n[4]);
|
||||
n[4][3] = DotProduct(n[4], p[0]) - n[4][2]*TERRAINTHICKNESS;
|
||||
}
|
||||
Heightmap_Trace_Brush(tr, n, 5);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (t = 0; t < 2; t++)
|
||||
{
|
||||
/*generate the brush (in world space*/
|
||||
if (t == 0)
|
||||
{
|
||||
VectorSubtract(p[1], p[0], d[0]);
|
||||
VectorSubtract(p[2], p[0], d[1]);
|
||||
//left-most
|
||||
Vector4Set(n[0], -1, 0, 0, -tr->htilesize*(sx+0));
|
||||
//top-most
|
||||
Vector4Set(n[1], 0, -1, 0, -tr->htilesize*(sy+0));
|
||||
//bottom-right
|
||||
VectorSet(n[2], 0.70710678118654752440084436210485, 0.70710678118654752440084436210485, 0);
|
||||
n[2][3] = DotProduct(n[2], p[1]);
|
||||
//top
|
||||
VectorNormalize(d[0]);
|
||||
VectorNormalize(d[1]);
|
||||
CrossProduct(d[0], d[1], n[3]);
|
||||
VectorNormalize(n[3]);
|
||||
n[3][3] = DotProduct(n[3], p[1]);
|
||||
//down
|
||||
VectorNegate(n[3], n[4]);
|
||||
n[4][3] = DotProduct(n[4], p[1]) - n[4][2]*TERRAINTHICKNESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSubtract(p[3], p[2], d[0]);
|
||||
VectorSubtract(p[3], p[1], d[1]);
|
||||
|
||||
//right-most
|
||||
Vector4Set(n[0], 1, 0, 0, tr->htilesize*(sx+1));
|
||||
//bottom-most
|
||||
Vector4Set(n[1], 0, 1, 0, tr->htilesize*(sy+1));
|
||||
//top-left
|
||||
VectorSet(n[2], -0.70710678118654752440084436210485, -0.70710678118654752440084436210485, 0);
|
||||
n[2][3] = DotProduct(n[2], p[1]);
|
||||
//top
|
||||
VectorNormalize(d[0]);
|
||||
VectorNormalize(d[1]);
|
||||
CrossProduct(d[0], d[1], n[3]);
|
||||
VectorNormalize(n[3]);
|
||||
n[3][3] = DotProduct(n[3], p[1]);
|
||||
//down
|
||||
VectorNegate(n[3], n[4]);
|
||||
n[4][3] = DotProduct(n[4], p[1]) - n[4][2]*TERRAINTHICKNESS;
|
||||
}
|
||||
Heightmap_Trace_Brush(tr, n, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define DIST_EPSILON 0
|
||||
|
@ -1461,24 +1490,24 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec
|
|||
|
||||
hmtrace.plane[0] = 0;
|
||||
hmtrace.plane[1] = 0;
|
||||
hmtrace.plane[2] = 1;
|
||||
hmtrace.plane[2] = 0;
|
||||
hmtrace.plane[3] = 0;
|
||||
|
||||
memset(trace, 0, sizeof(*trace));
|
||||
trace->fraction = 1;
|
||||
|
||||
//to tile space
|
||||
hmtrace.start[0] = (start[0] + CHUNKBIAS*hmtrace.hm->sectionsize);
|
||||
hmtrace.start[1] = (start[1] + CHUNKBIAS*hmtrace.hm->sectionsize);
|
||||
hmtrace.start[0] = (start[0]);
|
||||
hmtrace.start[1] = (start[1]);
|
||||
hmtrace.start[2] = (start[2] + mins[2]);
|
||||
hmtrace.end[0] = (end[0] + CHUNKBIAS*hmtrace.hm->sectionsize);
|
||||
hmtrace.end[1] = (end[1] + CHUNKBIAS*hmtrace.hm->sectionsize);
|
||||
hmtrace.end[0] = (end[0]);
|
||||
hmtrace.end[1] = (end[1]);
|
||||
hmtrace.end[2] = (end[2] + mins[2]);
|
||||
|
||||
dir[0] = (hmtrace.end[0] - hmtrace.start[0])/hmtrace.htilesize;
|
||||
dir[1] = (hmtrace.end[1] - hmtrace.start[1])/hmtrace.htilesize;
|
||||
pos[0] = hmtrace.start[0]/hmtrace.htilesize;
|
||||
pos[1] = hmtrace.start[1]/hmtrace.htilesize;
|
||||
pos[0] = (hmtrace.start[0]+CHUNKBIAS*hmtrace.hm->sectionsize)/hmtrace.htilesize;
|
||||
pos[1] = (hmtrace.start[1]+CHUNKBIAS*hmtrace.hm->sectionsize)/hmtrace.htilesize;
|
||||
|
||||
emins[0] = (mins[0]-1)/hmtrace.htilesize;
|
||||
emins[1] = (mins[1]-1)/hmtrace.htilesize;
|
||||
|
@ -2003,7 +2032,7 @@ void QCBUILTIN PF_terrain_edit(progfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
tally[0] /= tally[1];
|
||||
if (IS_NAN(tally[0]))
|
||||
tally[0] = 0;
|
||||
ted_itterate(hm, pos, radius, 1, SECTHEIGHTSIZE, ted_heightsmooth, &tally);
|
||||
ted_itterate(hm, pos, radius, quant, SECTHEIGHTSIZE, ted_heightsmooth, &tally);
|
||||
break;
|
||||
case ter_height_spread:
|
||||
tally[0] = 0;
|
||||
|
@ -2225,6 +2254,19 @@ void Terr_ParseEntityLump(char *data, float *scale, int *minx, int *maxx, int *m
|
|||
else if (!strcmp("maxysegment", key))
|
||||
*maxy = atoi(com_token);
|
||||
}
|
||||
|
||||
*minx += CHUNKBIAS;
|
||||
*miny += CHUNKBIAS;
|
||||
*maxx += CHUNKBIAS;
|
||||
*maxy += CHUNKBIAS;
|
||||
if (*minx < 0)
|
||||
*minx = 0;
|
||||
if (*miny < 0)
|
||||
*miny = 0;
|
||||
if (*maxx > CHUNKLIMIT)
|
||||
*maxx = CHUNKLIMIT;
|
||||
if (*maxy > CHUNKLIMIT)
|
||||
*maxy = CHUNKLIMIT;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2265,23 +2307,14 @@ qboolean Terr_LoadTerrainModel (model_t *mod, void *buffer)
|
|||
strcpy(mod->entities, buffer);
|
||||
|
||||
hm->sectionsize = sectsize;
|
||||
hm->firstsegx = CHUNKBIAS - 1;
|
||||
hm->firstsegy = CHUNKBIAS - 1;
|
||||
hm->maxsegx = CHUNKBIAS + 1;
|
||||
hm->maxsegy = CHUNKBIAS + 1;
|
||||
hm->firstsegx = -1;
|
||||
hm->firstsegy = -1;
|
||||
hm->maxsegx = +1;
|
||||
hm->maxsegy = +1;
|
||||
hm->exteriorcontents = FTECONTENTS_SOLID; //sky outside the map
|
||||
|
||||
Terr_ParseEntityLump(mod->entities, &hm->sectionsize, &hm->firstsegx, &hm->maxsegx, &hm->firstsegy, &hm->maxsegy);
|
||||
|
||||
if (hm->firstsegx < 0)
|
||||
hm->firstsegx = 0;
|
||||
if (hm->firstsegy < 0)
|
||||
hm->firstsegy = 0;
|
||||
if (hm->maxsegx > CHUNKLIMIT)
|
||||
hm->maxsegx = CHUNKLIMIT;
|
||||
if (hm->maxsegy > CHUNKLIMIT)
|
||||
hm->maxsegy = CHUNKLIMIT;
|
||||
|
||||
mod->mins[0] = (hm->firstsegx - CHUNKBIAS) * hm->sectionsize;
|
||||
mod->mins[1] = (hm->firstsegy - CHUNKBIAS) * hm->sectionsize;
|
||||
mod->mins[2] = -999999999999999999999999.f;
|
||||
|
@ -2358,20 +2391,6 @@ void *Mod_LoadTerrainInfo(model_t *mod, char *loadname)
|
|||
|
||||
Terr_ParseEntityLump(mod->entities, &scale, &bounds[0], &bounds[1], &bounds[2], &bounds[3]);
|
||||
|
||||
bounds[0] += CHUNKBIAS;
|
||||
bounds[1] += CHUNKBIAS;
|
||||
bounds[2] += CHUNKBIAS;
|
||||
bounds[3] += CHUNKBIAS;
|
||||
|
||||
if (bounds[0] < 0)
|
||||
bounds[0] = 0;
|
||||
if (bounds[2] < 0)
|
||||
bounds[2] = 0;
|
||||
if (bounds[1] > CHUNKLIMIT)
|
||||
bounds[1] = CHUNKLIMIT;
|
||||
if (bounds[3] > CHUNKLIMIT)
|
||||
bounds[3] = CHUNKLIMIT;
|
||||
|
||||
if (!scale && (bounds[0] == bounds[1] || bounds[2] == bounds[3]))
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -927,6 +927,7 @@ int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
|
|||
window_width = DIBWidth;
|
||||
window_height = DIBHeight;
|
||||
VID_UpdateWindowStatus (mainwindow);
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
|
||||
CDAudio_Resume ();
|
||||
scr_disabled_for_loading = temp;
|
||||
|
@ -1293,9 +1294,8 @@ void GLVID_Recenter_f(void)
|
|||
WindowRect = centerrect(sys_parentleft, sys_parenttop, sys_parentwidth, sys_parentheight, vid_width.value, vid_height.value);
|
||||
MoveWindow(mainwindow, WindowRect.left, WindowRect.top, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, FALSE);
|
||||
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
Cvar_ForceCallback(&vid_conwidth);
|
||||
VID_UpdateWindowStatus (mainwindow);
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1822,6 +1822,7 @@ LONG WINAPI GLMainWndProc (
|
|||
|
||||
case WM_MOVE:
|
||||
VID_UpdateWindowStatus (hWnd);
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
|
@ -1939,9 +1940,8 @@ LONG WINAPI GLMainWndProc (
|
|||
case WM_SIZE:
|
||||
if (!vid_initializing)
|
||||
{
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
Cvar_ForceCallback(&vid_conwidth);
|
||||
VID_UpdateWindowStatus (hWnd);
|
||||
Cvar_ForceCallback(&vid_conautoscale);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in a new issue