@@ -18,55 +18,65 @@ is not a staircase.
1818
1919=============
2020*/
21- bool M_CheckBottom_Fast_Generic (const Vector3 &absmins, const Vector3 &absmaxs, bool ceiling) {
22- // FIXME - this will only handle 0,0,1 and 0,0,-1 gravity vectors
23- Vector3 start{};
24-
25- start[2 ] = absmins[2 ] - 1 ;
26- if (ceiling)
27- start[2 ] = absmaxs[2 ] + 1 ;
28-
29- for (int x = 0 ; x <= 1 ; x++)
30- for (int y = 0 ; y <= 1 ; y++) {
31- start[0 ] = x ? absmaxs[0 ] : absmins[0 ];
32- start[1 ] = y ? absmaxs[1 ] : absmins[1 ];
21+ bool M_CheckBottom_Fast_Generic (const Vector3 &absmins, const Vector3 &absmaxs, const Vector3 &gravityDir) {
22+ Vector3 start;
23+ int majorAxis = 0 ;
24+ if (fabsf (gravityDir[1 ]) > fabsf (gravityDir[0 ])) majorAxis = 1 ;
25+ if (fabsf (gravityDir[2 ]) > fabsf (gravityDir[majorAxis])) majorAxis = 2 ;
26+
27+ int axis1 = (majorAxis + 1 ) % 3 ;
28+ int axis2 = (majorAxis + 2 ) % 3 ;
29+
30+ if (gravityDir[majorAxis] > 0 ) // ceiling / up
31+ start[majorAxis] = absmaxs[majorAxis] + 1 ;
32+ else // floor / down
33+ start[majorAxis] = absmins[majorAxis] - 1 ;
34+
35+ for (int i = 0 ; i <= 1 ; i++)
36+ for (int j = 0 ; j <= 1 ; j++) {
37+ start[axis1] = i ? absmaxs[axis1] : absmins[axis1];
38+ start[axis2] = j ? absmaxs[axis2] : absmins[axis2];
3339 if (gi.pointContents (start) != CONTENTS_SOLID)
3440 return false ;
3541 }
3642
3743 return true ; // we got out easy
3844}
3945
40- bool M_CheckBottom_Slow_Generic (const Vector3 &origin, const Vector3 &mins, const Vector3 &maxs, gentity_t *ignore, contents_t mask, bool ceiling, bool allow_any_step_height) {
41- Vector3 start{};
46+ bool M_CheckBottom_Slow_Generic (const Vector3 &origin, const Vector3 &mins, const Vector3 &maxs, gentity_t *ignore, contents_t mask, const Vector3 &gravityDir, bool allow_any_step_height) {
47+ Vector3 start, stop;
48+ int majorAxis = 0 ;
49+ if (fabsf (gravityDir[1 ]) > fabsf (gravityDir[0 ])) majorAxis = 1 ;
50+ if (fabsf (gravityDir[2 ]) > fabsf (gravityDir[majorAxis])) majorAxis = 2 ;
51+
52+ int axis1 = (majorAxis + 1 ) % 3 ;
53+ int axis2 = (majorAxis + 2 ) % 3 ;
4254
4355 //
4456 // check it for real...
4557 //
4658 Vector3 step_quadrant_size = (maxs - mins) * 0 .5f ;
47- step_quadrant_size. z = 0 ;
59+ step_quadrant_size[majorAxis] = 0 ;
4860
4961 Vector3 half_step_quadrant = step_quadrant_size * 0 .5f ;
5062 Vector3 half_step_quadrant_mins = -half_step_quadrant;
5163
52- Vector3 stop;
53-
54- start[0 ] = stop[0 ] = origin.x ;
55- start[1 ] = stop[1 ] = origin.y ;
64+ start[axis1] = stop[axis1] = origin[axis1];
65+ start[axis2] = stop[axis2] = origin[axis2];
5666
57- if (!ceiling ) {
58- start[2 ] = origin. z + mins. z ;
59- stop[2 ] = start[2 ] - STEPSIZE * 2 ;
60- } else {
61- start[2 ] = origin. z + maxs. z ;
62- stop[2 ] = start[2 ] + STEPSIZE * 2 ;
67+ if (gravityDir[majorAxis] > 0 ) { // ceiling / up
68+ start[majorAxis ] = origin[majorAxis] + maxs[majorAxis] ;
69+ stop[majorAxis ] = start[majorAxis] + STEPSIZE * 2 ;
70+ } else { // floor / down
71+ start[majorAxis ] = origin[majorAxis] + mins[majorAxis] ;
72+ stop[majorAxis ] = start[majorAxis] - STEPSIZE * 2 ;
6373 }
6474
65- Vector3 mins_no_z = mins;
66- Vector3 maxs_no_z = maxs;
67- mins_no_z. z = maxs_no_z. z = 0 ;
75+ Vector3 mins_flat = mins;
76+ Vector3 maxs_flat = maxs;
77+ mins_flat[majorAxis] = maxs_flat[majorAxis] = 0 ;
6878
69- trace_t trace = gi.trace (start, mins_no_z, maxs_no_z , stop, ignore, mask);
79+ trace_t trace = gi.trace (start, mins_flat, maxs_flat , stop, ignore, mask);
7080
7181 if (trace.fraction == 1 .0f )
7282 return false ;
@@ -75,37 +85,36 @@ bool M_CheckBottom_Slow_Generic(const Vector3 &origin, const Vector3 &mins, cons
7585 if (allow_any_step_height)
7686 return true ;
7787
78- start[0 ] = stop[0 ] = origin. x + ((mins. x + maxs. x ) * 0 .5f );
79- start[1 ] = stop[1 ] = origin. y + ((mins. y + maxs. y ) * 0 .5f );
88+ start[axis1 ] = stop[axis1 ] = origin[axis1] + ((mins[axis1] + maxs[axis1] ) * 0 .5f );
89+ start[axis2 ] = stop[axis2 ] = origin[axis2] + ((mins[axis2] + maxs[axis2] ) * 0 .5f );
8090
81- float mid = trace.endPos [2 ];
91+ float mid = trace.endPos [majorAxis ];
8292
8393 // the corners must be within 16 of the midpoint
84- for (int32_t x = 0 ; x <= 1 ; x ++)
85- for (int32_t y = 0 ; y <= 1 ; y ++) {
94+ for (int32_t i = 0 ; i <= 1 ; i ++)
95+ for (int32_t j = 0 ; j <= 1 ; j ++) {
8696 Vector3 quadrant_start = start;
8797
88- if (x )
89- quadrant_start. x += half_step_quadrant. x ;
98+ if (i )
99+ quadrant_start[axis1] += half_step_quadrant[axis1] ;
90100 else
91- quadrant_start. x -= half_step_quadrant. x ;
101+ quadrant_start[axis1] -= half_step_quadrant[axis1] ;
92102
93- if (y )
94- quadrant_start. y += half_step_quadrant. y ;
103+ if (j )
104+ quadrant_start[axis2] += half_step_quadrant[axis2] ;
95105 else
96- quadrant_start. y -= half_step_quadrant. y ;
106+ quadrant_start[axis2] -= half_step_quadrant[axis2] ;
97107
98108 Vector3 quadrant_end = quadrant_start;
99- quadrant_end. z = stop. z ;
109+ quadrant_end[majorAxis] = stop[majorAxis] ;
100110
101111 trace = gi.trace (quadrant_start, half_step_quadrant_mins, half_step_quadrant, quadrant_end, ignore, mask);
102112
103- // FIXME - this will only handle 0,0,1 and 0,0,-1 gravity vectors
104- if (ceiling) {
105- if (trace.fraction == 1 .0f || trace.endPos [2 ] - mid > (STEPSIZE))
113+ if (gravityDir[majorAxis] > 0 ) {
114+ if (trace.fraction == 1 .0f || trace.endPos [majorAxis] - mid > (STEPSIZE))
106115 return false ;
107116 } else {
108- if (trace.fraction == 1 .0f || mid - trace.endPos [2 ] > (STEPSIZE))
117+ if (trace.fraction == 1 .0f || mid - trace.endPos [majorAxis ] > (STEPSIZE))
109118 return false ;
110119 }
111120 }
@@ -117,11 +126,11 @@ bool M_CheckBottom(gentity_t *ent) {
117126 // if all of the points under the corners are solid world, don't bother
118127 // with the tougher checks
119128
120- if (M_CheckBottom_Fast_Generic (ent->s .origin + ent->mins , ent->s .origin + ent->maxs , ent->gravityVector [ 2 ] > 0 ))
129+ if (M_CheckBottom_Fast_Generic (ent->s .origin + ent->mins , ent->s .origin + ent->maxs , ent->gravityVector ))
121130 return true ; // we got out easy
122131
123132 contents_t mask = (ent->svFlags & SVF_MONSTER) ? MASK_MONSTERSOLID : (MASK_SOLID | CONTENTS_MONSTER | CONTENTS_PLAYER);
124- return M_CheckBottom_Slow_Generic (ent->s .origin , ent->mins , ent->maxs , ent, mask, ent->gravityVector [ 2 ] > 0 , ent->spawnFlags .has (SPAWNFLAG_MONSTER_SUPER_STEP));
133+ return M_CheckBottom_Slow_Generic (ent->s .origin , ent->mins , ent->maxs , ent, mask, ent->gravityVector , ent->spawnFlags .has (SPAWNFLAG_MONSTER_SUPER_STEP));
125134}
126135
127136static bool IsBadAhead (gentity_t *self, gentity_t *bad, const Vector3 &move) {
0 commit comments