X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=world.c;h=ec9942e4d5f23d0b15877a4ee89f6abca378178e;hp=4bb4b54ddcbb04cb11e0bb38cc60e7cca0277990;hb=6a384398c93b7e2bc1936427797909eb60094160;hpb=cecffffdd5310e387e8b910735ff77aa329cdb43;ds=sidebyside diff --git a/world.c b/world.c index 4bb4b54d..ec9942e4 100644 --- a/world.c +++ b/world.c @@ -124,6 +124,7 @@ Offset is filled in to contain the adjustment that must be added to the testing object's origin to get a point to use with the returned hull. ================ */ +extern qboolean hlbsp; hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) { model_t *model; @@ -149,12 +150,29 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset) VectorSubtract (maxs, mins, size); // LordHavoc: FIXME!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if (size[0] < 3) - hull = &model->hulls[0]; - else if (size[0] <= 32) - hull = &model->hulls[1]; + if (hlbsp) + { + if (size[0] < 3) + hull = &model->hulls[0]; // 0x0x0 + else if (size[0] <= 32) + { + if (size[2] < 54) // pick the nearest of 36 or 72 + hull = &model->hulls[3]; // 32x32x36 + else + hull = &model->hulls[1]; // 32x32x72 + } + else + hull = &model->hulls[2]; // 64x64x64 + } else - hull = &model->hulls[2]; + { + if (size[0] < 3) + hull = &model->hulls[0]; // 0x0x0 + else if (size[0] <= 32) + hull = &model->hulls[1]; // 32x32x56 + else + hull = &model->hulls[2]; // 64x64x88 + } // calculate an offset value to center the origin VectorSubtract (hull->clip_mins, mins, offset); @@ -360,7 +378,10 @@ loc0: if ( node->contents < 0) { if (ent->num_leafs == MAX_ENT_LEAFS) + { + Con_DPrintf("FindTouchedLeafs overflow\n"); return; + } leaf = (mleaf_t *)node; leafnum = leaf - sv.worldmodel->leafs - 1; @@ -417,21 +438,28 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) // set the abs box // LordHavoc: enabling rotating bmodels - if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) + if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) { // expand for rotation float max, v; int i; + max = DotProduct(ent->v.mins, ent->v.mins); + v = DotProduct(ent->v.maxs, ent->v.maxs); + if (max < v) + max = v; + max = sqrt(max); + /* max = 0; for (i=0 ; i<3 ; i++) { - v =fabs( ent->v.mins[i]); - if (v > max) + v = fabs(ent->v.mins[i]); + if (max < v) max = v; - v =fabs( ent->v.maxs[i]); - if (v > max) + v = fabs(ent->v.maxs[i]); + if (max < v) max = v; } + */ for (i=0 ; i<3 ; i++) { ent->v.absmin[i] = ent->v.origin[i] - max; @@ -465,7 +493,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) ent->v.absmax[1] += 1; ent->v.absmax[2] += 1; } - + // link to PVS leafs ent->num_leafs = 0; if (ent->v.modelindex) @@ -487,7 +515,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) else break; // crosses the node } - + // link it in if (ent->v.solid == SOLID_TRIGGER) @@ -549,6 +577,7 @@ SV_RecursiveHullCheck ================== */ +/* qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace) { dclipnode_t *node; @@ -586,16 +615,8 @@ loc0: node = hull->clipnodes + num; plane = hull->planes + node->planenum; - if (plane->type < 3) - { - t1 = p1[plane->type] - plane->dist; - t2 = p2[plane->type] - plane->dist; - } - else - { - t1 = DotProduct (plane->normal, p1) - plane->dist; - t2 = DotProduct (plane->normal, p2) - plane->dist; - } + t1 = PlaneDiff(p1, plane); + t2 = PlaneDiff(p2, plane); #if 1 if (t1 >= 0 && t2 >= 0) @@ -620,17 +641,14 @@ loc0: // put the crosspoint DIST_EPSILON pixels on the near side if (t1 < 0) - frac = (t1 + DIST_EPSILON)/(t1-t2); + frac = bound(0, (t1 + DIST_EPSILON)/(t1-t2), 1); else - frac = (t1 - DIST_EPSILON)/(t1-t2); - if (frac < 0) - frac = 0; - if (frac > 1) - frac = 1; + frac = bound(0, (t1 - DIST_EPSILON)/(t1-t2), 1); midf = p1f + (p2f - p1f)*frac; - for (i=0 ; i<3 ; i++) - mid[i] = p1[i] + frac*(p2[i] - p1[i]); + mid[0] = p1[0] + frac*(p2[0] - p1[0]); + mid[1] = p1[1] + frac*(p2[1] - p1[1]); + mid[2] = p1[2] + frac*(p2[2] - p1[2]); side = (t1 < 0); @@ -645,11 +663,12 @@ loc0: return false; } #endif - + if (SV_HullPointContents (hull, node->children[side^1], mid) != CONTENTS_SOLID) // go past the node return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); // mid would need to be duplicated during recursion... +*/ /* { p1f = midf; @@ -658,6 +677,7 @@ loc0: goto loc0; } */ +/* if (trace->allsolid) return false; // never got out of the solid area @@ -672,11 +692,7 @@ loc0: } else { - // LordHavoc: unrolled vector operation because the compiler can't be sure vec3_origin is 0 -// VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); - trace->plane.normal[0] = -plane->normal[0]; - trace->plane.normal[1] = -plane->normal[1]; - trace->plane.normal[2] = -plane->normal[2]; + VectorNegate (plane->normal, trace->plane.normal); trace->plane.dist = -plane->dist; } @@ -700,6 +716,194 @@ loc0: return false; } +*/ + +// LordHavoc: backported from my optimizations to PM_RecursiveHullCheck in QuakeForge newtree (QW) +qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace) +{ + dclipnode_t *node; + mplane_t *plane; + float t1, t2; + float frac; + int i; + vec3_t mid; + int side; + float midf; + + // LordHavoc: a goto! everyone flee in terror... :) +loc0: +// check for empty + if (num < 0) + { + if (num != CONTENTS_SOLID) + { + trace->allsolid = false; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } + else + trace->startsolid = true; + return true; // empty + } + + // LordHavoc: this can be eliminated by validating in the loader... but Mercury told me not to bother + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("SV_RecursiveHullCheck: bad node number"); + +// find the point distances + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + { + t1 = p1[plane->type] - plane->dist; + t2 = p2[plane->type] - plane->dist; + } + else + { + t1 = DotProduct (plane->normal, p1) - plane->dist; + t2 = DotProduct (plane->normal, p2) - plane->dist; + } + + // LordHavoc: recursion optimization + if (t1 >= 0 && t2 >= 0) + { + num = node->children[0]; + goto loc0; + } + if (t1 < 0 && t2 < 0) + { + num = node->children[1]; + goto loc0; + } + +// put the crosspoint DIST_EPSILON pixels on the near side + side = (t1 < 0); + if (side) + frac = bound(0, (t1 + DIST_EPSILON) / (t1 - t2), 1); + else + frac = bound(0, (t1 - DIST_EPSILON) / (t1 - t2), 1); + + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + +// move up to the node + if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) + return false; + +#ifdef PARANOID + if (SV_HullPointContents (pm_hullmodel, mid, node->children[side]) == CONTENTS_SOLID) + { + Con_Printf ("mid PointInHullSolid\n"); + return false; + } +#endif + + // LordHavoc: warning to the clumsy, this recursion can not be optimized because mid would need to be duplicated on a stack + if (SV_HullPointContents (hull, node->children[side^1], mid) != CONTENTS_SOLID) +// go past the node + return SV_RecursiveHullCheck (hull, node->children[side^1], midf, p2f, mid, p2, trace); + + if (trace->allsolid) + return false; // never got out of the solid area + +//================== +// the other side of the node is solid, this is the impact point +//================== + if (!side) + { + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + else + { + VectorNegate (plane->normal, trace->plane.normal); + trace->plane.dist = -plane->dist; + } + + while (SV_HullPointContents (hull, hull->firstclipnode, mid) == CONTENTS_SOLID) + { // shouldn't really happen, but does occasionally + frac -= 0.1; + if (frac < 0) + { + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + Con_DPrintf ("backup past 0\n"); + return false; + } + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + } + + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + + return false; +} + +qboolean SV_TestLine (hull_t *hull, int num, vec3_t p1, vec3_t p2) +{ + dclipnode_t *node; + mplane_t *plane; + float t1, t2, frac; + vec3_t mid; + int side; + +loc0: +// check for empty + if (num < 0) + return num != CONTENTS_SOLID; + + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("SV_RecursiveHullCheck: bad node number"); + +// +// find the point distances +// + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + t1 = PlaneDiff(p1, plane); + t2 = PlaneDiff(p2, plane); + + if (t1 >= 0 && t2 >= 0) + { + num = node->children[0]; + goto loc0; + } + if (t1 < 0 && t2 < 0) + { + num = node->children[1]; + goto loc0; + } + +// put the crosspoint DIST_EPSILON pixels on the near side + side = (t1 < 0); + + if (side) + frac = bound(0, (t1 + DIST_EPSILON)/(t1-t2), 1); + else + frac = bound(0, (t1 - DIST_EPSILON)/(t1-t2), 1); + + mid[0] = p1[0] + frac*(p2[0] - p1[0]); + mid[1] = p1[1] + frac*(p2[1] - p1[1]); + mid[2] = p1[2] + frac*(p2[2] - p1[2]); + + if (node->children[side] < 0) + { + if (node->children[side] == CONTENTS_SOLID) + return false; + return SV_TestLine(hull, node->children[!side], mid, p2); + } + else if (SV_TestLine(hull, node->children[side], p1, mid)) + return SV_TestLine(hull, node->children[!side], mid, p2); + else + return false; +} /* @@ -731,8 +935,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max // LordHavoc: enabling rotating bmodels // rotate start and end into the models frame of reference - if (ent->v.solid == SOLID_BSP && - (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) + if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) { vec3_t forward, right, up; vec3_t temp; @@ -755,8 +958,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max // LordHavoc: enabling rotating bmodels // rotate endpos back to world frame of reference - if (ent->v.solid == SOLID_BSP && - (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) ) + if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) { vec3_t a; vec3_t forward, right, up; @@ -764,7 +966,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max if (trace.fraction != 1) { - VectorSubtract (vec3_origin, ent->v.angles, a); + VectorNegate (ent->v.angles, a); AngleVectors (a, forward, right, up); VectorCopy (trace.endpos, temp);