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:
Spoike 2012-07-21 04:43:31 +00:00
parent 60d490fce6
commit f15532d525
6 changed files with 296 additions and 254 deletions

View File

@ -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;

View File

@ -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]);

View File

@ -172,6 +172,7 @@ void P_InitParticleSystem(void)
void P_Shutdown(void)
{
CL_ClearLerpEntsParticleState();
if (pe)
{
pe->ShutdownParticles();

View File

@ -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);

View File

@ -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;
s->ents = malloc(sizeof(*s->ents) * s->maxents);
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*/
@ -541,9 +575,11 @@ int HeightMap_Save(heightmap_t *hm)
continue;
if (s->flags & TSF_EDITED)
{
s->flags &= ~TSF_EDITED;
Terr_SaveSection(hm, s, x, y);
sectionssaved++;
if (Terr_SaveSection(hm, s, x, y))
{
s->flags &= ~TSF_EDITED;
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,22 +1238,97 @@ typedef struct {
int contents;
} hmtrace_t;
static void Heightmap_Trace_Brush(hmtrace_t *tr, vec4_t *planes, int numplanes)
{
qboolean startout;
float *enterplane;
double enterfrac, exitfrac, nearfrac=0;
double enterdist=0;
double dist, d1, d2, f;
int i;
startout = false;
enterplane= NULL;
enterfrac = -1;
exitfrac = 10;
for (i = 0; i < numplanes; i++)
{
/*calculate the distance based upon the shape of the object we're tracing for*/
dist = planes[i][3];
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 we're fully inside the plane, then whatever is happening is not relevent for this plane
if (d1 <= 0 && d2 <= 0)
continue;
f = (d1) / (d1-d2);
if (d1 > d2)
{
//entered the brush. favour the furthest fraction to avoid extended edges (yay for convex shapes)
if (enterfrac < f)
{
enterfrac = f;
nearfrac = (d1 - (0.03125)) / (d1-d2);
enterplane = planes[i];
enterdist = dist;
}
}
else
{
//left the brush, favour the nearest plane (smallest frac)
if (exitfrac > f)
{
exitfrac = f;
}
}
}
if (!startout)
{
tr->frac = -1;
return;
}
if (enterfrac != -1 && enterfrac < exitfrac)
{
//impact!
if (enterfrac < tr->frac)
{
if (nearfrac < 0)
nearfrac = 0;
tr->frac = nearfrac;//enterfrac;
tr->plane[3] = enterdist;
VectorCopy(enterplane, tr->plane);
}
}
nextbrush:
;
}
//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_Square(hmtrace_t *tr, int tx, int ty)
{
vec3_t d[2];
vec3_t p[4];
vec4_t n[5];
int t, i;
int t;
qboolean startout, endout;
float *enterplane;
float enterfrac, exitfrac, nearfrac=0;
float enterdist=0;
float dist, d1, d2, f;
#ifndef STRICTEDGES
float d1, d2;
#endif
int sx, sy;
hmsection_t *s;
unsigned int holebit;
if (tx < 0 || tx >= CHUNKLIMIT*(SECTHEIGHTSIZE-1))
return;
@ -1221,213 +1336,127 @@ void Heightmap_Trace_Square(hmtrace_t *tr, int tx, int ty)
return;
s = Terr_GetSection(tr->hm, tx/(SECTHEIGHTSIZE-1), ty/(SECTHEIGHTSIZE-1), true);
sx = tx;
sy = ty;
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]);
// 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++)
#ifndef STRICTEDGES
d1 = fabs(p[0][2] - p[3][2]);
d2 = fabs(p[1][2] - p[2][2]);
if (d1 < d2)
{
/*generate the brush (in world space*/
if (t == 0)
for (t = 0; t < 2; t++)
{
// 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]);
}
startout = false;
endout = false;
enterplane= NULL;
enterfrac = -1;
exitfrac = 10;
for (i = 0; i < 4; i++)
{
/*calculate the distance based upon the shape of the object we're tracing for*/
dist = n[i][3];
d1 = DotProduct (tr->start, n[i]) - dist;
d2 = DotProduct (tr->end, n[i]) - dist;
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)
continue;
f = (d1) / (d1-d2);
if (d1 > d2)
/*generate the brush (in world space*/
if (t == 0)
{
//entered the brush. favour the furthest fraction to avoid extended edges (yay for convex shapes)
if (enterfrac < f)
{
enterfrac = f;
nearfrac = (d1 - (0.03125)) / (d1-d2);
enterplane = n[i];
enterdist = dist;
}
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
{
//left the brush, favour the nearest plane (smallest frac)
if (exitfrac > f)
{
exitfrac = f;
}
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;
}
}
if (!startout)
{
tr->frac = -1;
return;
}
if (enterfrac != -1 && enterfrac < exitfrac)
{
//impact!
if (enterfrac < tr->frac)
{
if (nearfrac < 0)
nearfrac = 0;
tr->frac = nearfrac;//enterfrac;
tr->plane[3] = enterdist;
VectorCopy(enterplane, tr->plane);
}
}
nextbrush:
;
}
#if 0
float normf = 0.70710678118654752440084436210485;
float pd, sd, ed, bd;
int tris, x, y;
vec3_t closest;
vec3_t point;
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;
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;

View File

@ -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;