Annotation of quakeworld/client/pmovetst.c, revision 1.1.1.1

1.1       root        1: /*
                      2: Copyright (C) 1996-1997 Id Software, Inc.
                      3: 
                      4: This program is free software; you can redistribute it and/or
                      5: modify it under the terms of the GNU General Public License
                      6: as published by the Free Software Foundation; either version 2
                      7: of the License, or (at your option) any later version.
                      8: 
                      9: This program is distributed in the hope that it will be useful,
                     10: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
                     12: 
                     13: See the GNU General Public License for more details.
                     14: 
                     15: You should have received a copy of the GNU General Public License
                     16: along with this program; if not, write to the Free Software
                     17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
                     18: 
                     19: */
                     20: #include "quakedef.h"
                     21: 
                     22: static hull_t          box_hull;
                     23: static dclipnode_t     box_clipnodes[6];
                     24: static mplane_t        box_planes[6];
                     25: 
                     26: extern vec3_t player_mins;
                     27: extern vec3_t player_maxs;
                     28: 
                     29: /*
                     30: ===================
                     31: PM_InitBoxHull
                     32: 
                     33: Set up the planes and clipnodes so that the six floats of a bounding box
                     34: can just be stored out and get a proper hull_t structure.
                     35: ===================
                     36: */
                     37: void PM_InitBoxHull (void)
                     38: {
                     39:        int             i;
                     40:        int             side;
                     41: 
                     42:        box_hull.clipnodes = box_clipnodes;
                     43:        box_hull.planes = box_planes;
                     44:        box_hull.firstclipnode = 0;
                     45:        box_hull.lastclipnode = 5;
                     46: 
                     47:        for (i=0 ; i<6 ; i++)
                     48:        {
                     49:                box_clipnodes[i].planenum = i;
                     50:                
                     51:                side = i&1;
                     52:                
                     53:                box_clipnodes[i].children[side] = CONTENTS_EMPTY;
                     54:                if (i != 5)
                     55:                        box_clipnodes[i].children[side^1] = i + 1;
                     56:                else
                     57:                        box_clipnodes[i].children[side^1] = CONTENTS_SOLID;
                     58:                
                     59:                box_planes[i].type = i>>1;
                     60:                box_planes[i].normal[i>>1] = 1;
                     61:        }
                     62:        
                     63: }
                     64: 
                     65: 
                     66: /*
                     67: ===================
                     68: PM_HullForBox
                     69: 
                     70: To keep everything totally uniform, bounding boxes are turned into small
                     71: BSP trees instead of being compared directly.
                     72: ===================
                     73: */
                     74: hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs)
                     75: {
                     76:        box_planes[0].dist = maxs[0];
                     77:        box_planes[1].dist = mins[0];
                     78:        box_planes[2].dist = maxs[1];
                     79:        box_planes[3].dist = mins[1];
                     80:        box_planes[4].dist = maxs[2];
                     81:        box_planes[5].dist = mins[2];
                     82: 
                     83:        return &box_hull;
                     84: }
                     85: 
                     86: 
                     87: /*
                     88: ==================
                     89: PM_HullPointContents
                     90: 
                     91: ==================
                     92: */
                     93: int PM_HullPointContents (hull_t *hull, int num, vec3_t p)
                     94: {
                     95:        float           d;
                     96:        dclipnode_t     *node;
                     97:        mplane_t        *plane;
                     98: 
                     99:        while (num >= 0)
                    100:        {
                    101:                if (num < hull->firstclipnode || num > hull->lastclipnode)
                    102:                        Sys_Error ("PM_HullPointContents: bad node number");
                    103:        
                    104:                node = hull->clipnodes + num;
                    105:                plane = hull->planes + node->planenum;
                    106:                
                    107:                if (plane->type < 3)
                    108:                        d = p[plane->type] - plane->dist;
                    109:                else
                    110:                        d = DotProduct (plane->normal, p) - plane->dist;
                    111:                if (d < 0)
                    112:                        num = node->children[1];
                    113:                else
                    114:                        num = node->children[0];
                    115:        }
                    116:        
                    117:        return num;
                    118: }
                    119: 
                    120: /*
                    121: ==================
                    122: PM_PointContents
                    123: 
                    124: ==================
                    125: */
                    126: int PM_PointContents (vec3_t p)
                    127: {
                    128:        float           d;
                    129:        dclipnode_t     *node;
                    130:        mplane_t        *plane;
                    131:        hull_t          *hull;
                    132:        int                     num;
                    133: 
                    134:        hull = &pmove.physents[0].model->hulls[0];
                    135: 
                    136:        num = hull->firstclipnode;
                    137: 
                    138:        while (num >= 0)
                    139:        {
                    140:                if (num < hull->firstclipnode || num > hull->lastclipnode)
                    141:                        Sys_Error ("PM_HullPointContents: bad node number");
                    142:        
                    143:                node = hull->clipnodes + num;
                    144:                plane = hull->planes + node->planenum;
                    145:                
                    146:                if (plane->type < 3)
                    147:                        d = p[plane->type] - plane->dist;
                    148:                else
                    149:                        d = DotProduct (plane->normal, p) - plane->dist;
                    150:                if (d < 0)
                    151:                        num = node->children[1];
                    152:                else
                    153:                        num = node->children[0];
                    154:        }
                    155:        
                    156:        return num;
                    157: }
                    158: 
                    159: /*
                    160: ===============================================================================
                    161: 
                    162: LINE TESTING IN HULLS
                    163: 
                    164: ===============================================================================
                    165: */
                    166: 
                    167: // 1/32 epsilon to keep floating point happy
                    168: #define        DIST_EPSILON    (0.03125)
                    169: 
                    170: /*
                    171: ==================
                    172: PM_RecursiveHullCheck
                    173: 
                    174: ==================
                    175: */
                    176: qboolean PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, pmtrace_t *trace)
                    177: {
                    178:        dclipnode_t     *node;
                    179:        mplane_t        *plane;
                    180:        float           t1, t2;
                    181:        float           frac;
                    182:        int                     i;
                    183:        vec3_t          mid;
                    184:        int                     side;
                    185:        float           midf;
                    186: 
                    187: // check for empty
                    188:        if (num < 0)
                    189:        {
                    190:                if (num != CONTENTS_SOLID)
                    191:                {
                    192:                        trace->allsolid = false;
                    193:                        if (num == CONTENTS_EMPTY)
                    194:                                trace->inopen = true;
                    195:                        else
                    196:                                trace->inwater = true;
                    197:                }
                    198:                else
                    199:                        trace->startsolid = true;
                    200:                return true;            // empty
                    201:        }
                    202: 
                    203:        if (num < hull->firstclipnode || num > hull->lastclipnode)
                    204:                Sys_Error ("PM_RecursiveHullCheck: bad node number");
                    205: 
                    206: //
                    207: // find the point distances
                    208: //
                    209:        node = hull->clipnodes + num;
                    210:        plane = hull->planes + node->planenum;
                    211: 
                    212:        if (plane->type < 3)
                    213:        {
                    214:                t1 = p1[plane->type] - plane->dist;
                    215:                t2 = p2[plane->type] - plane->dist;
                    216:        }
                    217:        else
                    218:        {
                    219:                t1 = DotProduct (plane->normal, p1) - plane->dist;
                    220:                t2 = DotProduct (plane->normal, p2) - plane->dist;
                    221:        }
                    222:        
                    223: #if 1
                    224:        if (t1 >= 0 && t2 >= 0)
                    225:                return PM_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace);
                    226:        if (t1 < 0 && t2 < 0)
                    227:                return PM_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace);
                    228: #else
                    229:        if ( (t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0) )
                    230:                return PM_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace);
                    231:        if ( (t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0) )
                    232:                return PM_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace);
                    233: #endif
                    234: 
                    235: // put the crosspoint DIST_EPSILON pixels on the near side
                    236:        if (t1 < 0)
                    237:                frac = (t1 + DIST_EPSILON)/(t1-t2);
                    238:        else
                    239:                frac = (t1 - DIST_EPSILON)/(t1-t2);
                    240:        if (frac < 0)
                    241:                frac = 0;
                    242:        if (frac > 1)
                    243:                frac = 1;
                    244:                
                    245:        midf = p1f + (p2f - p1f)*frac;
                    246:        for (i=0 ; i<3 ; i++)
                    247:                mid[i] = p1[i] + frac*(p2[i] - p1[i]);
                    248: 
                    249:        side = (t1 < 0);
                    250: 
                    251: // move up to the node
                    252:        if (!PM_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) )
                    253:                return false;
                    254: 
                    255: #ifdef PARANOID
                    256:        if (PM_HullPointContents (pm_hullmodel, mid, node->children[side])
                    257:        == CONTENTS_SOLID)
                    258:        {
                    259:                Con_Printf ("mid PointInHullSolid\n");
                    260:                return false;
                    261:        }
                    262: #endif
                    263:        
                    264:        if (PM_HullPointContents (hull, node->children[side^1], mid)
                    265:        != CONTENTS_SOLID)
                    266: // go past the node
                    267:                return PM_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace);
                    268:        
                    269:        if (trace->allsolid)
                    270:                return false;           // never got out of the solid area
                    271:                
                    272: //==================
                    273: // the other side of the node is solid, this is the impact point
                    274: //==================
                    275:        if (!side)
                    276:        {
                    277:                VectorCopy (plane->normal, trace->plane.normal);
                    278:                trace->plane.dist = plane->dist;
                    279:        }
                    280:        else
                    281:        {
                    282:                VectorSubtract (vec3_origin, plane->normal, trace->plane.normal);
                    283:                trace->plane.dist = -plane->dist;
                    284:        }
                    285: 
                    286:        while (PM_HullPointContents (hull, hull->firstclipnode, mid)
                    287:        == CONTENTS_SOLID)
                    288:        { // shouldn't really happen, but does occasionally
                    289:                frac -= 0.1;
                    290:                if (frac < 0)
                    291:                {
                    292:                        trace->fraction = midf;
                    293:                        VectorCopy (mid, trace->endpos);
                    294:                        Con_DPrintf ("backup past 0\n");
                    295:                        return false;
                    296:                }
                    297:                midf = p1f + (p2f - p1f)*frac;
                    298:                for (i=0 ; i<3 ; i++)
                    299:                        mid[i] = p1[i] + frac*(p2[i] - p1[i]);
                    300:        }
                    301: 
                    302:        trace->fraction = midf;
                    303:        VectorCopy (mid, trace->endpos);
                    304: 
                    305:        return false;
                    306: }
                    307: 
                    308: 
                    309: /*
                    310: ================
                    311: PM_TestPlayerPosition
                    312: 
                    313: Returns false if the given player position is not valid (in solid)
                    314: ================
                    315: */
                    316: qboolean PM_TestPlayerPosition (vec3_t pos)
                    317: {
                    318:        int                     i;
                    319:        physent_t       *pe;
                    320:        vec3_t          mins, maxs, test;
                    321:        hull_t          *hull;
                    322: 
                    323:        for (i=0 ; i< pmove.numphysent ; i++)
                    324:        {
                    325:                pe = &pmove.physents[i];
                    326:        // get the clipping hull
                    327:                if (pe->model)
                    328:                        hull = &pmove.physents[i].model->hulls[1];
                    329:                else
                    330:                {
                    331:                        VectorSubtract (pe->mins, player_maxs, mins);
                    332:                        VectorSubtract (pe->maxs, player_mins, maxs);
                    333:                        hull = PM_HullForBox (mins, maxs);
                    334:                }
                    335: 
                    336:                VectorSubtract (pos, pe->origin, test);
                    337: 
                    338:                if (PM_HullPointContents (hull, hull->firstclipnode, test) == CONTENTS_SOLID)
                    339:                        return false;
                    340:        }
                    341: 
                    342:        return true;
                    343: }
                    344: 
                    345: /*
                    346: ================
                    347: PM_PlayerMove
                    348: ================
                    349: */
                    350: pmtrace_t PM_PlayerMove (vec3_t start, vec3_t end)
                    351: {
                    352:        pmtrace_t               trace, total;
                    353:        vec3_t          offset;
                    354:        vec3_t          start_l, end_l;
                    355:        hull_t          *hull;
                    356:        int                     i;
                    357:        physent_t       *pe;
                    358:        vec3_t          mins, maxs;
                    359: 
                    360: // fill in a default trace
                    361:        memset (&total, 0, sizeof(pmtrace_t));
                    362:        total.fraction = 1;
                    363:        total.ent = -1;
                    364:        VectorCopy (end, total.endpos);
                    365: 
                    366:        for (i=0 ; i< pmove.numphysent ; i++)
                    367:        {
                    368:                pe = &pmove.physents[i];
                    369:        // get the clipping hull
                    370:                if (pe->model)
                    371:                        hull = &pmove.physents[i].model->hulls[1];
                    372:                else
                    373:                {
                    374:                        VectorSubtract (pe->mins, player_maxs, mins);
                    375:                        VectorSubtract (pe->maxs, player_mins, maxs);
                    376:                        hull = PM_HullForBox (mins, maxs);
                    377:                }
                    378: 
                    379:        // PM_HullForEntity (ent, mins, maxs, offset);
                    380:        VectorCopy (pe->origin, offset);
                    381: 
                    382:                VectorSubtract (start, offset, start_l);
                    383:                VectorSubtract (end, offset, end_l);
                    384: 
                    385:        // fill in a default trace
                    386:                memset (&trace, 0, sizeof(pmtrace_t));
                    387:                trace.fraction = 1;
                    388:                trace.allsolid = true;
                    389: //             trace.startsolid = true;
                    390:                VectorCopy (end, trace.endpos);
                    391: 
                    392:        // trace a line through the apropriate clipping hull
                    393:                PM_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace);
                    394: 
                    395:                if (trace.allsolid)
                    396:                        trace.startsolid = true;
                    397:                if (trace.startsolid)
                    398:                        trace.fraction = 0;
                    399: 
                    400:        // did we clip the move?
                    401:                if (trace.fraction < total.fraction)
                    402:                {
                    403:                        // fix trace up by the offset
                    404:                        VectorAdd (trace.endpos, offset, trace.endpos);
                    405:                        total = trace;
                    406:                        total.ent = i;
                    407:                }
                    408: 
                    409:        }
                    410: 
                    411:        return total;
                    412: }
                    413: 
                    414: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.