311 unsigned int num_points,
316 unsigned int *personalities
349 const float parallel_factor = 0.9f;
356 if (chunk_size > num_points) chunk_size = num_points;
362 for (
unsigned int chunkIndex = 0; chunkIndex < num_points - 1; chunkIndex += (chunk_size - 1))
364 unsigned int point_cnt = num_points - chunkIndex;
365 point_cnt =
MIN(point_cnt, chunk_size);
368 unsigned int pointIndex;
369 unsigned int segmentIndex;
370 unsigned int intersectionIndex;
379 Matrix3D view2( view[0].X,view[0].Y,view[0].Z,view[0].
W,
380 view[1].X,view[1].Y,view[1].Z,view[1].
W,
381 view[2].X,view[2].Y,view[2].Z,view[2].
W);
383#ifdef ALLOW_TEMPORARIES
387 modelview.
mul(view2, transform);
391 &points[chunkIndex], modelview, point_cnt);
403 for (pointIndex = 0; pointIndex < point_cnt; pointIndex++)
406 base_tex_v[pointIndex] = 0.0f;
457 unsigned int sub_point_cnt;
459 subdivision_util(point_cnt, xformed_pts, base_tex_v, &sub_point_cnt, xformed_subdiv_pts, subdiv_tex_v);
462 Vector3 *points = xformed_subdiv_pts;
463 float *tex_v = subdiv_tex_v;
464 point_cnt = sub_point_cnt;
491 bool switch_edges =
false;
508 struct LineSegmentIntersection
510 unsigned int PointCount;
511 unsigned int NextSegmentID;
520 float radius = Width * 0.5f;
535 for (segmentIndex = 1; segmentIndex < point_cnt; segmentIndex++)
538 radius = widths[segmentIndex];
540 Vector3 &curr_point = points[segmentIndex - 1];
541 Vector3 &next_point = points[segmentIndex];
544 next_point.
X += 0.001f;
549 Vector3 &segdir = segment[segmentIndex].StartPlane;
550 segdir = next_point - curr_point;
560 Vector3 top = curr_point + offset * radius;
561 Vector3 bottom = curr_point + offset * -radius;
568 segment[segmentIndex].EdgePlane[TOP_EDGE] = top_normal;
573 segment[segmentIndex].EdgePlane[BOTTOM_EDGE] = bottom_normal;
579 if (segmentIndex > 1)
592 switch_edges = !switch_edges;
593 intersection[segmentIndex][TOP_EDGE].Fold =
true;
594 intersection[segmentIndex][BOTTOM_EDGE].Fold =
true;
598 intersection[segmentIndex][TOP_EDGE].Fold =
false;
599 intersection[segmentIndex][BOTTOM_EDGE].Fold =
false;
606 segment[segmentIndex].EdgePlane[TOP_EDGE] = -bottom_normal;
607 segment[segmentIndex].EdgePlane[BOTTOM_EDGE] = -top_normal;
624 unsigned int numsegs = point_cnt - 1;
625 unsigned int num_intersections[NUM_EDGES];
628 num_intersections[TOP_EDGE] = point_cnt;
629 num_intersections[BOTTOM_EDGE] = point_cnt;
632 intersection[0][TOP_EDGE].PointCount = 0;
633 intersection[0][TOP_EDGE].NextSegmentID = 0;
634 intersection[0][TOP_EDGE].Direction.Set(1,0,0);
635 intersection[0][TOP_EDGE].Point.Set(0,0,0);
636 intersection[0][TOP_EDGE].TexV = 0.0f;
637 intersection[0][TOP_EDGE].Fold =
true;
638 intersection[0][TOP_EDGE].Parallel =
false;
639 intersection[0][BOTTOM_EDGE].PointCount = 0;
640 intersection[0][BOTTOM_EDGE].NextSegmentID = 0;
641 intersection[0][BOTTOM_EDGE].Point.Set(0,0,0);
642 intersection[0][BOTTOM_EDGE].TexV = 0.0f;
643 intersection[0][BOTTOM_EDGE].Direction.Set(1,0,0);
644 intersection[0][BOTTOM_EDGE].Fold =
true;
645 intersection[0][BOTTOM_EDGE].Parallel =
false;
648 intersection[1][TOP_EDGE].PointCount = 1;
649 intersection[1][TOP_EDGE].NextSegmentID = 1;
650 intersection[1][TOP_EDGE].Point = points[0];
651 intersection[1][TOP_EDGE].TexV = tex_v[0];
652 intersection[1][TOP_EDGE].Fold =
true;
653 intersection[1][TOP_EDGE].Parallel =
false;
654 intersection[1][BOTTOM_EDGE].PointCount = 1;
655 intersection[1][BOTTOM_EDGE].NextSegmentID = 1;
656 intersection[1][BOTTOM_EDGE].Point = points[0];
657 intersection[1][BOTTOM_EDGE].TexV = tex_v[0];
658 intersection[1][BOTTOM_EDGE].Fold =
true;
659 intersection[1][BOTTOM_EDGE].Parallel =
false;
667 Vector3 &first_point = points[0];
668 Vector3 *first_plane = &(segment[1].EdgePlane[0]);
669 top = first_point - first_plane[TOP_EDGE] *
Vector3::Dot_Product(first_plane[TOP_EDGE], first_point);
671 intersection[1][TOP_EDGE].Direction = top;
672 bottom = first_point - first_plane[BOTTOM_EDGE] *
Vector3::Dot_Product(first_plane[BOTTOM_EDGE], first_point);
674 intersection[1][BOTTOM_EDGE].Direction = bottom;
676 Vector3 segdir = points[1] - points[0];
684 segment[0].StartPlane = segment[0].EdgePlane[TOP_EDGE] = segment[0].EdgePlane[BOTTOM_EDGE] = start_pl;
688 segment[0].StartPlane = segment[0].EdgePlane[TOP_EDGE] = segment[0].EdgePlane[BOTTOM_EDGE] = -start_pl;
692 segment[1].StartPlane = segment[0].StartPlane;
695 unsigned int last_isec = num_intersections[TOP_EDGE];
697 intersection[last_isec][TOP_EDGE].PointCount = 1;
698 intersection[last_isec][TOP_EDGE].NextSegmentID = numsegs + 1;
699 intersection[last_isec][TOP_EDGE].Point = points[point_cnt - 1];
700 intersection[last_isec][TOP_EDGE].TexV = tex_v[point_cnt - 1];
701 intersection[last_isec][TOP_EDGE].Fold =
true;
702 intersection[last_isec][TOP_EDGE].Parallel =
false;
703 intersection[last_isec][BOTTOM_EDGE].PointCount = 1;
704 intersection[last_isec][BOTTOM_EDGE].NextSegmentID = numsegs + 1;
705 intersection[last_isec][BOTTOM_EDGE].Point = points[point_cnt - 1];
706 intersection[last_isec][BOTTOM_EDGE].TexV = tex_v[point_cnt - 1];
707 intersection[last_isec][BOTTOM_EDGE].Fold =
true;
708 intersection[last_isec][BOTTOM_EDGE].Parallel =
false;
713 Vector3 &last_point = points[point_cnt - 1];
714 Vector3 *last_plane = &(segment[numsegs].EdgePlane[0]);
715 top = last_point - last_plane[TOP_EDGE] *
Vector3::Dot_Product(last_plane[TOP_EDGE], last_point);
717 intersection[last_isec][TOP_EDGE].Direction = top;
718 bottom = last_point - last_plane[BOTTOM_EDGE] *
Vector3::Dot_Product(last_plane[BOTTOM_EDGE], last_point);
720 intersection[last_isec][BOTTOM_EDGE].Direction = bottom;
722 segdir = points[point_cnt - 1] - points[point_cnt - 2];
729 segment[numsegs + 1].StartPlane = segment[numsegs + 1].EdgePlane[TOP_EDGE] =
730 segment[numsegs + 1].EdgePlane[BOTTOM_EDGE] = start_pl;
734 segment[numsegs + 1].StartPlane = segment[numsegs + 1].EdgePlane[TOP_EDGE] =
735 segment[numsegs + 1].EdgePlane[BOTTOM_EDGE] = -start_pl;
749 for (intersectionIndex = 2; intersectionIndex < num_intersections[TOP_EDGE]; intersectionIndex++)
753 Vector3 &midpoint = points[intersectionIndex - 1];
754 float mid_tex_v = tex_v[intersectionIndex - 1];
757 intersection[intersectionIndex][TOP_EDGE].PointCount = 1;
758 intersection[intersectionIndex][TOP_EDGE].NextSegmentID = intersectionIndex;
759 intersection[intersectionIndex][TOP_EDGE].Point = midpoint;
762 intersection[intersectionIndex][TOP_EDGE].TexV = personalities[intersectionIndex]&1;
764 intersection[intersectionIndex][BOTTOM_EDGE].PointCount = 1;
765 intersection[intersectionIndex][BOTTOM_EDGE].NextSegmentID = intersectionIndex;
766 intersection[intersectionIndex][BOTTOM_EDGE].Point = midpoint;
769 intersection[intersectionIndex][BOTTOM_EDGE].TexV = personalities[intersectionIndex]&1;
777 vdp =
Vector3::Dot_Product(segment[intersectionIndex - 1].EdgePlane[TOP_EDGE], segment[intersectionIndex].EdgePlane[TOP_EDGE]);
778 if (fabs(vdp) < parallel_factor)
783 Vector3::Cross_Product(segment[intersectionIndex - 1].EdgePlane[TOP_EDGE], segment[intersectionIndex].EdgePlane[TOP_EDGE],
784 &(intersection[intersectionIndex][TOP_EDGE].Direction));
785 intersection[intersectionIndex][TOP_EDGE].Direction.Normalize();
788 intersection[intersectionIndex][TOP_EDGE].Direction = -intersection[intersectionIndex][TOP_EDGE].Direction;
791 intersection[intersectionIndex][TOP_EDGE].Parallel =
false;
803 pl = segment[intersectionIndex - 1].EdgePlane[TOP_EDGE] + segment[intersectionIndex].EdgePlane[TOP_EDGE];
807 pl = segment[intersectionIndex - 1].EdgePlane[TOP_EDGE] - segment[intersectionIndex].EdgePlane[TOP_EDGE];
811 intersection[intersectionIndex][TOP_EDGE].Direction = midpoint - pl *
Vector3::Dot_Product(pl, midpoint);
812 intersection[intersectionIndex][TOP_EDGE].Direction.Normalize();
814 intersection[intersectionIndex][TOP_EDGE].Parallel =
true;
818 vdp =
Vector3::Dot_Product(segment[intersectionIndex - 1].EdgePlane[BOTTOM_EDGE], segment[intersectionIndex].EdgePlane[BOTTOM_EDGE]);
819 if (fabs(vdp) < parallel_factor)
824 Vector3::Cross_Product(segment[intersectionIndex - 1].EdgePlane[BOTTOM_EDGE], segment[intersectionIndex].EdgePlane[BOTTOM_EDGE],
825 &(intersection[intersectionIndex][BOTTOM_EDGE].Direction));
826 intersection[intersectionIndex][BOTTOM_EDGE].Direction.Normalize();
827 if (
Vector3::Dot_Product(intersection[intersectionIndex][BOTTOM_EDGE].Direction, midpoint) < 0.0f)
829 intersection[intersectionIndex][BOTTOM_EDGE].Direction = -intersection[intersectionIndex][BOTTOM_EDGE].Direction;
832 intersection[intersectionIndex][BOTTOM_EDGE].Parallel =
false;
844 pl = segment[intersectionIndex - 1].EdgePlane[BOTTOM_EDGE] + segment[intersectionIndex].EdgePlane[BOTTOM_EDGE];
848 pl = segment[intersectionIndex - 1].EdgePlane[BOTTOM_EDGE] - segment[intersectionIndex].EdgePlane[BOTTOM_EDGE];
852 intersection[intersectionIndex][BOTTOM_EDGE].Direction = midpoint - pl *
Vector3::Dot_Product(pl, midpoint);
853 intersection[intersectionIndex][BOTTOM_EDGE].Direction.Normalize();
855 intersection[intersectionIndex][BOTTOM_EDGE].Parallel =
true;
859 Vector3::Cross_Product(intersection[intersectionIndex][TOP_EDGE].Direction, intersection[intersectionIndex][BOTTOM_EDGE].Direction, &start_pl);
864 segment[intersectionIndex].StartPlane = start_pl;
868 segment[intersectionIndex].StartPlane = -start_pl;
885 unsigned int intersectionIndex_r;
886 unsigned int intersectionIndex_w;
898 for (edge = FIRST_EDGE; edge <= MAX_EDGE; edge = (SegmentEdge)((int)edge + 1))
905 unsigned int num_isects = num_intersections[edge];
906 for (intersectionIndex_r = 1, intersectionIndex_w = 1; intersectionIndex_r < num_isects; intersectionIndex_r++, intersectionIndex_w++) {
919 LineSegmentIntersection *curr_int = &(intersection[intersectionIndex_r][edge]);
920 LineSegmentIntersection *next_int = &(intersection[intersectionIndex_r + 1][edge]);
921 LineSegmentIntersection *write_int = &(intersection[intersectionIndex_w][edge]);
922 LineSegmentIntersection *prev_int = &(intersection[intersectionIndex_w - 1][edge]);
923 LineSegment *next_seg = &(segment[next_int->NextSegmentID]);
924 LineSegment *curr_seg = &(segment[curr_int->NextSegmentID]);
925 LineSegment *prev_seg = &(segment[prev_int->NextSegmentID]);
931 while ( (!next_int->Fold &&
943 unsigned int new_count = curr_int->PointCount + next_int->PointCount;
944 float oo_new_count = 1.0f / (float)new_count;
945 float curr_factor = oo_new_count * (float)curr_int->PointCount;
946 float next_factor = oo_new_count * (float)curr_int->PointCount;
947 Vector3 new_point = curr_int->Point * curr_factor + next_int->Point * next_factor;
948 float new_tex_v = curr_int->TexV * curr_factor + next_int->TexV * next_factor;
954 if (fabs(vdp) < parallel_factor)
963 new_direction = -new_direction;
966 new_parallel =
false;
982 pl = prev_seg->EdgePlane[edge] + next_seg->EdgePlane[edge];
986 pl = prev_seg->EdgePlane[edge] - next_seg->EdgePlane[edge];
990 if (curr_int->Parallel)
1001 new_parallel =
true;
1007 if (MergeAbortFactor > 0.0f)
1009 float abort_dist = radius * MergeAbortFactor;
1010 float abort_dist2 = abort_dist * abort_dist;
1011 Vector3 diff_curr = curr_int->Point -
1013 if (diff_curr.
Length2() > abort_dist2)
break;
1014 Vector3 next_curr = next_int->Point -
1016 if (next_curr.
Length2() > abort_dist2)
break;
1022 curr_int->Direction = new_direction;
1023 curr_int->Parallel = new_parallel;
1024 curr_int->Point = new_point;
1025 curr_int->TexV = new_tex_v;
1026 curr_int->PointCount = new_count;
1027 curr_int->NextSegmentID = next_int->NextSegmentID;
1028 curr_int->Fold = curr_int->Fold || next_int->Fold;
1031 num_intersections[edge]--;
1034 intersectionIndex_r++;
1037 if (intersectionIndex_r == num_isects)
1043 next_int = &(intersection[intersectionIndex_r + 1][edge]);
1044 next_seg = &(segment[next_int->NextSegmentID]);
1049 write_int->PointCount = curr_int->PointCount;
1050 write_int->NextSegmentID = curr_int->NextSegmentID;
1051 write_int->Point = curr_int->Point;
1052 write_int->TexV = curr_int->TexV;
1053 write_int->Direction = curr_int->Direction;
1054 write_int->Fold = curr_int->Fold;
1061 if (intersectionIndex_r == num_isects)
1063 LineSegmentIntersection *write_int = &(intersection[intersectionIndex_w][edge]);
1064 LineSegmentIntersection *curr_int = &(intersection[intersectionIndex_r][edge]);
1065 write_int->PointCount = curr_int->PointCount;
1066 write_int->NextSegmentID = curr_int->NextSegmentID;
1067 write_int->Point = curr_int->Point;
1068 write_int->TexV = curr_int->TexV;
1069 write_int->Direction = curr_int->Direction;
1070 write_int->Fold = curr_int->Fold;
1073#ifdef ENABLE_WWDEBUGGING
1075 unsigned int total_cnt = 0;
1076 for (
unsigned int nidx = 0; nidx <= num_intersections[edge]; nidx++)
1078 total_cnt += intersection[nidx][edge].PointCount;
1080 assert(total_cnt == point_cnt);
1095 unsigned int vnum = num_intersections[TOP_EDGE] + num_intersections[BOTTOM_EDGE];
1100 unsigned int vertexIndex = 0;
1101 unsigned int triangleIndex = 0;
1118 Vector3 &top_dir = intersection[1][TOP_EDGE].Direction;
1120 Vector3 &bottom_dir = intersection[1][BOTTOM_EDGE].Direction;
1122 vertexArray[vertexIndex].
x = top.
X;
1123 vertexArray[vertexIndex].
y = top.
Y;
1124 vertexArray[vertexIndex].
z = top.
Z;
1125 vertexArray[vertexIndex].
u1 = u_values[0] ;
1126 vertexArray[vertexIndex].
v1 = intersection[1][TOP_EDGE].TexV ;
1128 vertexArray[vertexIndex].
x = bottom.
X;
1129 vertexArray[vertexIndex].
y = bottom.
Y;
1130 vertexArray[vertexIndex].
z = bottom.
Z;
1131 vertexArray[vertexIndex].
u1 = u_values[1] ;
1132 vertexArray[vertexIndex].
v1 = intersection[1][BOTTOM_EDGE].TexV ;
1135 unsigned int last_top_vertexIndex = 0;
1136 unsigned int last_bottom_vertexIndex = 1;
1139 unsigned int top_int_idx = 1;
1140 unsigned int bottom_int_idx = 1;
1142 unsigned int residual_top_points = intersection[1][TOP_EDGE].PointCount;
1143 unsigned int residual_bottom_points = intersection[1][BOTTOM_EDGE].PointCount;
1146 unsigned int delta =
MIN(residual_top_points, residual_bottom_points) - 1;
1147 residual_top_points -= delta;
1148 residual_bottom_points -= delta;
1149 pointIndex += delta;
1154 if (residual_top_points == 1 && residual_bottom_points == 1)
1157 v_index_array[triangleIndex].
I = last_top_vertexIndex;
1158 v_index_array[triangleIndex].
J = last_bottom_vertexIndex;
1159 v_index_array[triangleIndex].
K = vertexIndex;
1161 v_index_array[triangleIndex].
I = last_bottom_vertexIndex;
1162 v_index_array[triangleIndex].
J = vertexIndex + 1;
1163 v_index_array[triangleIndex].
K = vertexIndex;
1165 last_top_vertexIndex = vertexIndex;
1166 last_bottom_vertexIndex = vertexIndex + 1;
1171 residual_top_points = intersection[top_int_idx][TOP_EDGE].PointCount;
1172 residual_bottom_points = intersection[bottom_int_idx][BOTTOM_EDGE].PointCount;
1178 Vector3 &top_dir = intersection[top_int_idx][TOP_EDGE].Direction;
1180 Vector3 &bottom_dir = intersection[bottom_int_idx][BOTTOM_EDGE].Direction;
1183 vertexArray[vertexIndex].
x = top.
X;
1184 vertexArray[vertexIndex].
y = top.
Y;
1185 vertexArray[vertexIndex].
z = top.
Z;
1186 vertexArray[vertexIndex].
u1 = u_values[0] ;
1187 vertexArray[vertexIndex].
v1 = intersection[top_int_idx][TOP_EDGE].TexV ;
1189 vertexArray[vertexIndex].
x = bottom.
X;
1190 vertexArray[vertexIndex].
y = bottom.
Y;
1191 vertexArray[vertexIndex].
z = bottom.
Z;
1192 vertexArray[vertexIndex].
u1 = u_values[1] ;
1193 vertexArray[vertexIndex].
v1 = intersection[bottom_int_idx][BOTTOM_EDGE].TexV ;
1199 if (residual_top_points > 1)
1202 v_index_array[triangleIndex].
I = last_top_vertexIndex;
1203 v_index_array[triangleIndex].
J = last_bottom_vertexIndex;
1204 v_index_array[triangleIndex].
K = vertexIndex;
1206 last_bottom_vertexIndex = vertexIndex;
1209 residual_top_points--;
1211 residual_bottom_points = intersection[bottom_int_idx][BOTTOM_EDGE].PointCount;
1217 Vector3 &bottom_dir = intersection[bottom_int_idx][BOTTOM_EDGE].Direction;
1220 vertexArray[vertexIndex].
x = bottom.
X;
1221 vertexArray[vertexIndex].
y = bottom.
Y;
1222 vertexArray[vertexIndex].
z = bottom.
Z;
1223 vertexArray[vertexIndex].
u1 = u_values[1] ;
1224 vertexArray[vertexIndex].
v1 = intersection[bottom_int_idx][BOTTOM_EDGE].TexV ;
1233 v_index_array[triangleIndex].
I = last_top_vertexIndex;
1234 v_index_array[triangleIndex].
J = last_bottom_vertexIndex;
1235 v_index_array[triangleIndex].
K = vertexIndex;
1237 last_top_vertexIndex = vertexIndex;
1240 residual_bottom_points--;
1242 residual_top_points = intersection[top_int_idx][TOP_EDGE].PointCount;
1248 Vector3 &top_dir = intersection[top_int_idx][TOP_EDGE].Direction;
1250 vertexArray[vertexIndex].
x = top.
X;
1251 vertexArray[vertexIndex].
y = top.
Y;
1252 vertexArray[vertexIndex].
z = top.
Z;
1253 vertexArray[vertexIndex].
u1 = u_values[0] ;
1254 vertexArray[vertexIndex].
v1 = intersection[top_int_idx][TOP_EDGE].TexV ;
1260 delta =
MIN(residual_top_points, residual_bottom_points) - 1;
1261 residual_top_points -= delta;
1262 residual_bottom_points -= delta;
1263 pointIndex += delta;
1265 if ( (top_int_idx >= num_intersections[TOP_EDGE] && residual_top_points == 1) ||
1266 (bottom_int_idx >= num_intersections[BOTTOM_EDGE] && residual_bottom_points == 1))
1270 assert(top_int_idx == num_intersections[TOP_EDGE]);
1271 assert(bottom_int_idx == num_intersections[BOTTOM_EDGE]);
1272 assert(pointIndex == point_cnt - 1);
1339 unsigned int argb = 0x00000000;
1341 unsigned int oddEven = 0;
1350 for (i=0; i<vnum; i++)
1352 DEBUG_ASSERTCRASH(vertexArray[i].x != (
float)0xdeadbeef && vertexArray[i].y != (
float)0xdeadbeef && vertexArray[i].z != (
float)0xdeadbeef && vertexArray[i].u1 != (
float)0xdeadbeeef && vertexArray[i].v1 != (
float)0xdeadbeef, (
"Uninitialized vertexArray[%d]", i));
1353 DEBUG_ASSERTCRASH((! _isnan(vertexArray[i].x) && _finite(vertexArray[i].x) && ! _isnan(vertexArray[i].y) && _finite(vertexArray[i].y) && ! _isnan(vertexArray[i].z) && _finite(vertexArray[i].z)) , (
"Bad vertexArray[%d]", i));
1354 Vector3 *vertex =
reinterpret_cast<Vector3 *
>(vb + verticesOffset);
1355 vertex->
X = vertexArray[i].
x;
1356 vertex->
Y = vertexArray[i].
y;
1357 vertex->
Z = vertexArray[i].
z;
1359 Vector2 *texture =
reinterpret_cast<Vector2 *
>(vb + textureOffset);
1360 texture->
U = vertexArray[i].
u1;
1361 texture->
V = vertexArray[i].
v1;
1373 for (i=0; i<triangleIndex; i++)
1375 *inds++=v_index_array[i].
I;
1376 *inds++=v_index_array[i].
J;
1377 *inds++=v_index_array[i].
K;