| 83 | |
| 84 | template< typename Base > |
| 85 | U32 PolyhedronImpl< Base >::constructIntersection( const PlaneF& plane, Point3F* outPoints, U32 maxOutPoints ) const |
| 86 | { |
| 87 | // The assumption here is that the polyhedron is entirely composed |
| 88 | // of convex polygons implicitly described by the edges, points, and planes. |
| 89 | // So, any polygon can only have one of three relations to the given plane |
| 90 | // |
| 91 | // 1) None of its edges intersect with the plane, i.e. the polygon can be ignored. |
| 92 | // 2) One of its edges lies on the plane. |
| 93 | // 2) Two of its edges intersect with the plane. |
| 94 | // |
| 95 | // Conceptually, we need to find the first face with an intersecting edge, then find |
| 96 | // another edge on the same face that is also intersecting, and then continue with the |
| 97 | // face on the opposite side of the edge. |
| 98 | |
| 99 | const U32 numEdges = this->getNumEdges(); |
| 100 | const typename Base::EdgeType* edges = this->getEdges(); |
| 101 | const typename Base::PointType* points = this->getPoints(); |
| 102 | U32 numOutPoints = 0; |
| 103 | |
| 104 | #define ADD_POINT( p ) \ |
| 105 | if( numOutPoints >= maxOutPoints ) \ |
| 106 | return 0; \ |
| 107 | outPoints[ numOutPoints ++ ] = p; |
| 108 | |
| 109 | Point3F intersection; |
| 110 | |
| 111 | S32 firstEdge = -1; |
| 112 | S32 firstFace = -1; |
| 113 | |
| 114 | U32 v1 = 0; |
| 115 | U32 v2 = 0; |
| 116 | |
| 117 | PlaneF::Side v1Side = PlaneF::Front; |
| 118 | PlaneF::Side v2Side = PlaneF::Front; |
| 119 | |
| 120 | // Find an edge to start with. This is the first edge |
| 121 | // in the polyhedron that intersects the plane. |
| 122 | |
| 123 | for( U32 i = 0; i < numEdges; ++ i ) |
| 124 | { |
| 125 | const typename Base::EdgeType& edge = edges[ i ]; |
| 126 | |
| 127 | v1 = edge.vertex[ 0 ]; |
| 128 | v2 = edge.vertex[ 1 ]; |
| 129 | |
| 130 | const Point3F& p1 = points[ v1 ]; |
| 131 | const Point3F& p2 = points[ v2 ]; |
| 132 | |
| 133 | v1Side = plane.whichSide( p1 ); |
| 134 | v2Side = plane.whichSide( p2 ); |
| 135 | |
| 136 | if( v1Side == PlaneF::On || v2Side == PlaneF::On || |
| 137 | plane.clipSegment( p1, p2, intersection ) ) |
| 138 | { |
| 139 | firstEdge = i; |
| 140 | firstFace = edge.face[ 0 ]; |
| 141 | break; |
| 142 | } |
no test coverage detected