29 #include "../precompiled.h"
42 static int boxVertPlanes[8] = {
43 ( (1<<0) | (1<<2) | (1<<4) ),
44 ( (1<<1) | (1<<2) | (1<<4) ),
45 ( (1<<1) | (1<<3) | (1<<4) ),
46 ( (1<<0) | (1<<3) | (1<<4) ),
47 ( (1<<0) | (1<<2) | (1<<5) ),
48 ( (1<<1) | (1<<2) | (1<<5) ),
49 ( (1<<1) | (1<<3) | (1<<5) ),
50 ( (1<<0) | (1<<3) | (1<<5) ),
62 ax[0] = extents[0] * axis[0];
63 ax[1] = extents[1] * axis[1];
64 ax[2] = extents[2] * axis[2];
65 temp[0] = center - ax[0];
66 temp[1] = center + ax[0];
67 temp[2] = ax[1] - ax[2];
68 temp[3] = ax[1] + ax[2];
69 points[0] = temp[0] - temp[3];
70 points[1] = temp[1] - temp[3];
71 points[2] = temp[1] + temp[2];
72 points[3] = temp[0] + temp[2];
73 points[4] = temp[0] - temp[2];
74 points[5] = temp[1] - temp[2];
75 points[6] = temp[1] + temp[3];
76 points[7] = temp[0] + temp[3];
88 if ( min + plane[3] > 0.0
f ) {
89 return min + plane[3];
91 if ( max + plane[3] < 0.0
f ) {
92 return max + plane[3];
106 if ( min + plane[3] > epsilon ) {
109 if ( max + plane[3] < epsilon ) {
156 d1 =
dNear - localOrigin.
x;
160 if ( d1 - d2 > 0.0
f ) {
165 d1 = localOrigin.
x -
dFar;
166 if ( d1 - d2 > 0.0
f ) {
170 testOrigin = localOrigin;
171 testAxis = localAxis;
173 if ( testOrigin.
y < 0.0f ) {
174 testOrigin.
y = -testOrigin.
y;
175 testAxis[0][1] = -testAxis[0][1];
176 testAxis[1][1] = -testAxis[1][1];
177 testAxis[2][1] = -testAxis[2][1];
185 if ( d1 - d2 > 0.0
f ) {
189 if ( testOrigin.
z < 0.0f ) {
190 testOrigin.
z = -testOrigin.
z;
191 testAxis[0][2] = -testAxis[0][2];
192 testAxis[1][2] = -testAxis[1][2];
193 testAxis[2][2] = -testAxis[2][2];
197 d1 =
dFar * testOrigin.
z -
dUp * testOrigin.
x;
201 if ( d1 - d2 > 0.0
f ) {
219 idVec3 localOrigin, center, extents;
222 center = ( bounds[0] + bounds[1] ) * 0.5
f;
223 extents = bounds[1] - center;
264 float d,
r, rs, sFar;
271 if (
dNear - center.
x > r ) {
276 if ( center.
x -
dFar > r ) {
285 if ( ( d * d ) > rs * ( sFar +
dLeft *
dLeft ) ) {
291 if ( ( d * d ) > rs * ( sFar +
dUp *
dUp ) ) {
310 float dx, dy, dz, leftScale, upScale;
313 dy = -localFrustum.
axis[1].x;
314 dz = -localFrustum.
axis[2].x;
316 dx = -cornerVecs[
index].
x;
319 if ( indexPoints[index].
x <
dNear ) {
324 dy = localFrustum.
axis[1].x;
325 dz = localFrustum.
axis[2].x;
330 if ( indexPoints[index].
x >
dFar ) {
343 if ( indexPoints[index].
y > indexPoints[index].
x * leftScale ) {
354 if ( indexPoints[index].
y < -indexPoints[index].
x * leftScale ) {
367 if ( indexPoints[index].
z > indexPoints[index].
x * upScale ) {
378 if ( indexPoints[index].
z < -indexPoints[index].
x * upScale ) {
397 idVec3 indexPoints[8], cornerVecs[4];
400 localFrustum = frustum;
415 int i, pCull, culled;
416 float leftScale, upScale;
422 for ( i = 0; i < numPoints; i++ ) {
428 else if ( p.
x >
dFar ) {
438 pointCull[
i] = pCull;
441 return ( culled != 0 );
455 pointCull = (
int *) _alloca16( winding.
GetNumPoints() *
sizeof(
int ) );
459 localPoints[
i] = ( winding[
i].ToVec3() -
origin ) * transpose;
476 dy = -localFrustum.
axis[1].x;
477 dz = -localFrustum.
axis[2].x;
479 dx = -cornerVecs[
index].
x;
482 if ( indexPoints[index].
x < bounds[0].
x ) {
486 dy = localFrustum.
axis[1].x;
487 dz = localFrustum.
axis[2].x;
492 if ( indexPoints[index].x > bounds[1].x ) {
496 dy = -localFrustum.
axis[1].y;
497 dz = -localFrustum.
axis[2].y;
499 dx = -cornerVecs[
index].
y;
502 if ( indexPoints[index].
y < bounds[0].
y ) {
506 dy = localFrustum.
axis[1].y;
507 dz = localFrustum.
axis[2].y;
512 if ( indexPoints[index].y > bounds[1].y ) {
516 dy = -localFrustum.
axis[1].z;
517 dz = -localFrustum.
axis[2].z;
519 dx = -cornerVecs[
index].
z;
522 if ( indexPoints[index].
z < bounds[0].
z ) {
526 dy = localFrustum.
axis[1].z;
527 dz = localFrustum.
axis[2].z;
532 if ( indexPoints[index].z > bounds[1].z ) {
549 float d1, d2, fstart, fend, lstart, lend,
f,
x;
550 float leftScale, upScale;
558 if (
dNear > 0.0f ) {
559 d1 =
dNear - start.x;
564 f = d1 / ( d1 - d2 );
580 f = d1 / ( d1 - d2 );
589 fstart =
dFar * start.y;
591 lstart =
dLeft * start.x;
595 d1 = fstart - lstart;
600 f = d1 / ( d1 - d2 );
601 x = start.x + f * dir.
x;
611 d1 = -fstart - lstart;
616 f = d1 / ( d1 - d2 );
617 x = start.x + f * dir.
x;
626 fstart =
dFar * start.z;
628 lstart =
dUp * start.x;
632 d1 = fstart - lstart;
637 f = d1 / ( d1 - d2 );
638 x = start.x + f * dir.
x;
640 if (
idMath::Fabs( start.y + f * dir.
y ) <= x * leftScale ) {
648 d1 = -fstart - lstart;
653 f = d1 / ( d1 - d2 );
654 x = start.x + f * dir.
x;
656 if (
idMath::Fabs( start.y + f * dir.
y ) <= x * leftScale ) {
663 return ( startInside != 0 );
676 float d1, d2, fstart, fend, lstart, lend,
f,
x;
677 float leftScale, upScale;
688 if (
dNear > 0.0f ) {
693 f = d1 / ( d1 - d2 );
696 if ( f < scale1 ) scale1 =
f;
697 if ( f > scale2 ) scale2 =
f;
708 f = d1 / ( d1 - d2 );
711 if ( f < scale1 ) scale1 =
f;
712 if ( f > scale2 ) scale2 =
f;
717 fstart =
dFar * start.
y;
723 d1 = fstart - lstart;
727 f = d1 / ( d1 - d2 );
728 x = start.
x + f * dir.x;
731 if ( f < scale1 ) scale1 =
f;
732 if ( f > scale2 ) scale2 =
f;
738 d1 = -fstart - lstart;
742 f = d1 / ( d1 - d2 );
743 x = start.
x + f * dir.x;
746 if ( f < scale1 ) scale1 =
f;
747 if ( f > scale2 ) scale2 =
f;
752 fstart =
dFar * start.
z;
754 lstart =
dUp * start.
x;
758 d1 = fstart - lstart;
762 f = d1 / ( d1 - d2 );
763 x = start.
x + f * dir.x;
765 if (
idMath::Fabs( start.
y + f * dir.y ) <= x * leftScale ) {
766 if ( f < scale1 ) scale1 =
f;
767 if ( f > scale2 ) scale2 =
f;
773 d1 = -fstart - lstart;
777 f = d1 / ( d1 - d2 );
778 x = start.
x + f * dir.x;
780 if (
idMath::Fabs( start.
y + f * dir.y ) <= x * leftScale ) {
781 if ( f < scale1 ) scale1 =
f;
782 if ( f > scale2 ) scale2 =
f;
787 return ( startInside != 0 );
808 for ( i = 0; i < 4; i++ ) {
813 if ( testFirstSide ) {
814 for ( i = 0; i < 4; i++ ) {
820 for ( i = 0; i < 4; i++ ) {
838 for ( i = 0; i < 4; i++ ) {
844 for ( i = 0; i < 4; i++ ) {
850 for ( i = 0; i < 4; i++ ) {
865 idVec3 localOrigin, center, extents;
868 center = ( bounds[0] + bounds[1] ) * 0.5
f;
869 extents = bounds[1] - center;
874 if (
CullLocalBox( localOrigin, extents, localAxis ) ) {
878 idVec3 indexPoints[8], cornerVecs[4];
886 idSwap( indexPoints[2], indexPoints[3] );
887 idSwap( indexPoints[6], indexPoints[7] );
893 BoxToPoints( localOrigin, extents, localAxis, indexPoints );
918 idVec3 indexPoints[8], cornerVecs[4];
921 localFrustum = *
this;
930 idSwap( indexPoints[2], indexPoints[3] );
931 idSwap( indexPoints[6], indexPoints[7] );
953 #define VORONOI_INDEX( x, y, z ) ( x + y * 3 + z * 9 )
974 else if ( p.
x >=
dFar ) {
983 if ( dir.
y > 0.0f ) {
986 if ( dir.
z > 0.0f ) {
1056 idVec3 indexPoints2[8], cornerVecs2[4];
1059 localFrustum2 = frustum;
1068 idVec3 indexPoints1[8], cornerVecs1[4];
1071 localFrustum1 = *
this;
1076 if ( frustum.
CullLocalFrustum( localFrustum1, indexPoints1, cornerVecs1 ) ) {
1080 idSwap( indexPoints2[2], indexPoints2[3] );
1081 idSwap( indexPoints2[6], indexPoints2[7] );
1087 idSwap( indexPoints1[2], indexPoints1[3] );
1088 idSwap( indexPoints1[6], indexPoints1[7] );
1103 int i,
j, *pointCull;
1105 idVec3 *localPoints, indexPoints[8], cornerVecs[4];
1110 pointCull = (
int *) _alloca16( winding.
GetNumPoints() *
sizeof(
int ) );
1114 localPoints[
i] = ( winding[
i].ToVec3() -
origin ) * transpose;
1128 if ( min + plane[3] > 0.0
f || max + plane[3] < 0.0
f ) {
1135 if ( !( pointCull[i] & pointCull[j] ) ) {
1142 idSwap( indexPoints[2], indexPoints[3] );
1143 idSwap( indexPoints[6], indexPoints[7] );
1146 for ( i = 0; i < 4; i++ ) {
1147 if ( winding.
LineIntersection( plane, indexPoints[i], indexPoints[4+i] ) ) {
1152 for ( i = 0; i < 4; i++ ) {
1153 if ( winding.
LineIntersection( plane, indexPoints[i], indexPoints[(i+1)&3] ) ) {
1158 for ( i = 0; i < 4; i++ ) {
1159 if ( winding.
LineIntersection( plane, indexPoints[4+i], indexPoints[4+((i+1)&3)] ) ) {
1191 if ( scale1 <= scale2 ) {
1217 float value, bestValue;
1224 dir = box.
GetCenter() - projectionOrigin;
1231 for ( i = 1; i < 3; i++ ) {
1241 int j, minX, minY, maxY, minZ, maxZ;
1244 minX = minY = maxY = minZ = maxZ = 0;
1246 for ( j = 0; j < 2; j++ ) {
1250 axis[1].Normalize();
1255 if ( points[0].
x <= 1.0
f ) {
1259 minX = minY = maxY = minZ = maxZ = 0;
1260 for ( i = 1; i < 8; i++ ) {
1261 if ( points[i].
x <= 1.0
f ) {
1264 if ( points[i].
x < points[minX].
x ) {
1267 if ( points[minY].x * points[i].
y < points[i].x * points[minY].
y ) {
1269 }
else if ( points[maxY].x * points[i].y > points[i].x * points[maxY].y ) {
1272 if ( points[minZ].x * points[i].
z < points[i].x * points[minZ].
z ) {
1274 }
else if ( points[maxZ].x * points[i].z > points[i].x * points[maxZ].z ) {
1286 this->
origin = projectionOrigin;
1287 this->
dNear = points[minX].
x;
1300 for ( j = 0; j < 2; j++ ) {
1304 axis[1].Normalize();
1310 for ( i = 0; i < 8; i++ ) {
1328 this->
origin = projectionOrigin;
1329 this->
dNear = b[0][0];
1342 axis[1].Normalize();
1345 for ( i = 0; i < 3; i++ ) {
1351 dist[0] =
axis[0] * ( box.
GetCenter() - projectionOrigin ) - dist[0];
1352 if ( dist[0] <= 1.0f ) {
1355 float invDist = 1.0f / dist[0];
1357 this->
origin = projectionOrigin;
1358 this->
dNear = dist[0];
1361 this->
dUp = dist[2] * invDist *
dFar;
1378 float d,
r,
s,
x,
y;
1382 dir = sphere.
GetOrigin() - projectionOrigin;
1386 if ( d <= r + 1.0
f ) {
1391 origin = projectionOrigin;
1419 if ( newdFar <=
dNear ) {
1439 if ( newdFar <=
dNear ) {
1459 if ( newdFar <=
dNear ) {
1479 if ( newdFar <=
dNear ) {
1506 points[0] = scaled[0] + scaled[1];
1507 points[1] = -scaled[0] + scaled[1];
1508 points[2] = -scaled[0] - scaled[1];
1509 points[3] = scaled[0] - scaled[1];
1511 for ( i = 0; i < 4; i++ ) {
1512 planes[i+2].
Normal() = points[
i].
Cross( points[(i+1)&3] - points[i] );
1530 points[0] = scaled[0] + scaled[1];
1531 points[1] = scaled[0] - scaled[1];
1532 points[2] = points[1] - scaled[2];
1533 points[3] = points[0] - scaled[2];
1534 points[0] += scaled[2];
1535 points[1] += scaled[2];
1541 points[4] = scaled[0] + scaled[1];
1542 points[5] = scaled[0] - scaled[1];
1543 points[6] = points[5] - scaled[2];
1544 points[7] = points[4] - scaled[2];
1545 points[4] += scaled[2];
1546 points[5] += scaled[2];
1561 points[0] = scaled[0] + scaled[1];
1562 points[1] = scaled[0] - scaled[1];
1563 points[2] = points[1] - scaled[2];
1564 points[3] = points[0] - scaled[2];
1565 points[0] += scaled[2];
1566 points[1] += scaled[2];
1572 points[4] = scaled[0] + scaled[1];
1573 points[5] = scaled[0] - scaled[1];
1574 points[6] = points[5] - scaled[2];
1575 points[7] = points[4] - scaled[2];
1576 points[4] += scaled[2];
1577 points[5] += scaled[2];
1579 points[4] =
origin + fractions[0] * points[4];
1580 points[5] =
origin + fractions[1] * points[5];
1581 points[6] =
origin + fractions[2] * points[6];
1582 points[7] =
origin + fractions[3] * points[7];
1597 indexPoints[0] = scaled[0] - scaled[1];
1598 indexPoints[2] = scaled[0] + scaled[1];
1599 indexPoints[1] = indexPoints[0] + scaled[2];
1600 indexPoints[3] = indexPoints[2] + scaled[2];
1601 indexPoints[0] -= scaled[2];
1602 indexPoints[2] -= scaled[2];
1608 indexPoints[4] = scaled[0] - scaled[1];
1609 indexPoints[6] = scaled[0] + scaled[1];
1610 indexPoints[5] = indexPoints[4] + scaled[2];
1611 indexPoints[7] = indexPoints[6] + scaled[2];
1612 indexPoints[4] -= scaled[2];
1613 indexPoints[6] -= scaled[2];
1630 indexPoints[0] = scaled[0] - scaled[1];
1631 indexPoints[2] = scaled[0] + scaled[1];
1632 indexPoints[1] = indexPoints[0] + scaled[2];
1633 indexPoints[3] = indexPoints[2] + scaled[2];
1634 indexPoints[0] -= scaled[2];
1635 indexPoints[2] -= scaled[2];
1641 cornerVecs[0] = scaled[0] - scaled[1];
1642 cornerVecs[2] = scaled[0] + scaled[1];
1643 cornerVecs[1] = cornerVecs[0] + scaled[2];
1644 cornerVecs[3] = cornerVecs[2] + scaled[2];
1645 cornerVecs[0] -= scaled[2];
1646 cornerVecs[2] -= scaled[2];
1648 indexPoints[4] = cornerVecs[0] +
origin;
1649 indexPoints[5] = cornerVecs[1] +
origin;
1650 indexPoints[6] = cornerVecs[2] +
origin;
1651 indexPoints[7] = cornerVecs[3] +
origin;
1670 min = indexPoints[
index] * dir;
1672 dx = -dir.
x * cornerVecs[
index].
x - dir.y * cornerVecs[
index].
y - dir.z * cornerVecs[
index].
z;
1674 max = indexPoints[
index] * dir;
1685 idVec3 indexPoints[8], cornerVecs[4];
1699 idVec3 indexPoints[8], cornerVecs[4];
1702 AxisProjection( indexPoints, cornerVecs, ax[0], bounds[0][0], bounds[1][0] );
1703 AxisProjection( indexPoints, cornerVecs, ax[1], bounds[0][1], bounds[1][1] );
1704 AxisProjection( indexPoints, cornerVecs, ax[2], bounds[0][2], bounds[1][2] );
1714 float d1, d2, fstart, fend, lstart, lend,
f;
1715 float leftScale, upScale;
1718 #ifdef FRUSTUM_DEBUG
1720 if ( r_showInteractionScissors.
GetInteger() > 1 ) {
1729 fstart =
dFar * start.y;
1730 fend =
dFar * end.
y;
1731 lstart =
dLeft * start.x;
1735 d1 = -fstart + lstart;
1741 f = d1 / ( d1 - d2 );
1742 p.
x = start.x + f * dir.
x;
1744 p.
z = start.z + f * dir.
z;
1755 d1 = fstart + lstart;
1761 f = d1 / ( d1 - d2 );
1762 p.
x = start.x + f * dir.
x;
1764 p.
z = start.z + f * dir.
z;
1774 fstart =
dFar * start.z;
1775 fend =
dFar * end.
z;
1776 lstart =
dUp * start.x;
1780 d1 = -fstart + lstart;
1786 f = d1 / ( d1 - d2 );
1787 p.
x = start.x + f * dir.
x;
1789 p.
y = start.y + f * dir.
y;
1800 d1 = fstart + lstart;
1806 f = d1 / ( d1 - d2 );
1807 p.
x = start.x + f * dir.
x;
1809 p.
y = start.y + f * dir.
y;
1819 if ( cull1 == 0 && start.x > 0.0f ) {
1823 p.
z = start.z *
dFar / ( start.x *
dUp );
1827 if ( cull2 == 0 && end.
x > 0.0f ) {
1835 if ( start.x < bounds[0].x ) {
1836 bounds[0].x = start.x < 0.0f ? 0.0f : start.x;
1838 if ( end.
x < bounds[0].x ) {
1839 bounds[0].x = end.
x < 0.0f ? 0.0f : end.
x;
1853 float d1, d2, fstart, fend, lstart, lend,
f;
1854 float leftScale, upScale;
1857 clip = startCull ^ endCull;
1862 #ifdef FRUSTUM_DEBUG
1864 if ( r_showInteractionScissors.
GetInteger() > 1 ) {
1873 if ( clip & (1|2) ) {
1875 fstart =
dFar * start.y;
1876 fend =
dFar * end.
y;
1877 lstart =
dLeft * start.x;
1882 d1 = -fstart + lstart;
1886 f = d1 / ( d1 - d2 );
1887 p.
x = start.x + f * dir.
x;
1889 p.
z = start.z + f * dir.
z;
1902 d1 = fstart + lstart;
1906 f = d1 / ( d1 - d2 );
1907 p.
x = start.x + f * dir.
x;
1909 p.
z = start.z + f * dir.
z;
1921 if ( clip & (4|8) ) {
1923 fstart =
dFar * start.z;
1924 fend =
dFar * end.
z;
1925 lstart =
dUp * start.x;
1930 d1 = -fstart + lstart;
1934 f = d1 / ( d1 - d2 );
1935 p.
x = start.x + f * dir.
x;
1937 p.
y = start.y + f * dir.
y;
1950 d1 = fstart + lstart;
1954 f = d1 / ( d1 - d2 );
1955 p.
x = start.x + f * dir.
x;
1957 p.
y = start.y + f * dir.
y;
1981 int i, startInside = 1;
1988 for ( i = 0; i < 2; i++ ) {
1989 d1 = start.
x - bounds[
i].x;
1991 d2 = end.
x - bounds[
i].x;
1993 f = d1 / ( d1 - d2 );
1994 p.
y = start.
y + f * dir.y;
1995 if ( bounds[0].
y <= p.
y && p.
y <= bounds[1].y ) {
1996 p.
z = start.
z + f * dir.z;
1997 if ( bounds[0].
z <= p.
z && p.
z <= bounds[1].z ) {
1998 if ( f < scale1 ) scale1 =
f;
1999 if ( f > scale2 ) scale2 =
f;
2004 d1 = start.
y - bounds[
i].y;
2006 d2 = end.
y - bounds[
i].y;
2008 f = d1 / ( d1 - d2 );
2009 p.
x = start.
x + f * dir.x;
2010 if ( bounds[0].
x <= p.
x && p.
x <= bounds[1].x ) {
2011 p.
z = start.
z + f * dir.z;
2012 if ( bounds[0].
z <= p.
z && p.
z <= bounds[1].z ) {
2013 if ( f < scale1 ) scale1 =
f;
2014 if ( f > scale2 ) scale2 =
f;
2019 d1 = start.
z - bounds[
i].z;
2021 d2 = end.
z - bounds[
i].z;
2023 f = d1 / ( d1 - d2 );
2024 p.
x = start.
x + f * dir.x;
2025 if ( bounds[0].
x <= p.
x && p.
x <= bounds[1].x ) {
2026 p.
y = start.
y + f * dir.y;
2027 if ( bounds[0].
y <= p.
y && p.
y <= bounds[1].y ) {
2028 if ( f < scale1 ) scale1 =
f;
2029 if ( f > scale2 ) scale2 =
f;
2035 return ( startInside != 0 );
2055 int i, p1, p2, pointCull[8], culled, outside;
2056 float scale1, scale2;
2059 idMat3 localAxis, localScaled;
2065 float boxMin, boxMax, base;
2070 projectionBounds[0].x = boxMin - base;
2071 projectionBounds[1].x = boxMax - base;
2072 projectionBounds[0].y = projectionBounds[0].z = -1.0f;
2073 projectionBounds[1].y = projectionBounds[1].z = 1.0f;
2078 projectionBounds.
Clear();
2088 for ( i = 0; i < 4; i++ ) {
2092 culled &= pointCull[p1] & pointCull[p2];
2093 outside |= pointCull[p1] | pointCull[p2];
2107 for ( i = 0; i < 4; i++ ) {
2113 for ( i = 0; i < 4; i++ ) {
2120 if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) {
2124 localScaled[0] *=
dFar;
2125 localScaled[1] *=
dLeft;
2126 localScaled[2] *=
dUp;
2129 if ( (outside & 2) && (outside & 8) ) {
2130 BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 );
2131 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2136 if ( (outside & 2) && (outside & 4) ) {
2137 BoundsRayIntersection( bounds, localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 );
2138 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2143 if ( (outside & 1) && (outside & 8) ) {
2144 BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 );
2145 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2150 if ( (outside & 1) && (outside & 2) ) {
2151 BoundsRayIntersection( bounds, localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 );
2152 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2170 float d,
r, rs, sFar;
2173 projectionBounds.
Clear();
2182 if ( ( d * d ) > rs * ( sFar +
dLeft *
dLeft ) ) {
2188 if ( ( d * d ) > rs * ( sFar +
dUp *
dUp ) ) {
2193 projectionBounds[0].x = 0.0f;
2194 projectionBounds[1].x =
dFar;
2195 projectionBounds[0].y = projectionBounds[0].z = -1.0f;
2196 projectionBounds[1].y = projectionBounds[1].z = 1.0f;
2206 int i, p1, p2, pointCull[8], culled, outside;
2207 float scale1, scale2;
2215 float frustumMin, frustumMax, base;
2220 projectionBounds[0].x = frustumMin - base;
2221 projectionBounds[1].x = frustumMax - base;
2222 projectionBounds[0].y = projectionBounds[0].z = -1.0f;
2223 projectionBounds[1].y = projectionBounds[1].z = 1.0f;
2227 projectionBounds.
Clear();
2230 localFrustum = frustum;
2238 for ( i = 0; i < 4; i++ ) {
2242 culled &= pointCull[p1] & pointCull[p2];
2243 outside |= pointCull[p1] | pointCull[p2];
2257 if ( localFrustum.
dNear > 0.0f ) {
2258 for ( i = 0; i < 4; i++ ) {
2265 for ( i = 0; i < 4; i++ ) {
2272 if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) {
2276 localScaled[0] *=
dFar;
2277 localScaled[1] *=
dLeft;
2278 localScaled[2] *=
dUp;
2281 if ( (outside & 2) && (outside & 8) ) {
2282 frustum.
LocalRayIntersection( localOrigin, localScaled[0] - localScaled[1] - localScaled[2], scale1, scale2 );
2283 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2288 if ( (outside & 2) && (outside & 4) ) {
2289 frustum.
LocalRayIntersection( localOrigin, localScaled[0] - localScaled[1] + localScaled[2], scale1, scale2 );
2290 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2295 if ( (outside & 1) && (outside & 8) ) {
2296 frustum.
LocalRayIntersection( localOrigin, localScaled[0] + localScaled[1] - localScaled[2], scale1, scale2 );
2297 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2302 if ( (outside & 1) && (outside & 2) ) {
2303 frustum.
LocalRayIntersection( localOrigin, localScaled[0] + localScaled[1] + localScaled[2], scale1, scale2 );
2304 if ( scale1 <= scale2 && scale1 >= 0.0
f ) {
2320 int i, p1, p2, *pointCull, culled, outside;
2326 projectionBounds.
Clear();
2332 localPoints[
i] = ( winding[
i].ToVec3() -
origin ) * transpose;
2338 pointCull = (
int *) _alloca16( winding.
GetNumPoints() *
sizeof(
int ) );
2343 culled &= pointCull[p1] & pointCull[p2];
2344 outside |= pointCull[p1] | pointCull[p2];
2365 if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) {
2373 if ( (outside & 2) && (outside & 8) ) {
2378 if ( (outside & 2) && (outside & 4) ) {
2383 if ( (outside & 1) && (outside & 8) ) {
2388 if ( (outside & 1) && (outside & 2) ) {
2409 idVec3 localOrigin, cornerVecs[4];
2417 scaled[0] = localAxis[0] *
dFar;
2418 scaled[1] = localAxis[1] *
dLeft;
2419 scaled[2] = localAxis[2] *
dUp;
2420 cornerVecs[0] = scaled[0] + scaled[1];
2421 cornerVecs[1] = scaled[0] - scaled[1];
2422 cornerVecs[2] = cornerVecs[1] - scaled[2];
2423 cornerVecs[3] = cornerVecs[0] - scaled[2];
2424 cornerVecs[0] += scaled[2];
2425 cornerVecs[1] += scaled[2];
2432 for ( i = 0; i < 4; i++ ) {
2435 f = ( bounds[
index].x - localOrigin.
x ) / cornerVecs[i].x;
2436 clipFractions[
i] =
f;
2437 clipPlanes[
i] = 1 <<
index;
2440 f = ( bounds[
index].y - localOrigin.
y ) / cornerVecs[i].y;
2441 if ( f < clipFractions[i] ) {
2442 clipFractions[
i] =
f;
2443 clipPlanes[
i] = 4 <<
index;
2447 f = ( bounds[
index].z - localOrigin.
z ) / cornerVecs[i].z;
2448 if ( f < clipFractions[i] ) {
2449 clipFractions[
i] =
f;
2450 clipPlanes[
i] = 16 <<
index;
2454 if ( clipFractions[i] < minf ) {
2455 clipFractions[
i] = minf;
2469 float d1, d2, fstart, fend, lstart, lend,
f,
x;
2470 float leftScale, upScale;
2471 float scale1, scale2;
2472 int startCull, endCull;
2473 idVec3 localStart, localEnd, localDir;
2478 localStart = localPoints[startIndex];
2479 localEnd = localPoints[endIndex];
2480 localDir = localEnd - localStart;
2482 startClip = endClip = -1;
2486 fstart =
dFar * localStart.y;
2487 fend =
dFar * localEnd.
y;
2488 lstart =
dLeft * localStart.x;
2489 lend =
dLeft * localEnd.
x;
2492 d1 = -fstart + lstart;
2498 f = d1 / ( d1 - d2 );
2499 x = localStart.x + f * localDir.
x;
2501 if (
idMath::Fabs( localStart.z + f * localDir.
z ) <= x * upScale ) {
2502 if ( f < scale1 ) { scale1 =
f; startClip = 0; }
2503 if ( f > scale2 ) { scale2 =
f; endClip = 0; }
2510 d1 = fstart + lstart;
2516 f = d1 / ( d1 - d2 );
2517 x = localStart.x + f * localDir.
x;
2519 if (
idMath::Fabs( localStart.z + f * localDir.
z ) <= x * upScale ) {
2520 if ( f < scale1 ) { scale1 =
f; startClip = 1; }
2521 if ( f > scale2 ) { scale2 =
f; endClip = 1; }
2527 fstart =
dFar * localStart.z;
2528 fend =
dFar * localEnd.
z;
2529 lstart =
dUp * localStart.x;
2530 lend =
dUp * localEnd.
x;
2533 d1 = -fstart + lstart;
2539 f = d1 / ( d1 - d2 );
2540 x = localStart.x + f * localDir.
x;
2542 if (
idMath::Fabs( localStart.y + f * localDir.
y ) <= x * leftScale ) {
2543 if ( f < scale1 ) { scale1 =
f; startClip = 2; }
2544 if ( f > scale2 ) { scale2 =
f; endClip = 2; }
2551 d1 = fstart + lstart;
2557 f = d1 / ( d1 - d2 );
2558 x = localStart.x + f * localDir.
x;
2560 if (
idMath::Fabs( localStart.y + f * localDir.
y ) <= x * leftScale ) {
2561 if ( f < scale1 ) { scale1 =
f; startClip = 3; }
2562 if ( f > scale2 ) { scale2 =
f; endClip = 3; }
2569 if ( !( startCull | endCull ) ) {
2570 start = points[startIndex];
2571 end = points[endIndex];
2574 else if ( scale1 <= scale2 ) {
2576 start = points[startIndex];
2580 start = points[startIndex] + scale1 * ( points[endIndex] - points[startIndex] );
2583 end = points[endIndex];
2587 end = points[startIndex] + scale2 * ( points[endIndex] - points[startIndex] );
2599 static int capPointIndex[4][2] = {
2609 if ( pointClip < 0 ) {
2612 p = capPointIndex[pointClip];
2624 int i, p1, p2, clipPointCull[8], clipPlanes[4], usedClipPlanes, nearCull, farCull, outside;
2625 int pointCull[2], startClip, endClip, boxPointCull[8];
2626 float clipFractions[4], s1, s2, t1, t2, leftScale, upScale;
2628 idVec3 clipPoints[8], localPoints1[8], localPoints2[8], localOrigin1, localOrigin2,
start,
end;
2635 float clipBoxMin, clipBoxMax, frustumMin, frustumMax, base;
2641 projectionBounds[0].x =
Max( clipBoxMin, frustumMin ) - base;
2642 projectionBounds[1].x =
Min( clipBoxMax, frustumMax ) - base;
2643 projectionBounds[0].y = projectionBounds[0].z = -1.0f;
2644 projectionBounds[1].y = projectionBounds[1].z = 1.0f;
2648 projectionBounds.
Clear();
2652 usedClipPlanes = clipPlanes[0] | clipPlanes[1] | clipPlanes[2] | clipPlanes[3];
2657 localFrustum = frustum;
2663 for ( i = 0; i < 4; i++ ) {
2670 outside = clipPointCull[0] | clipPointCull[1] | clipPointCull[2] | clipPointCull[3] |
2671 clipPointCull[4] | clipPointCull[5] | clipPointCull[6] | clipPointCull[7];
2672 nearCull = clipPointCull[0] & clipPointCull[1] & clipPointCull[2] & clipPointCull[3];
2673 farCull = clipPointCull[4] & clipPointCull[5] & clipPointCull[6] & clipPointCull[7];
2679 if ( !nearCull && localFrustum.
dNear > 0.0f ) {
2680 for ( i = 0; i < 4; i++ ) {
2688 for ( i = 0; i < 4; i++ ) {
2697 if ( !( farCull && !( nearCull & farCull ) ) &&
2699 ( clipPlanes[0] != clipPlanes[1] || clipPlanes[1] != clipPlanes[2] || clipPlanes[2] != clipPlanes[3] ) ) {
2702 transpose = frustum.
axis;
2711 for ( i = 0; i < 8; i++ ) {
2713 if ( !( boxVertPlanes[i] & usedClipPlanes ) || p.
x <= 0.0f ) {
2714 boxPointCull[
i] = 1|2|4|8;
2717 boxPointCull[
i] = 0;
2735 for ( i = 0; i < 4; i++ ) {
2738 if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) {
2739 if ( frustum.
ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) {
2743 outside |= pointCull[0] | pointCull[1];
2748 for ( i = 0; i < 4; i++ ) {
2751 if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) {
2752 if ( frustum.
ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) {
2756 outside |= pointCull[0] | pointCull[1];
2761 for ( i = 0; i < 4; i++ ) {
2764 if ( !( boxPointCull[p1] & boxPointCull[p2] ) ) {
2765 if ( frustum.
ClipLine( localPoints1, localPoints2, p1, p2, start, end, startClip, endClip ) ) {
2769 outside |= pointCull[0] | pointCull[1];
2776 if ( outside != 1 && outside != 2 && outside != 4 && outside != 8 ) {
2779 transpose = frustum.
axis;
2781 localOrigin1 = (
origin - frustum.
origin ) * transpose;
2783 localAxis1[0] *=
dFar;
2784 localAxis1[1] *=
dLeft;
2785 localAxis1[2] *=
dUp;
2788 transpose = clipBox.
GetAxis();
2792 localAxis2[0] *=
dFar;
2793 localAxis2[1] *=
dLeft;
2794 localAxis2[2] *=
dUp;
2800 if ( (outside & 2) && (outside & 8) ) {
2801 frustum.
LocalRayIntersection( localOrigin1, localAxis1[0] - localAxis1[1] - localAxis1[2], s1, s2 );
2802 if ( s1 <= s2 && s1 >= 0.0
f ) {
2803 BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] - localAxis2[1] - localAxis2[2], t1, t2 );
2804 if ( t1 <= t2 && t2 > s1 && t1 < s2 ) {
2810 if ( (outside & 2) && (outside & 4) ) {
2811 frustum.
LocalRayIntersection( localOrigin1, localAxis1[0] - localAxis1[1] + localAxis1[2], s1, s2 );
2812 if ( s1 <= s2 && s1 >= 0.0
f ) {
2813 BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] - localAxis2[1] + localAxis2[2], t1, t2 );
2814 if ( t1 <= t2 && t2 > s1 && t1 < s2 ) {
2820 if ( (outside & 1) && (outside & 8) ) {
2821 frustum.
LocalRayIntersection( localOrigin1, localAxis1[0] + localAxis1[1] - localAxis1[2], s1, s2 );
2822 if ( s1 <= s2 && s1 >= 0.0
f ) {
2823 BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] + localAxis2[1] - localAxis2[2], t1, t2 );
2824 if ( t1 <= t2 && t2 > s1 && t1 < s2 ) {
2830 if ( (outside & 1) && (outside & 2) ) {
2831 frustum.
LocalRayIntersection( localOrigin1, localAxis1[0] + localAxis1[1] + localAxis1[2], s1, s2 );
2832 if ( s1 <= s2 && s1 >= 0.0
f ) {
2833 BoundsRayIntersection( clipBounds, localOrigin2, localAxis2[0] + localAxis2[1] + localAxis2[2], t1, t2 );
2834 if ( t1 <= t2 && t2 > s1 && t1 < s2 ) {
void AxisProjection(const idVec3 &dir, float &min, float &max) const
float PlaneDistance(const idPlane &plane) const
static float ATan16(float a)
bool CullSphere(const idSphere &sphere) const
bool ConstrainToBox(const idBox &box)
GLsizei const GLfloat * points
const idVec3 & GetOrigin(void) const
static const float INFINITY
idMat3 ToMat3(void) const
GLsizei const GLfloat * value
assert(prefInfo.fullscreenBtn)
const idVec3 & Normal(void) const
idMat3 mat3_identity(idVec3(1, 0, 0), idVec3(0, 1, 0), idVec3(0, 0, 1))
void ToIndexPointsAndCornerVecs(idVec3 indexPoints[8], idVec3 cornerVecs[4]) const
bool CullFrustum(const idFrustum &frustum) const
void ToPoints(idVec3 points[8]) const
bool LocalRayIntersection(const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2) const
bool LineIntersection(const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull=false) const
bool LocalLineIntersection(const idVec3 &start, const idVec3 &end) const
const idVec3 & GetExtents(void) const
void ClipFrustumToBox(const idBox &box, float clipFractions[4], int clipPlanes[4]) const
static float Tan16(float a)
ID_INLINE T Max(T x, T y)
void AddLocalLineToProjectionBoundsUseCull(const idVec3 &start, const idVec3 &end, int startCull, int endCull, idBounds &bounds) const
void MoveFarDistance(float dFar)
GLenum GLenum GLenum GLenum GLenum scale
idMat3 Transpose(void) const
bool IntersectsBounds(const idBounds &bounds) const
bool ConstrainToBounds(const idBounds &bounds)
void ToPlanes(idPlane planes[6]) const
bool LineIntersection(const idVec3 &start, const idVec3 &end) const
static float Sqrt(float x)
idVec3 Cross(const idVec3 &a) const
bool CullLocalBox(const idVec3 &localOrigin, const idVec3 &extents, const idMat3 &localAxis) const
void AddLocalLineToProjectionBoundsSetCull(const idVec3 &start, const idVec3 &end, int &startCull, int &endCull, idBounds &bounds) const
bool AddLocalCapsToProjectionBounds(const idVec3 endPoints[4], const int endPointCull[4], const idVec3 &point, int pointCull, int pointClip, idBounds &projectionBounds) const
bool ProjectionBounds(const idBounds &bounds, idBounds &projectionBounds) const
bool ContainsPoint(const idVec3 &p) const
bool CullLocalWinding(const idVec3 *points, const int numPoints, int *pointCull) const
bool CullBox(const idBox &box) const
bool ContainsPoint(const idVec3 &point) const
bool ClipLine(const idVec3 localPoints[8], const idVec3 points[8], int startIndex, int endIndex, idVec3 &start, idVec3 &end, int &startClip, int &endClip) const
bool AddPoint(const idVec3 &v)
bool IntersectsBox(const idBox &box) const
bool LocalFrustumIntersectsFrustum(const idVec3 points[8], const bool testFirstSide) const
#define FLOATSIGNBITSET(f)
virtual void DebugLine(const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime=0, const bool depthTest=false)=0
int GetNumPoints(void) const
void SetDist(const float dist)
idVec3 vec3_origin(0.0f, 0.0f, 0.0f)
static float Fabs(float f)
float GetRadius(void) const
int PlaneSide(const idPlane &plane, const float epsilon=ON_EPSILON) const
bool CullWinding(const class idWinding &winding) const
bool IntersectsWinding(const idWinding &winding) const
int GetInteger(void) const
void GetPlane(idVec3 &normal, float &dist) const
bool LocalFrustumIntersectsBounds(const idVec3 points[8], const idBounds &bounds) const
void ToClippedPoints(const float fractions[4], idVec3 points[8]) const
bool LineIntersection(const idVec3 &start, const idVec3 &end) const
float Normalize(bool fixDegenerate=true)
const idMat3 & GetAxis(void) const
ID_INLINE void idSwap(type &a, type &b)
GLsizei GLboolean transpose
void ToIndexPoints(idVec3 indexPoints[8]) const
idCVar r_showInteractionScissors("r_showInteractionScissors","0", CVAR_RENDERER|CVAR_INTEGER,"1 = show screen rectangle which contains the interaction frustum, 2 = also draw construction lines", 0, 2, idCmdSystem::ArgCompletion_Integer< 0, 2 >)
#define VORONOI_INDEX(x, y, z)
const idVec3 & GetCenter(void) const
GLdouble GLdouble GLdouble r
bool ClippedProjectionBounds(const idFrustum &frustum, const idBox &clipBox, idBounds &projectionBounds) const
bool ConstrainToSphere(const idSphere &sphere)
bool LineIntersection(const idVec3 &start, const idVec3 &end) const
#define FLOATSIGNBITNOTSET(f)
bool FromProjection(const idBounds &bounds, const idVec3 &projectionOrigin, const float dFar)
bool IntersectsFrustum(const idFrustum &frustum) const
bool CullBounds(const idBounds &bounds) const
bool CullLocalFrustum(const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4]) const
bool BoundsRayIntersection(const idBounds &bounds, const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2) const
bool RayIntersection(const idVec3 &start, const idVec3 &dir, float &scale1, float &scale2) const
void AxisProjection(const idVec3 &dir, float &min, float &max) const
void AxisProjection(const idVec3 &dir, float &min, float &max) const
void BoxToPoints(const idVec3 ¢er, const idVec3 &extents, const idMat3 &axis, idVec3 points[8])
bool ConstrainToFrustum(const idFrustum &frustum)
ID_INLINE T Min(T x, T y)
bool RayIntersection(const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull=false) const
bool CullPoint(const idVec3 &point) const
void AxisProjection(const idVec3 &dir, float &min, float &max) const
bool IntersectsSphere(const idSphere &sphere) const
idMat3 & TransposeSelf(void)
void FitThroughPoint(const idVec3 &p)
bool BoundsCullLocalFrustum(const idBounds &bounds, const idFrustum &localFrustum, const idVec3 indexPoints[8], const idVec3 cornerVecs[4]) const