Clip a polygon against one edge of another polygon Fills inbuf and maybe outbuf with new polygons, and writes any new verts to the vertices array Parameters: nv - the number of verts in the polygon to be clipped vertnums - pointer to list of vertex numbers in the polygon vertices - list of vertices referred to in vertnums v0,v1 - the edge we're clipping against normal - the surface normal of the p
| 822 | // outbuf - the new polygon created by the part of the input polygon that was |
| 823 | //clipped away onv - the number of verys in outbuf num_vertices - pointer to the number of verts in the vertices array |
| 824 | void ClipAgainstEdge(int nv, int16_t *vertnums, vertex *vertices, int *num_vertices, vector *v0, vector *v1, |
| 825 | vector *normal, int16_t *inbuf, int *inv, int16_t *outbuf, int *onv) { |
| 826 | int i, prev, next, check; |
| 827 | int16_t *ip = inbuf, *op = outbuf; |
| 828 | vertex *curv, *prevv, *nextv; |
| 829 | int inside_points = 0, outside_points = 0; // real inside/outside points, distinct from edge points |
| 830 | |
| 831 | for (i = 0, prev = nv - 1, next = 1; i < nv; i++) { |
| 832 | |
| 833 | curv = &vertices[vertnums[i]]; |
| 834 | |
| 835 | // Find out where point lies |
| 836 | check = CheckPointAgainstEdge(&curv->vec, v0, v1, normal); |
| 837 | if (check == 0) { // Current vertex is on edge |
| 838 | |
| 839 | // Add to both inside & outside lists |
| 840 | *op++ = vertnums[i]; |
| 841 | *ip++ = vertnums[i]; |
| 842 | } else if (check == -1) { // Current vertex is outside |
| 843 | int check2; |
| 844 | |
| 845 | prevv = &vertices[vertnums[prev]]; |
| 846 | nextv = &vertices[vertnums[next]]; |
| 847 | |
| 848 | // Clip edge w/ previous vertex |
| 849 | check2 = CheckPointAgainstEdge(&prevv->vec, v0, v1, normal); |
| 850 | if (check2 == 1) { // prev inside, so clip |
| 851 | ClipEdge(normal, prevv, curv, v0, v1, &vertices[*num_vertices]); |
| 852 | AddEdgeInsert(vertnums[prev], vertnums[i], *num_vertices); |
| 853 | *op++ = *ip++ = (*num_vertices)++; |
| 854 | } |
| 855 | |
| 856 | // Add current vertex to outside polygon |
| 857 | *op++ = vertnums[i]; |
| 858 | outside_points++; |
| 859 | |
| 860 | // Clip edge w/ next vertex |
| 861 | check2 = CheckPointAgainstEdge(&nextv->vec, v0, v1, normal); |
| 862 | if (check2 == 1) { // next inside, so clip |
| 863 | ClipEdge(normal, curv, nextv, v0, v1, &vertices[*num_vertices]); |
| 864 | AddEdgeInsert(vertnums[i], vertnums[next], *num_vertices); |
| 865 | *op++ = *ip++ = (*num_vertices)++; |
| 866 | } |
| 867 | } else { // Current vertex is inside |
| 868 | ASSERT(check == 1); |
| 869 | |
| 870 | // Add current vertex to inside polygon |
| 871 | *ip++ = vertnums[i]; |
| 872 | inside_points++; |
| 873 | } |
| 874 | |
| 875 | prev = i; |
| 876 | if (++next == nv) |
| 877 | next = 0; |
| 878 | } |
| 879 | |
| 880 | // Set number of verts for return. If no real inside or outside points, then don't count edge points |
| 881 | *inv = inside_points ? (ip - inbuf) : 0; |
no test coverage detected