219 unsigned int num_points,
236 float del = (float)delta;
237 Vector2 uv_offset = CurrentUVOffset + UVOffsetDeltaPerMS * del;
240 uv_offset.
X = uv_offset.
X - floorf(uv_offset.
X);
241 uv_offset.
Y = uv_offset.
Y - floorf(uv_offset.
Y);
244 CurrentUVOffset = uv_offset;
255 const float parallel_factor = 0.9f;
262 if (chunk_size > num_points) chunk_size = num_points;
268 for (
unsigned int chidx = 0; chidx < num_points - 1; chidx += (chunk_size - 1)) {
269 unsigned int point_cnt = num_points - chidx;
270 point_cnt =
MIN(point_cnt, chunk_size);
284 Matrix3D view2( view[0].X,view[0].Y,view[0].Z,view[0].
W,
285 view[1].X,view[1].Y,view[1].Z,view[1].
W,
286 view[2].X,view[2].Y,view[2].Z,view[2].
W);
288#ifdef ALLOW_TEMPORARIES
292 modelview.
mul(view2, transform);
296 &points[chidx], modelview, point_cnt);
307 for (pidx = 0; pidx < point_cnt; pidx++) {
309 base_tex_v[pidx] = 0.0f;
315 for (pidx = 0; pidx < point_cnt; pidx++) {
317 base_tex_v[pidx] = (float)(pidx + chidx) * TextureTileFactor;
323 for (pidx = 0; pidx < point_cnt; pidx++) {
325 base_tex_v[pidx] = (float)(pidx + chidx) * TextureTileFactor;
343 unsigned int sub_point_cnt;
345 Vector4 *rgbasPointer = rgbas ? &rgbas[ chidx ] :
NULL;
347 subdivision_util(point_cnt, xformed_pts, base_tex_v, &sub_point_cnt, xformed_subdiv_pts, subdiv_tex_v, rgbasPointer, subdiv_rgbas);
350 Vector3 *points = xformed_subdiv_pts;
351 float *tex_v = subdiv_tex_v;
352 Vector4 *diffuse = subdiv_rgbas;
353 point_cnt = sub_point_cnt;
379 bool switch_edges =
false;
395 struct LineSegmentIntersection {
396 unsigned int PointCount;
397 unsigned int NextSegmentID;
407 float radius = Width * 0.5f;
418 for (sidx = 1; sidx < point_cnt; sidx++) {
420 Vector3 &curr_point = points[sidx - 1];
421 Vector3 &next_point = points[sidx];
424 next_point.
X += 0.001f;
429 Vector3 &segdir = segment[sidx].StartPlane;
430 segdir = next_point - curr_point;
440 Vector3 top = curr_point + offset * radius;
441 Vector3 bottom = curr_point + offset * -radius;
448 segment[sidx].EdgePlane[TOP_EDGE] = top_normal;
453 segment[sidx].EdgePlane[BOTTOM_EDGE] = bottom_normal;
470 switch_edges = !switch_edges;
471 intersection[sidx][TOP_EDGE].Fold =
true;
472 intersection[sidx][BOTTOM_EDGE].Fold =
true;
474 intersection[sidx][TOP_EDGE].Fold =
false;
475 intersection[sidx][BOTTOM_EDGE].Fold =
false;
481 segment[sidx].EdgePlane[TOP_EDGE] = -bottom_normal;
482 segment[sidx].EdgePlane[BOTTOM_EDGE] = -top_normal;
495 unsigned int numsegs = point_cnt - 1;
496 unsigned int num_intersections[NUM_EDGES];
499 num_intersections[TOP_EDGE] = point_cnt;
500 num_intersections[BOTTOM_EDGE] = point_cnt;
503 intersection[0][TOP_EDGE].PointCount = 0;
504 intersection[0][TOP_EDGE].NextSegmentID = 0;
505 intersection[0][TOP_EDGE].Direction.Set(1,0,0);
506 intersection[0][TOP_EDGE].Point.Set(0,0,0);
507 intersection[0][TOP_EDGE].TexV = 0.0f;
508 intersection[0][TOP_EDGE].RGBA.Set(0, 0, 0, 0);
509 intersection[0][TOP_EDGE].Fold =
true;
510 intersection[0][TOP_EDGE].Parallel =
false;
511 intersection[0][BOTTOM_EDGE].PointCount = 0;
512 intersection[0][BOTTOM_EDGE].NextSegmentID = 0;
513 intersection[0][BOTTOM_EDGE].Point.Set(0,0,0);
514 intersection[0][BOTTOM_EDGE].TexV = 0.0f;
515 intersection[0][BOTTOM_EDGE].RGBA.Set(0, 0, 0, 0);
516 intersection[0][BOTTOM_EDGE].Direction.Set(1,0,0);
517 intersection[0][BOTTOM_EDGE].Fold =
true;
518 intersection[0][BOTTOM_EDGE].Parallel =
false;
521 intersection[1][TOP_EDGE].PointCount = 1;
522 intersection[1][TOP_EDGE].NextSegmentID = 1;
523 intersection[1][TOP_EDGE].Point = points[0];
524 intersection[1][TOP_EDGE].TexV = tex_v[0];
525 intersection[1][TOP_EDGE].RGBA = diffuse[0];
526 intersection[1][TOP_EDGE].Fold =
true;
527 intersection[1][TOP_EDGE].Parallel =
false;
528 intersection[1][BOTTOM_EDGE].PointCount = 1;
529 intersection[1][BOTTOM_EDGE].NextSegmentID = 1;
530 intersection[1][BOTTOM_EDGE].Point = points[0];
531 intersection[1][BOTTOM_EDGE].TexV = tex_v[0];
532 intersection[1][BOTTOM_EDGE].RGBA = diffuse[0];
533 intersection[1][BOTTOM_EDGE].Fold =
true;
534 intersection[1][BOTTOM_EDGE].Parallel =
false;
542 Vector3 &first_point = points[0];
543 Vector3 *first_plane = &(segment[1].EdgePlane[0]);
544 top = first_point - first_plane[TOP_EDGE] *
Vector3::Dot_Product(first_plane[TOP_EDGE], first_point);
546 intersection[1][TOP_EDGE].Direction = top;
547 bottom = first_point - first_plane[BOTTOM_EDGE] *
Vector3::Dot_Product(first_plane[BOTTOM_EDGE], first_point);
549 intersection[1][BOTTOM_EDGE].Direction = bottom;
551 Vector3 segdir = points[1] - points[0];
558 segment[0].StartPlane = segment[0].EdgePlane[TOP_EDGE] = segment[0].EdgePlane[BOTTOM_EDGE] = start_pl;
560 segment[0].StartPlane = segment[0].EdgePlane[TOP_EDGE] = segment[0].EdgePlane[BOTTOM_EDGE] = -start_pl;
564 segment[1].StartPlane = segment[0].StartPlane;
567 unsigned int last_isec = num_intersections[TOP_EDGE];
569 intersection[last_isec][TOP_EDGE].PointCount = 1;
570 intersection[last_isec][TOP_EDGE].NextSegmentID = numsegs + 1;
571 intersection[last_isec][TOP_EDGE].Point = points[point_cnt - 1];
572 intersection[last_isec][TOP_EDGE].TexV = tex_v[point_cnt - 1];
573 intersection[last_isec][TOP_EDGE].RGBA = diffuse[point_cnt - 1];
574 intersection[last_isec][TOP_EDGE].Fold =
true;
575 intersection[last_isec][TOP_EDGE].Parallel =
false;
576 intersection[last_isec][BOTTOM_EDGE].PointCount = 1;
577 intersection[last_isec][BOTTOM_EDGE].NextSegmentID = numsegs + 1;
578 intersection[last_isec][BOTTOM_EDGE].Point = points[point_cnt - 1];
579 intersection[last_isec][BOTTOM_EDGE].TexV = tex_v[point_cnt - 1];
580 intersection[last_isec][BOTTOM_EDGE].RGBA = diffuse[point_cnt - 1];
581 intersection[last_isec][BOTTOM_EDGE].Fold =
true;
582 intersection[last_isec][BOTTOM_EDGE].Parallel =
false;
587 Vector3 &last_point = points[point_cnt - 1];
588 Vector3 *last_plane = &(segment[numsegs].EdgePlane[0]);
589 top = last_point - last_plane[TOP_EDGE] *
Vector3::Dot_Product(last_plane[TOP_EDGE], last_point);
591 intersection[last_isec][TOP_EDGE].Direction = top;
592 bottom = last_point - last_plane[BOTTOM_EDGE] *
Vector3::Dot_Product(last_plane[BOTTOM_EDGE], last_point);
594 intersection[last_isec][BOTTOM_EDGE].Direction = bottom;
596 segdir = points[point_cnt - 1] - points[point_cnt - 2];
602 segment[numsegs + 1].StartPlane = segment[numsegs + 1].EdgePlane[TOP_EDGE] =
603 segment[numsegs + 1].EdgePlane[BOTTOM_EDGE] = start_pl;
605 segment[numsegs + 1].StartPlane = segment[numsegs + 1].EdgePlane[TOP_EDGE] =
606 segment[numsegs + 1].EdgePlane[BOTTOM_EDGE] = -start_pl;
620 for (iidx = 2; iidx < num_intersections[TOP_EDGE]; iidx++) {
623 Vector3 &midpoint = points[iidx - 1];
624 float mid_tex_v = tex_v[iidx - 1];
625 Vector4 mid_diffuse = diffuse[iidx - 1];
628 intersection[iidx][TOP_EDGE].PointCount = 1;
629 intersection[iidx][TOP_EDGE].NextSegmentID = iidx;
630 intersection[iidx][TOP_EDGE].Point = midpoint;
631 intersection[iidx][TOP_EDGE].TexV = mid_tex_v;
632 intersection[iidx][TOP_EDGE].RGBA = mid_diffuse;
633 intersection[iidx][BOTTOM_EDGE].PointCount = 1;
634 intersection[iidx][BOTTOM_EDGE].NextSegmentID = iidx;
635 intersection[iidx][BOTTOM_EDGE].Point = midpoint;
636 intersection[iidx][BOTTOM_EDGE].TexV = mid_tex_v;
637 intersection[iidx][BOTTOM_EDGE].RGBA = mid_diffuse;
645 vdp =
Vector3::Dot_Product(segment[iidx - 1].EdgePlane[TOP_EDGE], segment[iidx].EdgePlane[TOP_EDGE]);
646 if (fabs(vdp) < parallel_factor) {
651 &(intersection[iidx][TOP_EDGE].Direction));
652 intersection[iidx][TOP_EDGE].Direction.Normalize();
654 intersection[iidx][TOP_EDGE].Direction = -intersection[iidx][TOP_EDGE].Direction;
657 intersection[iidx][TOP_EDGE].Parallel =
false;
666 pl = segment[iidx - 1].EdgePlane[TOP_EDGE] + segment[iidx].EdgePlane[TOP_EDGE];
668 pl = segment[iidx - 1].EdgePlane[TOP_EDGE] - segment[iidx].EdgePlane[TOP_EDGE];
673 intersection[iidx][TOP_EDGE].Direction.Normalize();
675 intersection[iidx][TOP_EDGE].Parallel =
true;
679 vdp =
Vector3::Dot_Product(segment[iidx - 1].EdgePlane[BOTTOM_EDGE], segment[iidx].EdgePlane[BOTTOM_EDGE]);
680 if (fabs(vdp) < parallel_factor) {
685 &(intersection[iidx][BOTTOM_EDGE].Direction));
686 intersection[iidx][BOTTOM_EDGE].Direction.Normalize();
688 intersection[iidx][BOTTOM_EDGE].Direction = -intersection[iidx][BOTTOM_EDGE].Direction;
691 intersection[iidx][BOTTOM_EDGE].Parallel =
false;
700 pl = segment[iidx - 1].EdgePlane[BOTTOM_EDGE] + segment[iidx].EdgePlane[BOTTOM_EDGE];
702 pl = segment[iidx - 1].EdgePlane[BOTTOM_EDGE] - segment[iidx].EdgePlane[BOTTOM_EDGE];
707 intersection[iidx][BOTTOM_EDGE].Direction.Normalize();
709 intersection[iidx][BOTTOM_EDGE].Parallel =
true;
713 Vector3::Cross_Product(intersection[iidx][TOP_EDGE].Direction, intersection[iidx][BOTTOM_EDGE].Direction, &start_pl);
717 segment[iidx].StartPlane = start_pl;
719 segment[iidx].StartPlane = -start_pl;
747 for (edge = FIRST_EDGE; edge <= MAX_EDGE; edge = (SegmentEdge)((int)edge + 1)) {
753 unsigned int num_isects = num_intersections[edge];
754 for (iidx_r = 1, iidx_w = 1; iidx_r < num_isects; iidx_r++, iidx_w++) {
767 LineSegmentIntersection *curr_int = &(intersection[iidx_r][edge]);
768 LineSegmentIntersection *next_int = &(intersection[iidx_r + 1][edge]);
769 LineSegmentIntersection *write_int = &(intersection[iidx_w][edge]);
770 LineSegmentIntersection *prev_int = &(intersection[iidx_w - 1][edge]);
771 LineSegment *next_seg = &(segment[next_int->NextSegmentID]);
772 LineSegment *curr_seg = &(segment[curr_int->NextSegmentID]);
773 LineSegment *prev_seg = &(segment[prev_int->NextSegmentID]);
779 while ( (!next_int->Fold &&
790 unsigned int new_count = curr_int->PointCount + next_int->PointCount;
791 float oo_new_count = 1.0f / (float)new_count;
792 float curr_factor = oo_new_count * (float)curr_int->PointCount;
793 float next_factor = oo_new_count * (float)curr_int->PointCount;
794 Vector3 new_point = curr_int->Point * curr_factor + next_int->Point * next_factor;
795 float new_tex_v = curr_int->TexV * curr_factor + next_int->TexV * next_factor;
796 Vector4 new_diffuse = curr_int->RGBA * curr_factor + next_int->RGBA * next_factor;
802 if (fabs(vdp) < parallel_factor) {
809 new_direction = -new_direction;
812 new_parallel =
false;
825 pl = prev_seg->EdgePlane[edge] + next_seg->EdgePlane[edge];
827 pl = prev_seg->EdgePlane[edge] - next_seg->EdgePlane[edge];
831 if (curr_int->Parallel) {
845 if (MergeAbortFactor > 0.0f) {
846 float abort_dist = radius * MergeAbortFactor;
847 float abort_dist2 = abort_dist * abort_dist;
848 Vector3 diff_curr = curr_int->Point -
850 if (diff_curr.
Length2() > abort_dist2)
break;
851 Vector3 next_curr = next_int->Point -
853 if (next_curr.
Length2() > abort_dist2)
break;
859 curr_int->Direction = new_direction;
860 curr_int->Parallel = new_parallel;
861 curr_int->Point = new_point;
862 curr_int->TexV = new_tex_v;
863 curr_int->RGBA = new_diffuse;
864 curr_int->PointCount = new_count;
865 curr_int->NextSegmentID = next_int->NextSegmentID;
866 curr_int->Fold = curr_int->Fold || next_int->Fold;
869 num_intersections[edge]--;
875 if (iidx_r == num_isects) {
880 next_int = &(intersection[iidx_r + 1][edge]);
881 next_seg = &(segment[next_int->NextSegmentID]);
886 write_int->PointCount = curr_int->PointCount;
887 write_int->NextSegmentID = curr_int->NextSegmentID;
888 write_int->Point = curr_int->Point;
889 write_int->TexV = curr_int->TexV;
890 write_int->RGBA = curr_int->RGBA;
891 write_int->Direction = curr_int->Direction;
892 write_int->Fold = curr_int->Fold;
899 if (iidx_r == num_isects) {
900 LineSegmentIntersection *write_int = &(intersection[iidx_w][edge]);
901 LineSegmentIntersection *curr_int = &(intersection[iidx_r][edge]);
902 write_int->PointCount = curr_int->PointCount;
903 write_int->NextSegmentID = curr_int->NextSegmentID;
904 write_int->Point = curr_int->Point;
905 write_int->TexV = curr_int->TexV;
906 write_int->RGBA = curr_int->RGBA;
907 write_int->Direction = curr_int->Direction;
908 write_int->Fold = curr_int->Fold;
911#ifdef ENABLE_WWDEBUGGING
913 unsigned int total_cnt = 0;
914 for (
unsigned int nidx = 0; nidx <= num_intersections[edge]; nidx++) {
915 total_cnt += intersection[nidx][edge].PointCount;
917 assert(total_cnt == point_cnt);
932 unsigned int vnum = num_intersections[TOP_EDGE] + num_intersections[BOTTOM_EDGE];
937 unsigned int vidx = 0;
938 unsigned int tidx = 0;
943 Vector3 &top_dir = intersection[1][TOP_EDGE].Direction;
945 Vector3 &bottom_dir = intersection[1][BOTTOM_EDGE].Direction;
947 vArray[vidx].
x = top.
X;
948 vArray[vidx].
y = top.
Y;
949 vArray[vidx].
z = top.
Z;
951 vArray[vidx].
u1 = u_values[0] + uv_offset.
X;
952 vArray[vidx].
v1 = intersection[1][TOP_EDGE].TexV + uv_offset.
Y;
954 vArray[vidx].
x = bottom.
X;
955 vArray[vidx].
y = bottom.
Y;
956 vArray[vidx].
z = bottom.
Z;
958 vArray[vidx].
u1 = u_values[1] + uv_offset.
X;
959 vArray[vidx].
v1 = intersection[1][BOTTOM_EDGE].TexV + uv_offset.
Y;
962 unsigned int last_top_vidx = 0;
963 unsigned int last_bottom_vidx = 1;
966 unsigned int top_int_idx = 1;
967 unsigned int bottom_int_idx = 1;
969 unsigned int residual_top_points = intersection[1][TOP_EDGE].PointCount;
970 unsigned int residual_bottom_points = intersection[1][BOTTOM_EDGE].PointCount;
973 unsigned int delta =
MIN(residual_top_points, residual_bottom_points) - 1;
974 residual_top_points -= delta;
975 residual_bottom_points -= delta;
980 if (residual_top_points == 1 && residual_bottom_points == 1) {
982 v_index_array[tidx].
I = last_top_vidx;
983 v_index_array[tidx].
J = last_bottom_vidx;
984 v_index_array[tidx].
K = vidx;
986 v_index_array[tidx].
I = last_bottom_vidx;
987 v_index_array[tidx].
J = vidx + 1;
988 v_index_array[tidx].
K = vidx;
990 last_top_vidx = vidx;
991 last_bottom_vidx = vidx + 1;
996 residual_top_points = intersection[top_int_idx][TOP_EDGE].PointCount;
997 residual_bottom_points = intersection[bottom_int_idx][BOTTOM_EDGE].PointCount;
1003 Vector3 &top_dir = intersection[top_int_idx][TOP_EDGE].Direction;
1005 Vector3 &bottom_dir = intersection[bottom_int_idx][BOTTOM_EDGE].Direction;
1008 vArray[vidx].
x = top.
X;
1009 vArray[vidx].
y = top.
Y;
1010 vArray[vidx].
z = top.
Z;
1012 vArray[vidx].
u1 = u_values[0] + uv_offset.
X;
1013 vArray[vidx].
v1 = intersection[top_int_idx][TOP_EDGE].TexV + uv_offset.
Y;
1015 vArray[vidx].
x = bottom.
X;
1016 vArray[vidx].
y = bottom.
Y;
1017 vArray[vidx].
z = bottom.
Z;
1019 vArray[vidx].
u1 = u_values[1] + uv_offset.
X;
1020 vArray[vidx].
v1 = intersection[bottom_int_idx][BOTTOM_EDGE].TexV + uv_offset.
Y;
1024 if (residual_top_points > 1) {
1026 v_index_array[tidx].
I = last_top_vidx;
1027 v_index_array[tidx].
J = last_bottom_vidx;
1028 v_index_array[tidx].
K = vidx;
1030 last_bottom_vidx = vidx;
1033 residual_top_points--;
1035 residual_bottom_points = intersection[bottom_int_idx][BOTTOM_EDGE].PointCount;
1041 Vector3 &bottom_dir = intersection[bottom_int_idx][BOTTOM_EDGE].Direction;
1044 vArray[vidx].
x = bottom.
X;
1045 vArray[vidx].
y = bottom.
Y;
1046 vArray[vidx].
z = bottom.
Z;
1048 vArray[vidx].
u1 = u_values[1] + uv_offset.
X;
1049 vArray[vidx].
v1 = intersection[bottom_int_idx][BOTTOM_EDGE].TexV + uv_offset.
Y;
1056 v_index_array[tidx].
I = last_top_vidx;
1057 v_index_array[tidx].
J = last_bottom_vidx;
1058 v_index_array[tidx].
K = vidx;
1060 last_top_vidx = vidx;
1063 residual_bottom_points--;
1065 residual_top_points = intersection[top_int_idx][TOP_EDGE].PointCount;
1071 Vector3 &top_dir = intersection[top_int_idx][TOP_EDGE].Direction;
1073 vArray[vidx].
x = top.
X;
1074 vArray[vidx].
y = top.
Y;
1075 vArray[vidx].
z = top.
Z;
1077 vArray[vidx].
u1 = u_values[0] + uv_offset.
X;
1078 vArray[vidx].
v1 = intersection[top_int_idx][TOP_EDGE].TexV + uv_offset.
Y;
1084 delta =
MIN(residual_top_points, residual_bottom_points) - 1;
1085 residual_top_points -= delta;
1086 residual_bottom_points -= delta;
1090 if ( (top_int_idx >= num_intersections[TOP_EDGE] && residual_top_points == 1) ||
1091 (bottom_int_idx >= num_intersections[BOTTOM_EDGE] && residual_bottom_points == 1)) {
1094 assert(top_int_idx == num_intersections[TOP_EDGE]);
1095 assert(bottom_int_idx == num_intersections[BOTTOM_EDGE]);
1096 assert(pidx == point_cnt - 1);
1108 bool rgba_all=(rgba==0xFFFFFFFF);
1119 if (!rgba_all || (rgba != 0) ) {
1153 for (i=0; i<vnum; i++)
1156 Vector3 *vertex =
reinterpret_cast<Vector3 *
>(vb + verticesOffset);
1157 vertex->
X = vArray[i].
x;
1158 vertex->
Y = vArray[i].
y;
1159 vertex->
Z = vArray[i].
z;
1160 *
reinterpret_cast<unsigned int *
>(vb + diffuseOffset) = vArray[i].diffuse;
1161 Vector2 *texture =
reinterpret_cast<Vector2 *
>(vb + textureOffset);
1162 texture->
U = vArray[i].
u1;
1163 texture->
V = vArray[i].
v1;
1175 for (i=0; i<tidx; i++)
1177 *inds++=v_index_array[i].
I;
1178 *inds++=v_index_array[i].
J;
1179 *inds++=v_index_array[i].
K;