2004-08-21 01:25:48 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 1996-1997 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.
|
|
|
|
|
|
|
|
*/
|
|
|
|
#include "quakedef.h"
|
|
|
|
|
2014-01-13 02:42:25 +00:00
|
|
|
static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace, vec3_t origin, vec3_t angles);
|
2006-01-28 02:35:40 +00:00
|
|
|
int Q1BSP_HullPointContents(hull_t *hull, vec3_t p);
|
2004-08-21 01:25:48 +00:00
|
|
|
static hull_t box_hull;
|
2011-06-29 18:39:11 +00:00
|
|
|
static mclipnode_t box_clipnodes[6];
|
2004-08-21 01:25:48 +00:00
|
|
|
static mplane_t box_planes[6];
|
|
|
|
|
|
|
|
/*
|
|
|
|
===================
|
|
|
|
PM_InitBoxHull
|
|
|
|
|
|
|
|
Set up the planes and clipnodes so that the six floats of a bounding box
|
|
|
|
can just be stored out and get a proper hull_t structure.
|
|
|
|
===================
|
|
|
|
*/
|
|
|
|
void PM_InitBoxHull (void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int side;
|
|
|
|
|
|
|
|
box_hull.clipnodes = box_clipnodes;
|
|
|
|
box_hull.planes = box_planes;
|
|
|
|
box_hull.firstclipnode = 0;
|
|
|
|
box_hull.lastclipnode = 5;
|
|
|
|
|
|
|
|
for (i=0 ; i<6 ; i++)
|
|
|
|
{
|
|
|
|
box_clipnodes[i].planenum = i;
|
|
|
|
|
|
|
|
side = i&1;
|
|
|
|
|
|
|
|
box_clipnodes[i].children[side] = Q1CONTENTS_EMPTY;
|
|
|
|
if (i != 5)
|
|
|
|
box_clipnodes[i].children[side^1] = i + 1;
|
|
|
|
else
|
|
|
|
box_clipnodes[i].children[side^1] = Q1CONTENTS_SOLID;
|
|
|
|
|
|
|
|
box_planes[i].type = i>>1;
|
|
|
|
box_planes[i].normal[i>>1] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
===================
|
|
|
|
PM_HullForBox
|
|
|
|
|
|
|
|
To keep everything totally uniform, bounding boxes are turned into small
|
|
|
|
BSP trees instead of being compared directly.
|
|
|
|
===================
|
|
|
|
*/
|
|
|
|
hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs)
|
|
|
|
{
|
|
|
|
box_planes[0].dist = maxs[0];
|
|
|
|
box_planes[1].dist = mins[0];
|
|
|
|
box_planes[2].dist = maxs[1];
|
|
|
|
box_planes[3].dist = mins[1];
|
|
|
|
box_planes[4].dist = maxs[2];
|
|
|
|
box_planes[5].dist = mins[2];
|
|
|
|
|
|
|
|
return &box_hull;
|
|
|
|
}
|
|
|
|
|
2005-08-26 22:56:51 +00:00
|
|
|
|
|
|
|
int PM_TransformedModelPointContents (model_t *mod, vec3_t p, vec3_t origin, vec3_t angles)
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
vec3_t p_l, axis[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
VectorSubtract (p, origin, p_l);
|
|
|
|
|
2013-12-29 22:48:28 +00:00
|
|
|
if (!mod->funcs.PointContents)
|
|
|
|
return FTECONTENTS_EMPTY;
|
|
|
|
|
2004-08-21 01:25:48 +00:00
|
|
|
// rotate start and end into the models frame of reference
|
2005-08-26 22:56:51 +00:00
|
|
|
if (angles[0] || angles[1] || angles[2])
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
AngleVectors (angles, axis[0], axis[1], axis[2]);
|
|
|
|
VectorNegate(axis[1], axis[1]);
|
|
|
|
return mod->funcs.PointContents(mod, axis, p_l);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
2010-08-28 17:14:38 +00:00
|
|
|
return mod->funcs.PointContents(mod, NULL, p_l);
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
2005-08-26 22:56:51 +00:00
|
|
|
|
2004-08-21 01:25:48 +00:00
|
|
|
/*
|
|
|
|
==================
|
|
|
|
PM_PointContents
|
|
|
|
|
|
|
|
==================
|
|
|
|
*/
|
|
|
|
int PM_PointContents (vec3_t p)
|
|
|
|
{
|
|
|
|
int num;
|
|
|
|
|
|
|
|
int pc;
|
2005-08-26 22:56:51 +00:00
|
|
|
physent_t *pe;
|
|
|
|
model_t *pm;
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2013-12-29 22:48:28 +00:00
|
|
|
//check world.
|
2005-08-26 22:56:51 +00:00
|
|
|
pm = pmove.physents[0].model;
|
2013-07-26 17:19:06 +00:00
|
|
|
if (!pm || pm->needload)
|
2009-04-01 22:03:56 +00:00
|
|
|
return FTECONTENTS_EMPTY;
|
2010-08-28 17:14:38 +00:00
|
|
|
pc = pm->funcs.PointContents(pm, NULL, p);
|
2013-12-29 22:48:28 +00:00
|
|
|
|
2004-08-21 01:25:48 +00:00
|
|
|
//we need this for e2m2 - waterjumping on to plats wouldn't work otherwise.
|
|
|
|
for (num = 1; num < pmove.numphysent; num++)
|
|
|
|
{
|
2005-08-26 22:56:51 +00:00
|
|
|
pe = &pmove.physents[num];
|
2012-02-12 05:18:31 +00:00
|
|
|
|
|
|
|
if (pe->info == pmove.skipent)
|
|
|
|
continue;
|
|
|
|
|
2005-08-26 22:56:51 +00:00
|
|
|
pm = pe->model;
|
|
|
|
if (pm)
|
2009-03-03 01:52:30 +00:00
|
|
|
{
|
2012-02-12 05:18:31 +00:00
|
|
|
if (p[0] >= pe->origin[0]+pm->mins[0] && p[0] <= pe->origin[0]+pm->maxs[0] &&
|
|
|
|
p[1] >= pe->origin[1]+pm->mins[1] && p[1] <= pe->origin[1]+pm->maxs[1] &&
|
|
|
|
p[2] >= pe->origin[2]+pm->mins[2] && p[2] <= pe->origin[2]+pm->maxs[2])
|
2009-03-03 01:52:30 +00:00
|
|
|
{
|
2012-02-12 05:18:31 +00:00
|
|
|
if (pe->forcecontentsmask)
|
|
|
|
{
|
|
|
|
if (PM_TransformedModelPointContents(pm, p, pe->origin, pe->angles))
|
|
|
|
pc |= pe->forcecontentsmask;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pe->nonsolid)
|
|
|
|
continue;
|
|
|
|
pc |= PM_TransformedModelPointContents(pm, p, pe->origin, pe->angles);
|
|
|
|
}
|
2009-03-03 01:52:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pe->forcecontentsmask)
|
|
|
|
{
|
2012-02-12 05:18:31 +00:00
|
|
|
if (p[0] >= pe->origin[0]+pe->mins[0] && p[0] <= pe->origin[0]+pe->maxs[0] &&
|
|
|
|
p[1] >= pe->origin[1]+pe->mins[1] && p[1] <= pe->origin[1]+pe->maxs[1] &&
|
|
|
|
p[2] >= pe->origin[2]+pe->mins[2] && p[2] <= pe->origin[2]+pe->maxs[2])
|
2009-03-03 01:52:30 +00:00
|
|
|
pc |= pe->forcecontentsmask;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return pc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int PM_ExtraBoxContents (vec3_t p)
|
|
|
|
{
|
|
|
|
int num;
|
|
|
|
|
|
|
|
int pc = 0;
|
|
|
|
physent_t *pe;
|
|
|
|
model_t *pm;
|
|
|
|
trace_t tr;
|
|
|
|
|
|
|
|
for (num = 1; num < pmove.numphysent; num++)
|
|
|
|
{
|
|
|
|
pe = &pmove.physents[num];
|
|
|
|
if (!pe->nonsolid)
|
|
|
|
continue;
|
|
|
|
pm = pe->model;
|
|
|
|
if (pm)
|
|
|
|
{
|
|
|
|
if (pe->forcecontentsmask)
|
|
|
|
{
|
2014-01-13 02:42:25 +00:00
|
|
|
if (!PM_TransformedHullCheck(pm, p, p, pmove.player_mins, pmove.player_maxs, &tr, pe->origin, pe->angles))
|
2010-07-13 09:49:38 +00:00
|
|
|
continue;
|
2009-03-03 01:52:30 +00:00
|
|
|
if (tr.startsolid)
|
|
|
|
pc |= pe->forcecontentsmask;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pe->forcecontentsmask)
|
|
|
|
{
|
2014-01-13 02:42:25 +00:00
|
|
|
if (p[0]+pmove.player_maxs[0] >= pe->origin[0]+pe->mins[0] && p[0]+pmove.player_mins[0] <= pe->origin[0]+pe->maxs[0] &&
|
|
|
|
p[1]+pmove.player_maxs[1] >= pe->origin[1]+pe->mins[1] && p[1]+pmove.player_mins[1] <= pe->origin[1]+pe->maxs[1] &&
|
|
|
|
p[2]+pmove.player_maxs[2] >= pe->origin[2]+pe->mins[2] && p[2]+pmove.player_mins[2] <= pe->origin[2]+pe->maxs[2])
|
2009-03-03 01:52:30 +00:00
|
|
|
pc |= pe->forcecontentsmask;
|
|
|
|
}
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return pc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
LINE TESTING IN HULLS
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
|
|
|
|
2010-07-13 09:49:38 +00:00
|
|
|
/*returns if it actually did a trace*/
|
2014-01-13 02:42:25 +00:00
|
|
|
static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, vec3_t player_mins, vec3_t player_maxs, trace_t *trace, vec3_t origin, vec3_t angles)
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
|
|
|
vec3_t start_l, end_l;
|
2010-07-13 09:49:38 +00:00
|
|
|
int i;
|
2010-08-28 17:14:38 +00:00
|
|
|
vec3_t axis[3];
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
// subtract origin offset
|
|
|
|
VectorSubtract (start, origin, start_l);
|
|
|
|
VectorSubtract (end, origin, end_l);
|
|
|
|
|
|
|
|
// sweep the box through the model
|
2010-07-13 09:49:38 +00:00
|
|
|
if (model)
|
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
if (angles[0] || angles[1] || angles[2])
|
2010-07-13 09:49:38 +00:00
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
AngleVectors (angles, axis[0], axis[1], axis[2]);
|
|
|
|
VectorNegate(axis[1], axis[1]);
|
2012-01-17 07:57:46 +00:00
|
|
|
model->funcs.NativeTrace(model, 0, 0, axis, start_l, end_l, player_mins, player_maxs, MASK_PLAYERSOLID, trace);
|
2010-07-13 09:49:38 +00:00
|
|
|
}
|
2010-08-28 17:14:38 +00:00
|
|
|
else
|
2011-12-05 15:23:40 +00:00
|
|
|
{
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
if (start_l[i]+player_mins[i] > model->maxs[i] && end_l[i] + player_mins[i] > model->maxs[i])
|
|
|
|
return false;
|
|
|
|
if (start_l[i]+player_maxs[i] < model->mins[i] && end_l[i] + player_maxs[i] < model->mins[i])
|
|
|
|
return false;
|
|
|
|
}
|
2012-01-17 07:57:46 +00:00
|
|
|
model->funcs.NativeTrace(model, 0, 0, NULL, start_l, end_l, player_mins, player_maxs, MASK_PLAYERSOLID, trace);
|
2011-12-05 15:23:40 +00:00
|
|
|
}
|
2010-07-13 09:49:38 +00:00
|
|
|
}
|
2005-07-16 00:53:08 +00:00
|
|
|
else
|
2005-10-07 02:10:56 +00:00
|
|
|
{
|
2010-07-13 09:49:38 +00:00
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
{
|
|
|
|
if (start_l[i]+player_mins[i] > box_planes[0+i*2].dist && end_l[i] + player_mins[i] > box_planes[0+i*2].dist)
|
|
|
|
return false;
|
|
|
|
if (start_l[i]+player_maxs[i] < box_planes[1+i*2].dist && end_l[i] + player_maxs[i] < box_planes[1+i*2].dist)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Q1BSP_RecursiveHullCheck (&box_hull, box_hull.firstclipnode, 0, 1, start_l, end_l, trace);
|
2005-10-07 02:10:56 +00:00
|
|
|
}
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2010-08-28 17:14:38 +00:00
|
|
|
trace->endpos[0] += origin[0];
|
|
|
|
trace->endpos[1] += origin[1];
|
|
|
|
trace->endpos[2] += origin[2];
|
2010-07-13 09:49:38 +00:00
|
|
|
return true;
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
2014-06-21 17:58:17 +00:00
|
|
|
|
|
|
|
//a portal is flush with a world surface behind it.
|
|
|
|
//this causes problems. namely that we can't pass through the portal plane if the bsp behind it prevents out origin from getting through.
|
|
|
|
//so if the trace was clipped and ended infront of the portal, continue the trace to the edges of the portal cutout instead.
|
2014-06-25 03:53:11 +00:00
|
|
|
static void PM_PortalCSG(physent_t *portal, int entnum, float *trmin, float *trmax, vec3_t start, vec3_t end, trace_t *trace)
|
2014-06-21 17:58:17 +00:00
|
|
|
{
|
|
|
|
vec4_t planes[6]; //far, near, right, left, up, down
|
|
|
|
int plane;
|
|
|
|
vec3_t worldpos;
|
|
|
|
float portalradius = 128;
|
2014-06-25 03:53:11 +00:00
|
|
|
int hitplane = -1;
|
|
|
|
float bestfrac;
|
2014-06-21 17:58:17 +00:00
|
|
|
//only run this code if we impacted on the portal's parent.
|
|
|
|
if (trace->fraction == 1 && !trace->startsolid)
|
|
|
|
return;
|
|
|
|
if (!portalradius)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (trace->startsolid)
|
|
|
|
VectorCopy(start, worldpos); //make sure we use a sane valid position.
|
|
|
|
else
|
|
|
|
VectorCopy(trace->endpos, worldpos);
|
|
|
|
|
|
|
|
//determine the csg area. normals should be facing in
|
|
|
|
AngleVectors(portal->angles, planes[1], planes[3], planes[5]);
|
|
|
|
VectorNegate(planes[1], planes[0]);
|
|
|
|
VectorNegate(planes[3], planes[2]);
|
|
|
|
VectorNegate(planes[5], planes[4]);
|
|
|
|
|
|
|
|
portalradius/=2;
|
2014-06-25 03:53:11 +00:00
|
|
|
planes[0][3] = DotProduct(portal->origin, planes[0]) - (4.0/32);
|
|
|
|
planes[1][3] = DotProduct(portal->origin, planes[1]) - (4.0/32); //an epsilon beyond the portal. this needs to cover funny angle differences
|
2014-06-22 23:58:53 +00:00
|
|
|
planes[2][3] = DotProduct(portal->origin, planes[2]) - portalradius;
|
|
|
|
planes[3][3] = DotProduct(portal->origin, planes[3]) - portalradius;
|
|
|
|
planes[4][3] = DotProduct(portal->origin, planes[4]) - portalradius;
|
|
|
|
planes[5][3] = DotProduct(portal->origin, planes[5]) - portalradius;
|
2014-06-21 17:58:17 +00:00
|
|
|
|
|
|
|
//if we're actually inside the csg region
|
|
|
|
for (plane = 0; plane < 6; plane++)
|
|
|
|
{
|
2014-06-22 23:58:53 +00:00
|
|
|
vec3_t nearest;
|
2014-06-21 17:58:17 +00:00
|
|
|
float d = DotProduct(worldpos, planes[plane]);
|
2014-06-22 23:58:53 +00:00
|
|
|
int k;
|
|
|
|
for (k = 0; k < 3; k++)
|
|
|
|
nearest[k] = (planes[plane][k]>=0)?trmax[k]:trmin[k];
|
|
|
|
if (!plane) //front plane gets further away with side
|
|
|
|
planes[plane][3] -= DotProduct(nearest, planes[plane]);
|
|
|
|
else if (plane>1) //side planes get nearer with size
|
2014-06-25 03:53:11 +00:00
|
|
|
planes[plane][3] += 24;//+= DotProduct(nearest, planes[plane]);
|
2014-06-21 17:58:17 +00:00
|
|
|
if (d - planes[plane][3] >= 0)
|
|
|
|
continue; //endpos is inside
|
|
|
|
else
|
|
|
|
return; //end is already outside
|
|
|
|
}
|
|
|
|
//yup, we're inside, the trace shouldn't end where it actually did
|
2014-06-25 03:53:11 +00:00
|
|
|
bestfrac = 1;
|
|
|
|
hitplane = -1;
|
2014-06-21 17:58:17 +00:00
|
|
|
for (plane = 0; plane < 6; plane++)
|
|
|
|
{
|
|
|
|
float ds = DotProduct(start, planes[plane]) - planes[plane][3];
|
|
|
|
float de = DotProduct(end, planes[plane]) - planes[plane][3];
|
|
|
|
float frac;
|
|
|
|
if (ds >= 0 && de < 0)
|
|
|
|
{
|
2014-06-25 03:53:11 +00:00
|
|
|
frac = (ds - (1/32.0)) / (ds - de);
|
|
|
|
if (frac < bestfrac)
|
2014-06-21 17:58:17 +00:00
|
|
|
{
|
|
|
|
if (frac < 0)
|
|
|
|
frac = 0;
|
2014-06-25 03:53:11 +00:00
|
|
|
hitplane = plane;
|
|
|
|
bestfrac = frac;
|
2014-06-21 17:58:17 +00:00
|
|
|
VectorInterpolate(start, frac, end, trace->endpos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-25 03:53:11 +00:00
|
|
|
trace->startsolid = trace->allsolid = false;
|
|
|
|
//if we cross the front of the portal, don't shorten the trace, that will artificially clip us
|
|
|
|
if (hitplane == 0 && trace->fraction > bestfrac)
|
|
|
|
return;
|
|
|
|
//okay, elongate to clip to the portal hole properly.
|
|
|
|
trace->fraction = bestfrac;
|
|
|
|
VectorInterpolate(start, bestfrac, end, trace->endpos);
|
|
|
|
|
|
|
|
if (hitplane >= 0)
|
|
|
|
{
|
|
|
|
VectorCopy(planes[hitplane], trace->plane.normal);
|
|
|
|
trace->plane.dist = planes[hitplane][3];
|
|
|
|
if (hitplane == 1)
|
|
|
|
trace->entnum = entnum;
|
|
|
|
}
|
2014-06-21 17:58:17 +00:00
|
|
|
}
|
|
|
|
|
2004-08-21 01:25:48 +00:00
|
|
|
/*
|
|
|
|
================
|
|
|
|
PM_TestPlayerPosition
|
|
|
|
|
|
|
|
Returns false if the given player position is not valid (in solid)
|
|
|
|
================
|
|
|
|
*/
|
|
|
|
qboolean PM_TestPlayerPosition (vec3_t pos)
|
|
|
|
{
|
2014-06-21 17:58:17 +00:00
|
|
|
int i, j;
|
2004-08-21 01:25:48 +00:00
|
|
|
physent_t *pe;
|
|
|
|
vec3_t mins, maxs;
|
|
|
|
hull_t *hull;
|
2005-08-26 22:56:51 +00:00
|
|
|
trace_t trace;
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2014-06-21 17:58:17 +00:00
|
|
|
trace.allsolid = false;
|
|
|
|
|
2004-08-21 01:25:48 +00:00
|
|
|
for (i=0 ; i< pmove.numphysent ; i++)
|
|
|
|
{
|
|
|
|
pe = &pmove.physents[i];
|
|
|
|
|
2012-02-12 05:18:31 +00:00
|
|
|
if (pe->info == pmove.skipent)
|
|
|
|
continue;
|
|
|
|
|
2014-01-13 02:42:25 +00:00
|
|
|
if (pe->nonsolid || pe->isportal)
|
2009-03-03 01:52:30 +00:00
|
|
|
continue;
|
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
if (pe->forcecontentsmask && !(pe->forcecontentsmask & MASK_PLAYERSOLID))
|
|
|
|
continue;
|
|
|
|
|
2004-08-21 01:25:48 +00:00
|
|
|
// get the clipping hull
|
|
|
|
if (pe->model)
|
|
|
|
{
|
2014-01-13 02:42:25 +00:00
|
|
|
if (!PM_TransformedHullCheck (pe->model, pos, pos, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles))
|
2004-08-21 01:25:48 +00:00
|
|
|
continue;
|
2005-08-28 19:43:50 +00:00
|
|
|
if (trace.allsolid)
|
2014-06-21 17:58:17 +00:00
|
|
|
{
|
|
|
|
for (j = i+1; j < pmove.numphysent && trace.allsolid; j++)
|
|
|
|
{
|
|
|
|
pe = &pmove.physents[j];
|
|
|
|
if (pe->isportal)
|
2014-06-25 03:53:11 +00:00
|
|
|
PM_PortalCSG(pe, j, pmove.player_mins, pmove.player_maxs, pos, pos, &trace);
|
2014-06-21 17:58:17 +00:00
|
|
|
}
|
|
|
|
if (trace.allsolid)
|
|
|
|
return false;
|
|
|
|
}
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-13 02:42:25 +00:00
|
|
|
VectorSubtract (pe->mins, pmove.player_maxs, mins);
|
|
|
|
VectorSubtract (pe->maxs, pmove.player_mins, maxs);
|
2004-08-21 01:25:48 +00:00
|
|
|
hull = PM_HullForBox (mins, maxs);
|
2005-08-26 22:56:51 +00:00
|
|
|
VectorSubtract(pos, pe->origin, mins);
|
2004-08-21 01:25:48 +00:00
|
|
|
|
2013-10-29 17:38:22 +00:00
|
|
|
if (Q1BSP_HullPointContents(hull, mins) & MASK_PLAYERSOLID)
|
2005-08-26 22:56:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
2004-08-21 01:25:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
================
|
|
|
|
PM_PlayerTrace
|
|
|
|
================
|
|
|
|
*/
|
2013-10-29 17:38:22 +00:00
|
|
|
trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask)
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
|
|
|
trace_t trace, total;
|
2014-06-21 17:58:17 +00:00
|
|
|
int i, j;
|
2004-08-21 01:25:48 +00:00
|
|
|
physent_t *pe;
|
|
|
|
|
|
|
|
// fill in a default trace
|
|
|
|
memset (&total, 0, sizeof(trace_t));
|
|
|
|
total.fraction = 1;
|
|
|
|
total.entnum = -1;
|
|
|
|
VectorCopy (end, total.endpos);
|
|
|
|
|
|
|
|
for (i=0 ; i< pmove.numphysent ; i++)
|
|
|
|
{
|
|
|
|
pe = &pmove.physents[i];
|
|
|
|
|
2009-03-03 01:52:30 +00:00
|
|
|
if (pe->nonsolid)
|
|
|
|
continue;
|
2012-02-12 05:18:31 +00:00
|
|
|
if (pe->info == pmove.skipent)
|
|
|
|
continue;
|
2013-10-29 17:38:22 +00:00
|
|
|
if (pe->forcecontentsmask && !(pe->forcecontentsmask & solidmask))
|
|
|
|
continue;
|
2009-03-03 01:52:30 +00:00
|
|
|
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
if (!pe->model || pe->model->needload)
|
2005-10-07 02:10:56 +00:00
|
|
|
{
|
|
|
|
vec3_t mins, maxs;
|
2010-07-13 09:49:38 +00:00
|
|
|
|
2014-01-13 02:42:25 +00:00
|
|
|
VectorSubtract (pe->mins, pmove.player_maxs, mins);
|
|
|
|
VectorSubtract (pe->maxs, pmove.player_mins, maxs);
|
2005-10-07 02:10:56 +00:00
|
|
|
PM_HullForBox (mins, maxs);
|
|
|
|
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
// trace a line through the apropriate clipping hull
|
2014-01-13 02:42:25 +00:00
|
|
|
if (!PM_TransformedHullCheck (NULL, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles))
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (pe->isportal)
|
|
|
|
{
|
2014-06-21 17:58:17 +00:00
|
|
|
//make sure we don't hit the world if we're inside the portal
|
2014-06-25 03:53:11 +00:00
|
|
|
PM_PortalCSG(pe, i, pmove.player_mins, pmove.player_maxs, start, end, &total);
|
2014-06-21 17:58:17 +00:00
|
|
|
|
2014-01-13 02:42:25 +00:00
|
|
|
// trace a line through the apropriate clipping hull
|
|
|
|
if (!PM_TransformedHullCheck (pe->model, start, end, vec3_origin, vec3_origin, &trace, pe->origin, pe->angles))
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// trace a line through the apropriate clipping hull
|
2014-01-13 02:42:25 +00:00
|
|
|
if (!PM_TransformedHullCheck (pe->model, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles))
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
continue;
|
2014-06-21 17:58:17 +00:00
|
|
|
|
|
|
|
if (trace.allsolid)
|
|
|
|
{
|
|
|
|
for (j = i+1; j < pmove.numphysent && trace.allsolid; j++)
|
|
|
|
{
|
|
|
|
pe = &pmove.physents[j];
|
|
|
|
if (pe->isportal)
|
2014-06-25 03:53:11 +00:00
|
|
|
PM_PortalCSG(pe, j, pmove.player_mins, pmove.player_maxs, start, end, &trace);
|
2014-06-21 17:58:17 +00:00
|
|
|
}
|
|
|
|
pe = &pmove.physents[i];
|
|
|
|
}
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
}
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
if (trace.allsolid)
|
|
|
|
trace.startsolid = true;
|
2014-01-13 02:42:25 +00:00
|
|
|
|
|
|
|
if (trace.startsolid && pe->isportal)
|
2014-06-25 03:53:11 +00:00
|
|
|
trace.startsolid = false;
|
2004-08-21 01:25:48 +00:00
|
|
|
|
|
|
|
// did we clip the move?
|
2014-06-25 03:53:11 +00:00
|
|
|
if (trace.fraction < total.fraction || (trace.startsolid && !total.startsolid))
|
2004-08-21 01:25:48 +00:00
|
|
|
{
|
|
|
|
// fix trace up by the offset
|
|
|
|
total = trace;
|
|
|
|
total.entnum = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
2005-04-26 16:04:12 +00:00
|
|
|
//for use outside the pmove code. lame, but works.
|
|
|
|
trace_t PM_TraceLine (vec3_t start, vec3_t end)
|
|
|
|
{
|
2014-01-13 02:42:25 +00:00
|
|
|
VectorClear(pmove.player_mins);
|
|
|
|
VectorClear(pmove.player_maxs);
|
2013-10-29 17:38:22 +00:00
|
|
|
return PM_PlayerTrace(start, end, MASK_PLAYERSOLID);
|
2005-07-20 20:21:10 +00:00
|
|
|
}
|