29 #include "../precompiled.h"
77 p[0].ToVec3() = org - vright + vup;
78 p[0].s =
p[0].t = 0.0f;
79 p[1].ToVec3() = org + vright + vup;
80 p[1].s =
p[1].t = 0.0f;
81 p[2].ToVec3() = org + vright - vup;
82 p[2].s =
p[2].t = 0.0f;
83 p[3].ToVec3() = org - vright - vup;
84 p[3].s =
p[3].t = 0.0f;
108 counts[0] = counts[1] = counts[2] = 0;
112 dists[
i] = dot = plane.
Distance(
p[i].ToVec3() );
113 if ( dot > epsilon ) {
115 }
else if ( dot < -epsilon ) {
125 *front = *back =
NULL;
146 if ( !counts[SIDE_BACK] ) {
151 maxpts = numPoints+4;
167 if ( sides[i] == SIDE_FRONT ) {
172 if ( sides[i] == SIDE_BACK ) {
177 if ( sides[i+1] ==
SIDE_ON || sides[i+1] == sides[i] ) {
182 p2 = &
p[(i+1)%numPoints];
186 if ( sides[i] == SIDE_FRONT ) {
187 dot = dists[
i] / ( dists[
i] - dists[i+1] );
188 for ( j = 0; j < 3; j++ ) {
190 if ( plane.
Normal()[
j] == 1.0f ) {
191 mid[
j] = plane.
Dist();
192 }
else if ( plane.
Normal()[
j] == -1.0f ) {
193 mid[
j] = -plane.
Dist();
195 mid[
j] = (*p1)[
j] + dot * ( (*p2)[
j] - (*p1)[
j] );
198 mid.
s = p1->
s + dot * ( p2->
s - p1->
s );
199 mid.
t = p1->
t + dot * ( p2->
t - p1->
t );
201 dot = dists[i+1] / ( dists[i+1] - dists[
i] );
202 for ( j = 0; j < 3; j++ ) {
204 if ( plane.
Normal()[
j] == 1.0f ) {
205 mid[
j] = plane.
Dist();
206 }
else if ( plane.
Normal()[
j] == -1.0f ) {
207 mid[
j] = -plane.
Dist();
209 mid[
j] = (*p2)[
j] + dot * ( (*p1)[
j] - (*p2)[
j] );
212 mid.
s = p2->
s + dot * ( p1->
s - p2->
s );
213 mid.
t = p2->
t + dot * ( p1->
t - p2->
t );
255 dists[
i] = dot = plane.
Distance(
p[i].ToVec3() );
256 if ( dot > epsilon ) {
258 }
else if ( dot < -epsilon ) {
278 if ( !counts[SIDE_BACK] ) {
282 maxpts = numPoints + 4;
284 newPoints = (
idVec5 *) _alloca16( maxpts *
sizeof(
idVec5 ) );
290 if ( newNumPoints+1 > maxpts ) {
295 newPoints[newNumPoints] = *p1;
300 if ( sides[i] == SIDE_FRONT ) {
301 newPoints[newNumPoints] = *p1;
305 if ( sides[i+1] ==
SIDE_ON || sides[i+1] == sides[i] ) {
309 if ( newNumPoints+1 > maxpts ) {
314 p2 = &
p[(i+1)%numPoints];
316 dot = dists[
i] / (dists[
i] - dists[i+1]);
317 for ( j = 0; j < 3; j++ ) {
319 if ( plane.
Normal()[
j] == 1.0f ) {
320 mid[
j] = plane.
Dist();
321 }
else if ( plane.
Normal()[
j] == -1.0f ) {
322 mid[
j] = -plane.
Dist();
324 mid[
j] = (*p1)[
j] + dot * ( (*p2)[
j] - (*p1)[
j] );
327 mid.
s = p1->
s + dot * ( p2->
s - p1->
s );
328 mid.
t = p1->
t + dot * ( p2->
t - p1->
t );
330 newPoints[newNumPoints] = mid;
338 numPoints = newNumPoints;
339 memcpy(
p, newPoints, newNumPoints *
sizeof(
idVec5) );
370 dists[
i] = dot = plane.
Distance(
p[i].ToVec3() );
371 if ( dot > epsilon ) {
373 }
else if ( dot < -epsilon ) {
393 if ( !counts[SIDE_BACK] ) {
397 maxpts = numPoints + 4;
399 newPoints = (
idVec5 *) _alloca16( maxpts *
sizeof(
idVec5 ) );
405 if ( newNumPoints+1 > maxpts ) {
410 newPoints[newNumPoints] = *p1;
415 if ( sides[i] == SIDE_FRONT ) {
416 newPoints[newNumPoints] = *p1;
420 if ( sides[i+1] ==
SIDE_ON || sides[i+1] == sides[i] ) {
424 if ( newNumPoints+1 > maxpts ) {
429 p2 = &
p[(i+1)%numPoints];
431 dot = dists[
i] / (dists[
i] - dists[i+1]);
432 for ( j = 0; j < 3; j++ ) {
434 if ( plane.
Normal()[
j] == 1.0f ) {
435 mid[
j] = plane.
Dist();
436 }
else if ( plane.
Normal()[
j] == -1.0f ) {
437 mid[
j] = -plane.
Dist();
439 mid[
j] = (*p1)[
j] + dot * ( (*p2)[
j] - (*p1)[
j] );
442 mid.
s = p1->
s + dot * ( p2->
s - p1->
s );
443 mid.
t = p1->
t + dot * ( p2->
t - p1->
t );
445 newPoints[newNumPoints] = mid;
453 numPoints = newNumPoints;
454 memcpy(
p, newPoints, newNumPoints *
sizeof(
idVec5) );
485 w->
p[ numPoints - i - 1 ] =
p[
i];
499 for ( i = 0; i < (numPoints>>1); i++ ) {
539 for ( j = 0; j < 3; j++ ) {
542 idLib::common->
Printf(
"idWinding::Check: point %d outside world %c-axis: %f", i,
'X'+j, p1[j] );
548 j = i + 1 == numPoints ? 0 : i + 1;
551 d = p1 * plane.
Normal() + plane[3];
573 edgedist = p1 * edgenormal;
581 d =
p[
j].ToVec3() * edgenormal;
582 if ( d > edgedist ) {
605 d1 =
p[i-1].ToVec3() -
p[0].ToVec3();
606 d2 =
p[
i].ToVec3() -
p[0].ToVec3();
607 cross = d1.
Cross( d2 );
625 dir =
p[
i].ToVec3() - center;
645 center +=
p[
i].ToVec3();
666 v1 =
p[0].ToVec3() - center;
667 v2 =
p[1].ToVec3() - center;
668 normal = v2.
Cross( v1 );
670 dist =
p[0].ToVec3() * normal;
688 v1 =
p[0].ToVec3() - center;
689 v2 =
p[1].ToVec3() - center;
708 bounds[0] = bounds[1] =
p[0].ToVec3();
710 if (
p[i].
x < bounds[0].
x ) {
711 bounds[0].x =
p[
i].x;
712 }
else if (
p[i].x > bounds[1].x ) {
713 bounds[1].x =
p[
i].x;
715 if (
p[i].
y < bounds[0].
y ) {
716 bounds[0].y =
p[
i].y;
717 }
else if (
p[i].y > bounds[1].y ) {
718 bounds[1].y =
p[
i].y;
720 if (
p[i].
z < bounds[0].
z ) {
721 bounds[0].z =
p[
i].z;
722 }
else if (
p[i].z > bounds[1].z ) {
723 bounds[1].z =
p[
i].z;
737 if ( (
p[i].ToVec3() -
p[(i+numPoints-1)%numPoints].ToVec3()).LengthSqr() >=
Square( epsilon ) ) {
765 edgeNormal = (
p[
i].ToVec3() -
p[(i+numPoints-1)%numPoints].ToVec3()).Cross( normal );
767 dist = edgeNormal *
p[
i].ToVec3();
769 if (
idMath::Fabs( edgeNormal *
p[(i+1)%numPoints].ToVec3() - dist ) > epsilon ) {
797 int numNewHullPoints;
810 newHullPoints = (
idVec5 *) _alloca( maxPts *
sizeof(
idVec5 ) );
811 hullDirs = (
idVec3 *) _alloca( maxPts *
sizeof(
idVec3 ) );
812 hullSide = (
bool *) _alloca( maxPts *
sizeof(
bool ) );
814 for ( i = 0; i < winding->
numPoints; i++ ) {
818 for ( j = 0; j < this->
numPoints; j++ ) {
819 dir = this->
p[ (j + 1) % this->numPoints ].ToVec3() - this->
p[
j ].ToVec3();
821 hullDirs[
j] = normal.
Cross( dir );
826 for ( j = 0; j < this->
numPoints; j++ ) {
827 dir = p1.
ToVec3() - this->
p[
j].ToVec3();
828 d = dir * hullDirs[
j];
829 if ( d >= epsilon ) {
832 if ( d >= -epsilon ) {
845 for ( j = 0; j < this->
numPoints; j++ ) {
846 if ( !hullSide[ j ] && hullSide[ (j + 1) % this->numPoints ] ) {
850 if ( j >= this->numPoints ) {
855 newHullPoints[0] = p1;
856 numNewHullPoints = 1;
859 j = (j+1) % this->numPoints;
860 for ( k = 0; k < this->
numPoints; k++ ) {
861 if ( hullSide[ (j+k) % this->
numPoints ] && hullSide[ (j+k+1) % this->numPoints ] ) {
864 newHullPoints[numNewHullPoints] = this->
p[ (j+k+1) % this->numPoints ];
868 this->numPoints = numNewHullPoints;
869 memcpy( this->
p, newHullPoints, numNewHullPoints *
sizeof(
idVec5) );
882 int j, k, numHullPoints;
898 if (
p[0].ToVec3().Compare( point, epsilon ) ) {
901 p[1].ToVec3() = point;
907 if (
p[0].ToVec3().Compare( point, epsilon ) ||
p[1].ToVec3().Compare( point, epsilon ) ) {
911 dir = point -
p[0].ToVec3();
912 dir = dir.
Cross(
p[1].ToVec3() -
p[0].ToVec3() );
913 if ( dir[0] == 0.0
f && dir[1] == 0.0
f && dir[2] == 0.0
f ) {
917 if ( dir * normal > 0.0
f ) {
918 p[2].ToVec3() = point;
922 p[1].ToVec3() = point;
930 hullSide = (
bool *) _alloca(
numPoints *
sizeof(
bool ) );
934 dir =
p[(j + 1) % numPoints].ToVec3() -
p[
j].ToVec3();
935 hullDirs[
j] = normal.
Cross( dir );
941 dir = point -
p[
j].ToVec3();
942 d = dir * hullDirs[
j];
943 if ( d >= epsilon ) {
946 if ( d >= -epsilon ) {
960 if ( !hullSide[ j ] && hullSide[ (j + 1) % numPoints ] ) {
964 if ( j >= numPoints ) {
968 hullPoints = (
idVec5 *) _alloca( (numPoints+1) *
sizeof(
idVec5 ) );
971 hullPoints[0] = point;
975 j = (j+1) % numPoints;
977 if ( hullSide[ (j+k) %
numPoints ] && hullSide[ (j+k+1) % numPoints ] ) {
980 hullPoints[numHullPoints] =
p[ (j+k+1) % numPoints ];
987 numPoints = numHullPoints;
988 memcpy(
p, hullPoints, numHullPoints *
sizeof(
idVec5) );
996 #define CONTINUOUS_EPSILON 0.005f
999 idVec3 *p1, *p2, *p3, *p4, *back;
1021 for (k = 0; k < 3; k++ ) {
1047 delta = (*p1) - (*back);
1048 normal = planenormal.
Cross(delta);
1052 delta = (*back) - (*p1);
1053 dot = delta * normal;
1061 delta = (*back) - (*p2);
1062 normal = planenormal.
Cross( delta );
1066 delta = (*back) - (*p2);
1067 dot = delta * normal;
1081 if ( !keep && k == (i+1) % f1->
numPoints && !keep2 ) {
1091 if ( !keep && l == (j+1) % f2->
numPoints && !keep1 ) {
1107 if ( point < 0 || point >=
numPoints ) {
1111 memmove(&
p[point], &
p[point+1], (
numPoints - point - 1) *
sizeof(
p[0]) );
1158 normal = (
p[(i+1)%numPoints].ToVec3() -
p[
i].ToVec3()).Cross( plane.
Normal() );
1160 dist = normal *
p[
i].ToVec3();
1162 if (
idMath::Fabs( normal * point - dist ) > epsilon ) {
1167 dot = normal * point;
1169 dist = dot - normal *
p[
i].ToVec3();
1171 if ( dist < epsilon ) {
1173 if ( dist > -epsilon ) {
1179 dist = dot - normal *
p[(i+1)%numPoints].ToVec3();
1181 if ( dist > -epsilon ) {
1183 if ( dist < epsilon ) {
1200 #define EDGE_LENGTH 0.2f
1210 delta =
p[(i+1)%numPoints].ToVec3() -
p[
i].ToVec3();
1213 if ( ++edges == 3 ) {
1230 for ( j = 0; j < 3; j++ ) {
1301 if ( d < -epsilon ) {
1308 else if ( d > epsilon ) {
1331 #define WCONVEX_EPSILON 0.2f
1362 dir =
p[(i+1) % numPoints].ToVec3() -
p[
i].ToVec3();
1363 pointvec = point -
p[
i].ToVec3();
1365 n = dir.
Cross( normal );
1367 if ( pointvec * n < -epsilon ) {
1380 float front, back, frac;
1383 front = windingPlane.
Distance( start );
1384 back = windingPlane.
Distance( end );
1387 if ( front < 0.0
f && back < 0.0
f ) {
1391 if ( front > 0.0
f && back > 0.0
f ) {
1396 if ( backFaceCull && front < 0.0
f ) {
1405 frac = front / (front - back);
1406 mid[0] = start[0] + (end[0] - start[0]) * frac;
1407 mid[1] = start[1] + (end[1] - start[1]) * frac;
1408 mid[2] = start[2] + (end[2] - start[2]) * frac;
1421 bool side, lastside =
false;
1427 pl2.
FromLine(
p[i].ToVec3(),
p[(i+1)%numPoints].ToVec3() );
1429 if ( i && side != lastside ) {
1434 if ( !backFaceCull || lastside ) {
1452 cross = v1.
Cross( v2 );
1453 return 0.5f * cross.
Length();
1498 dists[
i] = dot = plane.
Distance(
p[i].ToVec3() );
1499 if ( dot > epsilon ) {
1501 }
else if ( dot < -epsilon ) {
1522 sides[
i] = sides[0];
1523 dists[
i] = dists[0];
1546 if ( sides[i] == SIDE_FRONT ) {
1550 if ( sides[i] == SIDE_BACK ) {
1555 if ( sides[i+1] ==
SIDE_ON || sides[i+1] == sides[i] ) {
1569 if ( j >= numPoints ) {
1576 dot = dists[
i] / (dists[
i] - dists[i+1]);
1577 for ( j = 0; j < 3; j++ ) {
1579 if ( plane.
Normal()[
j] == 1.0f ) {
1580 mid[
j] = plane.
Dist();
1581 }
else if ( plane.
Normal()[
j] == -1.0f ) {
1582 mid[
j] = -plane.
Dist();
1584 mid[
j] = (*p1)[
j] + dot * ( (*p2)[
j] - (*p1)[
j] );
1587 mid.
s = p1->
s + dot * ( p2->
s - p1->
s );
1588 mid.
t = p1->
t + dot * ( p2->
t - p1->
t );
void GetBounds(idBounds &bounds) const
static const float INFINITY
void RemoveEqualPoints(const float epsilon=ON_EPSILON)
float GetArea(void) const
void cross(float a[], float b[], float c[])
assert(prefInfo.fullscreenBtn)
const idVec3 & Normal(void) const
bool LineIntersection(const idPlane &windingPlane, const idVec3 &start, const idVec3 &end, bool backFaceCull=false) const
#define CONTINUOUS_EPSILON
const idVec3 & ToVec3(void) const
void AddToConvexHull(const idWinding *winding, const idVec3 &normal, const float epsilon=ON_EPSILON)
GLenum GLenum GLenum GLenum GLenum scale
float Distance(const idVec3 &v) const
idWinding * TryMerge(const idWinding &w, const idVec3 &normal, int keep=false) const
static float Sqrt(float x)
idWinding * Reverse(void) const
void SetNormal(const idVec3 &normal)
idWinding * Clip(const idPlane &plane, const float epsilon=ON_EPSILON, const bool keepOn=false)
idVec3 Cross(const idVec3 &a) const
bool PlanesConcave(const idWinding &w2, const idVec3 &normal1, const idVec3 &normal2, float dist1, float dist2) const
int Split(idFixedWinding *back, const idPlane &plane, const float epsilon=ON_EPSILON)
bool InsertPointIfOnEdge(const idVec3 &point, const idPlane &plane, const float epsilon=ON_EPSILON)
void FromLine(const idVec3 &start, const idVec3 &end)
virtual bool ReAllocate(int n, bool keep=false)
int PlaneSide(const idPlane &plane, const float epsilon=ON_EPSILON) const
void InsertPoint(const idVec3 &point, int spot)
bool EnsureAlloced(int n, bool keep=false)
GLfloat GLfloat GLfloat v2
#define FLOATSIGNBITSET(f)
#define MAX_POINTS_ON_WINDING
GLubyte GLubyte GLubyte GLubyte w
static float Fabs(float f)
static float TriangleArea(const idVec3 &a, const idVec3 &b, const idVec3 &c)
virtual void virtual void FatalError(const char *fmt,...) id_attribute((format(printf
void GetPlane(idVec3 &normal, float &dist) const
float PermutedInnerProduct(const idPluecker &a) const
void FromRay(const idVec3 &start, const idVec3 &dir)
bool Check(bool print=true) const
GLubyte GLubyte GLubyte a
bool RayIntersection(const idVec3 &start, const idVec3 &dir, float &scale) const
virtual void Printf(const char *fmt,...) id_attribute((format(printf
float Normalize(bool fixDegenerate=true)
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
int Split(const idPlane &plane, const float epsilon, idWinding **front, idWinding **back) const
GLdouble GLdouble GLdouble r
#define FLOATSIGNBITNOTSET(f)
bool PointInside(const idVec3 &normal, const idVec3 &point, const float epsilon) const
virtual bool ReAllocate(int n, bool keep=false)
idVec3 GetCenter(void) const
idWinding * Copy(void) const
void BaseForPlane(const idVec3 &normal, const float dist)
float GetRadius(const idVec3 ¢er) const
void RemovePoint(int point)
float dot(float a[], float b[])
float PlaneDistance(const idPlane &plane) const
bool ClipInPlace(const idPlane &plane, const float epsilon=ON_EPSILON, const bool keepOn=false)
bool RayIntersection(const idPlane &windingPlane, const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull=false) const
void NormalVectors(idVec3 &left, idVec3 &down) const
void RemoveColinearPoints(const idVec3 &normal, const float epsilon=ON_EPSILON)
static class idCommon * common
void FitThroughPoint(const idVec3 &p)