/* ============= idWinding2D::PlaneDistance ============= */ float idWinding2D::PlaneDistance( const idVec3 &plane ) const { int i; float d, min, max; min = idMath::INFINITY; max = -min; for ( i = 0; i < numPoints; i++ ) { d = plane.x * p[i].x + plane.y * p[i].y + plane.z; if ( d < min ) { min = d; if ( IEEE_FLT_SIGNBITSET( min ) & IEEE_FLT_SIGNBITNOTSET( max ) ) { return 0.0f; } } if ( d > max ) { max = d; if ( IEEE_FLT_SIGNBITSET( min ) & IEEE_FLT_SIGNBITNOTSET( max ) ) { return 0.0f; } } } if ( IEEE_FLT_SIGNBITNOTSET( min ) ) { return min; } if ( IEEE_FLT_SIGNBITSET( max ) ) { return max; } return 0.0f; }
/* ============ idBox::GetProjectionSilhouetteVerts ============ */ int idBox::GetProjectionSilhouetteVerts( const idVec3& projectionOrigin, idVec3 silVerts[6] ) const { float f; int i, planeBits, *index; idVec3 points[8], dir1, dir2; ToPoints( points ); dir1 = points[0] - projectionOrigin; dir2 = points[6] - projectionOrigin; f = dir1 * axis[0]; planeBits = IEEE_FLT_SIGNBITNOTSET( f ); f = dir2 * axis[0]; planeBits |= IEEE_FLT_SIGNBITSET( f ) << 1; f = dir1 * axis[1]; planeBits |= IEEE_FLT_SIGNBITNOTSET( f ) << 2; f = dir2 * axis[1]; planeBits |= IEEE_FLT_SIGNBITSET( f ) << 3; f = dir1 * axis[2]; planeBits |= IEEE_FLT_SIGNBITNOTSET( f ) << 4; f = dir2 * axis[2]; planeBits |= IEEE_FLT_SIGNBITSET( f ) << 5; index = boxPlaneBitsSilVerts[planeBits]; for( i = 0; i < index[0]; i++ ) { silVerts[i] = points[index[i + 1]]; } return index[0]; }
/* ============ idWinding2D::LineIntersection ============ */ bool idWinding2D::LineIntersection( const idVec2 &start, const idVec2 &end ) const { int i, numEdges; int sides[MAX_POINTS_ON_WINDING_2D+1], counts[3]; float d1, d2, epsilon = 0.1f; idVec3 plane, edges[2]; counts[SIDE_FRONT] = counts[SIDE_BACK] = counts[SIDE_ON] = 0; plane = Plane2DFromPoints( start, end ); for ( i = 0; i < numPoints; i++ ) { d1 = plane.x * p[i].x + plane.y * p[i].y + plane.z; if ( d1 > epsilon ) { sides[i] = SIDE_FRONT; } else if ( d1 < -epsilon ) { sides[i] = SIDE_BACK; } else { sides[i] = SIDE_ON; } counts[sides[i]]++; } sides[i] = sides[0]; if ( !counts[SIDE_FRONT] ) { return false; } if ( !counts[SIDE_BACK] ) { return false; } numEdges = 0; for ( i = 0; i < numPoints; i++ ) { if ( sides[i] != sides[i+1] && sides[i+1] != SIDE_ON ) { edges[numEdges++] = Plane2DFromPoints( p[i], p[(i+1)%numPoints] ); if ( numEdges >= 2 ) { break; } } } if ( numEdges < 2 ) { return false; } d1 = edges[0].x * start.x + edges[0].y * start.y + edges[0].z; d2 = edges[0].x * end.x + edges[0].y * end.y + edges[0].z; if ( IEEE_FLT_SIGNBITNOTSET( d1 ) & IEEE_FLT_SIGNBITNOTSET( d2 ) ) { return false; } d1 = edges[1].x * start.x + edges[1].y * start.y + edges[1].z; d2 = edges[1].x * end.x + edges[1].y * end.y + edges[1].z; if ( IEEE_FLT_SIGNBITNOTSET( d1 ) & IEEE_FLT_SIGNBITNOTSET( d2 ) ) { return false; } return true; }