29 #include "../precompiled.h"
38 ID_INLINE
int UpdateVertexIndex(
int vertexIndexNum[2],
int *vertexRemap,
int *vertexCopyIndex,
int vertNum ) {
40 vertexIndexNum[0] = vertexRemap[vertNum];
41 vertexRemap[vertNum] = vertexIndexNum[
s];
42 vertexIndexNum[1] +=
s;
43 vertexCopyIndex[vertexRemap[vertNum]] = vertNum;
44 return vertexRemap[vertNum];
57 int * edgeSplitVertex;
58 int numEdgeSplitVertexes;
60 int vertexIndexNum[2][2];
61 int * vertexCopyIndex[2];
65 int * onPlaneEdges[2];
66 int numOnPlaneEdges[2];
75 counts[0] = counts[1] = counts[2] = 0;
78 for ( i = 0; i <
verts.
Num(); i++ ) {
82 }
else if ( f < -epsilon ) {
90 *front = *back =
NULL;
110 if ( !counts[SIDE_BACK] ) {
119 edgeSplitVertex = (
int *) _alloca(
edges.Num() *
sizeof(
int ) );
120 numEdgeSplitVertexes = 0;
122 maxOnPlaneEdges = 4 * counts[
SIDE_ON];
126 for ( i = 0; i <
edges.Num(); i++ ) {
129 int sidesOr = ( sides[
v0] | sides[
v1] );
132 if ( !( sides[v0] ^ sides[v1] ) || ( sidesOr &
SIDE_ON ) ) {
133 edgeSplitVertex[
i] = -1;
137 f = dists[
v0] / ( dists[
v0] - dists[
v1] );
139 edgeSplitVertex[
i] = numEdgeSplitVertexes++;
146 surface[0]->
indexes.
Resize( ( ( counts[SIDE_FRONT] + counts[
SIDE_ON] ) * 2 ) + ( numEdgeSplitVertexes * 4 ) );
147 surface[1]->
indexes.
Resize( ( ( counts[SIDE_BACK] + counts[SIDE_ON] ) * 2 ) + ( numEdgeSplitVertexes * 4 ) );
150 vertexRemap[0] = (
int *) _alloca(
verts.
Num() *
sizeof(
int ) );
151 memset( vertexRemap[0], -1,
verts.
Num() *
sizeof(
int ) );
152 vertexRemap[1] = (
int *) _alloca(
verts.
Num() *
sizeof(
int ) );
153 memset( vertexRemap[1], -1,
verts.
Num() *
sizeof(
int ) );
155 vertexCopyIndex[0] = (
int *) _alloca( ( numEdgeSplitVertexes +
verts.
Num() ) *
sizeof(
int ) );
156 vertexCopyIndex[1] = (
int *) _alloca( ( numEdgeSplitVertexes +
verts.
Num() ) *
sizeof(
int ) );
158 vertexIndexNum[0][0] = vertexIndexNum[1][0] = 0;
159 vertexIndexNum[0][1] = vertexIndexNum[1][1] = numEdgeSplitVertexes;
166 maxOnPlaneEdges += 4 * numEdgeSplitVertexes;
168 onPlaneEdges[0] = (
int *) _alloca( ( maxOnPlaneEdges + 1 ) *
sizeof(
int ) );
169 onPlaneEdges[1] = (
int *) _alloca( ( maxOnPlaneEdges + 1 ) *
sizeof(
int ) );
170 numOnPlaneEdges[0] = numOnPlaneEdges[1] = 0;
186 if ( ( sides[v0] & sides[v1] & sides[v2] ) & SIDE_ON ) {
191 s = ( sides[
v0] | sides[
v1] | sides[
v2] ) & SIDE_BACK;
194 onPlaneEdges[
s][numOnPlaneEdges[
s]] =
n;
195 numOnPlaneEdges[
s] += ( sides[
v0] & sides[
v1] ) >> 1;
196 onPlaneEdges[
s][numOnPlaneEdges[
s]] = n+1;
197 numOnPlaneEdges[
s] += ( sides[
v1] & sides[
v2] ) >> 1;
198 onPlaneEdges[
s][numOnPlaneEdges[
s]] = n+2;
199 numOnPlaneEdges[
s] += ( sides[
v2] & sides[
v0] ) >> 1;
201 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
202 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
203 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
210 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
212 index[n++] = edgeSplitVertex[e0];
213 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
214 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
218 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
220 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
221 index[n++] = edgeSplitVertex[e0];
222 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
229 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
231 index[n++] = edgeSplitVertex[e1];
232 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
233 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
237 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
239 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
240 index[n++] = edgeSplitVertex[e1];
241 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
248 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
250 index[n++] = edgeSplitVertex[e1];
251 index[n++] = edgeSplitVertex[e0];
252 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
256 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
258 index[n++] = edgeSplitVertex[e0];
259 index[n++] = edgeSplitVertex[e1];
260 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
261 index[n++] = edgeSplitVertex[e1];
262 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
263 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
270 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
272 index[n++] = edgeSplitVertex[e2];
273 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
274 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
278 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
280 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
281 index[n++] = edgeSplitVertex[e2];
282 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
289 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
291 index[n++] = edgeSplitVertex[e0];
292 index[n++] = edgeSplitVertex[e2];
293 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
297 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
299 index[n++] = edgeSplitVertex[e2];
300 index[n++] = edgeSplitVertex[e0];
301 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
302 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
303 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
304 index[n++] = edgeSplitVertex[e2];
311 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
313 index[n++] = edgeSplitVertex[e2];
314 index[n++] = edgeSplitVertex[e1];
315 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v2 );
319 onPlaneEdges[
s][numOnPlaneEdges[
s]++] =
n;
321 index[n++] = edgeSplitVertex[e1];
322 index[n++] = edgeSplitVertex[e2];
323 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
324 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v0 );
325 index[n++] =
UpdateVertexIndex( vertexIndexNum[s], vertexRemap[s], vertexCopyIndex[s], v1 );
326 index[n++] = edgeSplitVertex[e2];
337 surface[0]->
verts.
SetNum( vertexIndexNum[0][1],
false );
338 index = vertexCopyIndex[0];
339 for ( i = numEdgeSplitVertexes; i < surface[0]->
verts.
Num(); i++ ) {
342 surface[1]->
verts.
SetNum( vertexIndexNum[1][1],
false );
343 index = vertexCopyIndex[1];
344 for ( i = numEdgeSplitVertexes; i < surface[1]->
verts.
Num(); i++ ) {
352 if ( frontOnPlaneEdges ) {
353 memcpy( frontOnPlaneEdges, onPlaneEdges[0], numOnPlaneEdges[0] *
sizeof(
int ) );
354 frontOnPlaneEdges[numOnPlaneEdges[0]] = -1;
357 if ( backOnPlaneEdges ) {
358 memcpy( backOnPlaneEdges, onPlaneEdges[1], numOnPlaneEdges[1] *
sizeof(
int ) );
359 backOnPlaneEdges[numOnPlaneEdges[1]] = -1;
376 int * edgeSplitVertex;
378 int vertexIndexNum[2];
379 int * vertexCopyIndex;
382 int numEdgeSplitVertexes;
390 counts[0] = counts[1] = counts[2] = 0;
393 for ( i = 0; i <
verts.
Num(); i++ ) {
397 }
else if ( f < -epsilon ) {
422 if ( !counts[SIDE_BACK] ) {
426 edgeSplitVertex = (
int *) _alloca(
edges.Num() *
sizeof(
int ) );
427 numEdgeSplitVertexes = 0;
432 for ( i = 0; i <
edges.Num(); i++ ) {
437 if ( !( sides[v0] ^ sides[v1] ) || ( ( sides[
v0] | sides[
v1] ) &
SIDE_ON ) ) {
438 edgeSplitVertex[
i] = -1;
439 counts[(sides[
v0]|sides[
v1]) & SIDE_BACK]++;
441 f = dists[
v0] / ( dists[
v0] - dists[
v1] );
443 edgeSplitVertex[
i] = numEdgeSplitVertexes++;
450 newIndexes.
Resize( ( counts[SIDE_FRONT] << 1 ) + ( numEdgeSplitVertexes << 2 ) );
453 vertexRemap = (
int *) _alloca(
verts.
Num() *
sizeof(
int ) );
454 memset( vertexRemap, -1,
verts.
Num() *
sizeof(
int ) );
456 vertexCopyIndex = (
int *) _alloca( ( numEdgeSplitVertexes +
verts.
Num() ) *
sizeof(
int ) );
458 vertexIndexNum[0] = 0;
459 vertexIndexNum[1] = numEdgeSplitVertexes;
461 indexPtr = newIndexes.
Ptr();
462 indexNum = newIndexes.
Num();
466 int e0, e1, e2,
v0,
v1,
v2;
478 if ( ( sides[v0] | sides[v1] | sides[v2] ) & SIDE_BACK ) {
481 if ( ( sides[v0] & sides[v1] & sides[v2] ) &
SIDE_ON ) {
491 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
492 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
493 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
497 if ( !( sides[v0] & SIDE_BACK ) ) {
498 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
499 indexPtr[indexNum++] = edgeSplitVertex[e0];
500 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
502 indexPtr[indexNum++] = edgeSplitVertex[e0];
503 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
504 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
509 if ( !( sides[v1] & SIDE_BACK ) ) {
510 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
511 indexPtr[indexNum++] = edgeSplitVertex[e1];
512 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
514 indexPtr[indexNum++] = edgeSplitVertex[e1];
515 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
516 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
521 if ( !( sides[v1] & SIDE_BACK ) ) {
522 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
523 indexPtr[indexNum++] = edgeSplitVertex[e1];
524 indexPtr[indexNum++] = edgeSplitVertex[e0];
526 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
527 indexPtr[indexNum++] = edgeSplitVertex[e0];
528 indexPtr[indexNum++] = edgeSplitVertex[e1];
529 indexPtr[indexNum++] = edgeSplitVertex[e1];
530 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
531 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
536 if ( !( sides[v2] & SIDE_BACK ) ) {
537 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
538 indexPtr[indexNum++] = edgeSplitVertex[e2];
539 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
541 indexPtr[indexNum++] = edgeSplitVertex[e2];
542 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
543 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
548 if ( !( sides[v0] & SIDE_BACK ) ) {
549 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
550 indexPtr[indexNum++] = edgeSplitVertex[e0];
551 indexPtr[indexNum++] = edgeSplitVertex[e2];
553 indexPtr[indexNum++] = edgeSplitVertex[e0];
554 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
555 indexPtr[indexNum++] = edgeSplitVertex[e2];
556 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
557 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
558 indexPtr[indexNum++] = edgeSplitVertex[e2];
563 if ( !( sides[v2] & SIDE_BACK ) ) {
564 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v2 );
565 indexPtr[indexNum++] = edgeSplitVertex[e2];
566 indexPtr[indexNum++] = edgeSplitVertex[e1];
568 indexPtr[indexNum++] = edgeSplitVertex[e2];
569 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
570 indexPtr[indexNum++] = edgeSplitVertex[e1];
571 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v0 );
572 indexPtr[indexNum++] =
UpdateVertexIndex( vertexIndexNum, vertexRemap, vertexCopyIndex, v1 );
573 indexPtr[indexNum++] = edgeSplitVertex[e2];
580 newIndexes.
SetNum( indexNum,
false );
583 newVerts.
SetNum( vertexIndexNum[1],
false );
584 for ( i = numEdgeSplitVertexes; i < newVerts.
Num(); i++ ) {
585 newVerts[
i] =
verts[vertexCopyIndex[
i]];
603 int i,
j, numIslands, numTris;
604 int queueStart, queueEnd;
605 int *queue, *islandNum;
606 int curTri, nextTri, edgeNum;
611 islandNum = (
int *) _alloca16( numTris *
sizeof(
int ) );
612 memset( islandNum, -1, numTris *
sizeof(
int ) );
613 queue = (
int *) _alloca16( numTris *
sizeof(
int ) );
615 for ( i = 0; i < numTris; i++ ) {
617 if ( islandNum[i] != -1 ) {
624 islandNum[
i] = numIslands;
626 for ( curTri = queue[queueStart]; queueStart < queueEnd; curTri = queue[++queueStart] ) {
630 for ( j = 0; j < 3; j++ ) {
635 if ( nextTri == -1 ) {
641 if ( islandNum[nextTri] != -1 ) {
645 queue[queueEnd++] = nextTri;
646 islandNum[nextTri] = numIslands;
652 return ( numIslands == 1 );
661 for (
int i = 0;
i <
edges.Num();
i++ ) {
685 for ( j = 0; j <
verts.
Num(); j++ ) {
705 for ( i = 0; i <
verts.
Num(); i++ ) {
741 for ( i = 0; i <
verts.
Num(); i++ ) {
743 if ( d < -epsilon ) {
750 else if ( d > epsilon ) {
777 return ( scale >= 0.0
f && scale <= 1.0
f );
786 int i, i0,
i1,
i2, s0, s1, s2;
798 for ( i = 0; i <
edges.Num(); i++ ) {
813 if ( s0 & s1 & s2 ) {
819 }
else if ( !backFaceCull && !(s0 | s1 | s2) ) {
843 int *
index, *vertexEdges, *edgeChain;
846 vertexEdges = (
int *) _alloca16(
verts.
Num() *
sizeof(
int ) );
847 memset( vertexEdges, -1,
verts.
Num() *
sizeof(
int ) );
848 edgeChain = (
int *) _alloca16(
indexes.
Num() *
sizeof(
int ) );
856 edges.Append( e[0] );
867 e[0].
verts[1] = index[s^1];
870 e[1].
verts[1] = index[s^3];
873 e[2].
verts[1] = index[s^2];
875 for ( j = 0; j < 3; j++ ) {
878 for ( edgeNum = vertexEdges[v0]; edgeNum >= 0; edgeNum = edgeChain[edgeNum] ) {
886 edgeNum =
edges.Append( e[j] );
887 edgeChain[edgeNum] = vertexEdges[
v0];
888 vertexEdges[
v0] = edgeNum;
891 if ( index[j] == v0 ) {
893 edges[edgeNum].tris[0] =
i;
897 edges[edgeNum].tris[1] =
i;
910 int i, firstVert, secondVert;
919 for ( i = 1; i <
edges.Num(); i++ ) {
926 if ( i <
edges.Num() ) {
927 return v1 < v2 ? i : -
i;
static const float INFINITY
idList< idDrawVert > verts
assert(prefInfo.fullscreenBtn)
bool FromPoints(const idVec3 &p1, const idVec3 &p2, const idVec3 &p3, bool fixDegenerate=true)
const idVec3 & Normal(void) const
void SetNum(int newnum, bool resize=true)
GLenum GLenum GLenum GLenum GLenum scale
float Distance(const idVec3 &v) const
bool IsClosed(void) const
void FromLine(const idVec3 &start, const idVec3 &end)
bool ClipInPlace(const idPlane &plane, const float epsilon=ON_EPSILON, const bool keepOn=false)
bool RayIntersection(const idVec3 &start, const idVec3 &dir, float &scale, bool backFaceCull=false) const
GLfloat GLfloat GLfloat v2
idList< int > edgeIndexes
#define FLOATSIGNBITSET(f)
int PlaneSide(const idPlane &plane, const float epsilon=ON_EPSILON) const
float PlaneDistance(const idPlane &plane) const
int Split(const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges=NULL, int *backOnPlaneEdges=NULL) const
static float Fabs(float f)
#define INTSIGNBITNOTSET(i)
idList< surfaceEdge_t > edges
void LerpAll(const idDrawVert &a, const idDrawVert &b, const float f)
float PermutedInnerProduct(const idPluecker &a) const
bool LineIntersection(const idVec3 &start, const idVec3 &end, bool backFaceCull=false) const
void FromRay(const idVec3 &start, const idVec3 &dir)
bool RayIntersection(const idVec3 &start, const idVec3 &dir, float &scale) const
int Side(const idVec3 &v, const float epsilon=0.0f) const
bool IsConnected(void) const
ID_INLINE int UpdateVertexIndex(int vertexIndexNum[2], int *vertexRemap, int *vertexCopyIndex, int vertNum)
int Append(const type &obj)
void GenerateEdgeIndexes(void)
#define FLOATSIGNBITNOTSET(f)
bool IsPolytope(const float epsilon=0.1f) const
int FindEdge(int v1, int v2) const