static __regargs UWORD ClipPolygon(Point3D *S, Point3D *O, UWORD n, UWORD plane) { Point3D *E = S + 1; BOOL S_inside = CheckInside(S, plane); BOOL needClose = TRUE; UWORD m = 0; if (S_inside) { needClose = FALSE; O[m++] = *S; } while (--n) { BOOL E_inside = CheckInside(E, plane); if (S_inside && E_inside) { O[m++] = *E; } else if (S_inside && !E_inside) { ClipEdge(&O[m++], S, E, plane); } else if (!S_inside && E_inside) { ClipEdge(&O[m++], E, S, plane); O[m++] = *E; } S_inside = E_inside; S++; E++; } if (needClose) O[m++] = *O; return m; }
void ClipPolygon(float_polygon_type poly, float_polygon_type &poly_out) { win_edge_type edge; for (int edg = 0; edg < 4; edg++) { poly_out.n = 0; // Reset poly_out edge = (win_edge_type)edg; poly.vertex[poly.n] = poly.vertex[0]; for (int i = 0; i < poly.n; i++) ClipEdge(poly.vertex[i], poly.vertex[i + 1], edge, poly_out); poly = poly_out;// Copy poly_out to poly } }
void TriangleClipperBase::processFaces() { for (UINT32 i = 0; i < (UINT32)mesh.faces.size(); i++) { ClipFace& face = mesh.faces[i]; if (face.visible) { // The edge is culled. If the edge is exactly on the clip // plane, it is possible that a visible triangle shares it. // The edge will be re-added during the face loop. for (UINT32 j = 0; j < (UINT32)face.edges.size(); j++) { ClipEdge& edge = mesh.edges[face.edges[j]]; ClipVert& v0 = mesh.verts[edge.verts[0]]; ClipVert& v1 = mesh.verts[edge.verts[1]]; v0.occurs = 0; v1.occurs = 0; } } UINT32 start, end; if (getOpenPolyline(mesh.faces[i], start, end)) { // Polyline is open, close it UINT32 closeEdgeIdx = (UINT32)mesh.edges.size(); mesh.edges.push_back(ClipEdge()); ClipEdge& closeEdge = mesh.edges.back(); closeEdge.verts[0] = start; closeEdge.verts[1] = end; closeEdge.faces.push_back(i); face.edges.push_back(closeEdgeIdx); } } }
void OcclusionBuffer::ClipVertices(const Vector4& plane, Vector4* vertices, bool* triangles, unsigned& numTriangles) { unsigned num = numTriangles; for (unsigned i = 0; i < num; ++i) { if (triangles[i]) { unsigned index = i * 3; float d0 = plane.DotProduct(vertices[index]); float d1 = plane.DotProduct(vertices[index + 1]); float d2 = plane.DotProduct(vertices[index + 2]); // If all vertices behind the plane, reject triangle if (d0 < 0.0f && d1 < 0.0f && d2 < 0.0f) { triangles[i] = false; continue; } // If 2 vertices behind the plane, create a new triangle in-place else if (d0 < 0.0f && d1 < 0.0f) { vertices[index] = ClipEdge(vertices[index], vertices[index + 2], d0, d2); vertices[index + 1] = ClipEdge(vertices[index + 1], vertices[index + 2], d1, d2); } else if (d0 < 0.0f && d2 < 0.0f) { vertices[index] = ClipEdge(vertices[index], vertices[index + 1], d0, d1); vertices[index + 2] = ClipEdge(vertices[index + 2], vertices[index + 1], d2, d1); } else if (d1 < 0.0f && d2 < 0.0f) { vertices[index + 1] = ClipEdge(vertices[index + 1], vertices[index], d1, d0); vertices[index + 2] = ClipEdge(vertices[index + 2], vertices[index], d2, d0); } // 1 vertex behind the plane: create one new triangle, and modify one in-place else if (d0 < 0.0f) { unsigned newIdx = numTriangles * 3; triangles[numTriangles] = true; ++numTriangles; vertices[newIdx] = ClipEdge(vertices[index], vertices[index + 2], d0, d2); vertices[newIdx + 1] = vertices[index] = ClipEdge(vertices[index], vertices[index + 1], d0, d1); vertices[newIdx + 2] = vertices[index + 2]; } else if (d1 < 0.0f) { unsigned newIdx = numTriangles * 3; triangles[numTriangles] = true; ++numTriangles; vertices[newIdx + 1] = ClipEdge(vertices[index + 1], vertices[index], d1, d0); vertices[newIdx + 2] = vertices[index + 1] = ClipEdge(vertices[index + 1], vertices[index + 2], d1, d2); vertices[newIdx] = vertices[index]; } else if (d2 < 0.0f) { unsigned newIdx = numTriangles * 3; triangles[numTriangles] = true; ++numTriangles; vertices[newIdx + 2] = ClipEdge(vertices[index + 2], vertices[index + 1], d2, d1); vertices[newIdx] = vertices[index + 2] = ClipEdge(vertices[index + 2], vertices[index], d2, d0); vertices[newIdx + 1] = vertices[index + 1]; } } } }