aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/PrimMesher.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/PrimMesher.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/PrimMesher.cs207
1 files changed, 150 insertions, 57 deletions
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
index 53cae56..d49ac44 100644
--- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs
+++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
@@ -415,7 +415,7 @@ namespace PrimMesher
415 415
416 internal List<Coord> coords; 416 internal List<Coord> coords;
417 internal List<Face> faces; 417 internal List<Face> faces;
418 internal List<Coord> normals; 418 internal List<Coord> edgeNormals;
419 419
420 internal bool calcVertexNormals = false; 420 internal bool calcVertexNormals = false;
421 421
@@ -423,7 +423,7 @@ namespace PrimMesher
423 { 423 {
424 this.coords = new List<Coord>(); 424 this.coords = new List<Coord>();
425 this.faces = new List<Face>(); 425 this.faces = new List<Face>();
426 this.normals = new List<Coord>(); 426 this.edgeNormals = new List<Coord>();
427 } 427 }
428 428
429 public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) 429 public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals)
@@ -431,9 +431,14 @@ namespace PrimMesher
431 this.calcVertexNormals = calcVertexNormals; 431 this.calcVertexNormals = calcVertexNormals;
432 this.coords = new List<Coord>(); 432 this.coords = new List<Coord>();
433 this.faces = new List<Face>(); 433 this.faces = new List<Face>();
434 this.normals = new List<Coord>(); 434 this.edgeNormals = new List<Coord>();
435 Coord center = new Coord(0.0f, 0.0f, 0.0f); 435 Coord center = new Coord(0.0f, 0.0f, 0.0f);
436
436 List<Coord> hollowCoords = new List<Coord>(); 437 List<Coord> hollowCoords = new List<Coord>();
438 List<Coord> hollowNormals = new List<Coord>();
439
440 bool hasHollow = (hollow > 0.0f);
441 bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f);
437 442
438 AngleList angles = new AngleList(); 443 AngleList angles = new AngleList();
439 AngleList hollowAngles = new AngleList(); 444 AngleList hollowAngles = new AngleList();
@@ -458,25 +463,10 @@ namespace PrimMesher
458 return; 463 return;
459 } 464 }
460 465
461 bool simpleFace = false; // flag to create as few triangles as possible for 3 or 4 side profile 466 // flag to create as few triangles as possible for 3 or 4 side profile
462 if (sides < 5 && hollow == 0.0f && profileStart == 0.0f && profileEnd == 1.0f) 467 bool simpleFace = (sides < 5 && !(hasHollow || hasProfileCut));
463 simpleFace = true;
464
465 if (this.calcVertexNormals)
466 {
467 if (sides > 4)
468 foreach (Angle a in angles.angles)
469 normals.Add(new Coord(a.X, a.Y, 0.0f));
470 else
471 for (int i = 0; i < angles.angles.Count - 1; i++)
472 {
473 Angle a1 = angles.angles[i];
474 Angle a2 = angles.angles[i + 1];
475 normals.Add(new Coord(0.5f * (a1.X + a2.X), 0.5f * (a1.Y + a2.Y), 0.0f).Normalize());
476 }
477 }
478 468
479 if (hollow > 0.001f) 469 if (hasHollow)
480 { 470 {
481 if (sides == hollowSides) 471 if (sides == hollowSides)
482 hollowAngles = angles; 472 hollowAngles = angles;
@@ -490,33 +480,19 @@ namespace PrimMesher
490 return; 480 return;
491 } 481 }
492 } 482 }
493
494 if (this.calcVertexNormals)
495 {
496 if (hollowSides > 4)
497 foreach (Angle a in hollowAngles.angles)
498 normals.Add(new Coord(-a.X, -a.Y, 0.0f));
499 else
500 for (int i = 0; i < hollowAngles.angles.Count - 1; i++)
501 {
502 Angle a1 = hollowAngles.angles[i];
503 Angle a2 = hollowAngles.angles[i + 1];
504 normals.Add(new Coord(-0.5f * (a1.X + a2.X), -0.5f * (a1.Y + a2.Y), 0.0f).Normalize());
505 }
506 }
507 } 483 }
508 else if (!simpleFace) 484 else if (!simpleFace)
509 { 485 {
510 this.coords.Add(center); 486 this.coords.Add(center);
511 if (this.calcVertexNormals && sides > 4) 487 if (this.calcVertexNormals && sides > 4)
512 this.normals.Add(new Coord(0.0f, 0.0f, 1.0f)); 488 this.edgeNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
513 } 489 }
514 490
515 float z = 0.0f; 491 float z = 0.0f;
516 492
517 Angle angle; 493 Angle angle;
518 Coord newVert = new Coord(); 494 Coord newVert = new Coord();
519 if (hollow > 0.001f && hollowSides != sides) 495 if (hasHollow && hollowSides != sides)
520 { 496 {
521 int numHollowAngles = hollowAngles.angles.Count; 497 int numHollowAngles = hollowAngles.angles.Count;
522 for (int i = 0; i < numHollowAngles; i++) 498 for (int i = 0; i < numHollowAngles; i++)
@@ -527,6 +503,8 @@ namespace PrimMesher
527 newVert.Z = z; 503 newVert.Z = z;
528 504
529 hollowCoords.Add(newVert); 505 hollowCoords.Add(newVert);
506 if (this.calcVertexNormals)
507 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
530 } 508 }
531 } 509 }
532 510
@@ -539,6 +517,8 @@ namespace PrimMesher
539 newVert.Y = angle.Y * yScale; 517 newVert.Y = angle.Y * yScale;
540 newVert.Z = z; 518 newVert.Z = z;
541 this.coords.Add(newVert); 519 this.coords.Add(newVert);
520 if (this.calcVertexNormals)
521 this.edgeNormals.Add(new Coord(angle.X, angle.Y, 0.0f));
542 522
543 if (hollow > 0.0f) 523 if (hollow > 0.0f)
544 { 524 {
@@ -548,6 +528,8 @@ namespace PrimMesher
548 newVert.Y *= hollow; 528 newVert.Y *= hollow;
549 newVert.Z = z; 529 newVert.Z = z;
550 hollowCoords.Add(newVert); 530 hollowCoords.Add(newVert);
531 if (this.calcVertexNormals)
532 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
551 } 533 }
552 } 534 }
553 else if (!simpleFace && createFaces && angle.angle > 0.0001f) 535 else if (!simpleFace && createFaces && angle.angle > 0.0001f)
@@ -556,14 +538,22 @@ namespace PrimMesher
556 newFace.v1 = 0; 538 newFace.v1 = 0;
557 newFace.v2 = index; 539 newFace.v2 = index;
558 newFace.v3 = index + 1; 540 newFace.v3 = index + 1;
541 //if (this.calcVertexNormals)
542 //{
543 // newFace.n1 = newFace.v1;
544 // newFace.n2 = newFace.v2;
545 // newFace.n3 = newFace.v3;
546 //}
559 this.faces.Add(newFace); 547 this.faces.Add(newFace);
560 } 548 }
561 index += 1; 549 index += 1;
562 } 550 }
563 551
564 if (hollow > 0.0f) 552 if (hasHollow)
565 { 553 {
566 hollowCoords.Reverse(); 554 hollowCoords.Reverse();
555 if (this.calcVertexNormals)
556 hollowNormals.Reverse();
567 557
568 if (createFaces) 558 if (createFaces)
569 { 559 {
@@ -580,11 +570,23 @@ namespace PrimMesher
580 newFace.v1 = coordIndex; 570 newFace.v1 = coordIndex;
581 newFace.v2 = coordIndex + 1; 571 newFace.v2 = coordIndex + 1;
582 newFace.v3 = numTotalVerts - coordIndex - 1; 572 newFace.v3 = numTotalVerts - coordIndex - 1;
573 //if (this.calcVertexNormals)
574 //{
575 // newFace.n1 = newFace.v1;
576 // newFace.n2 = newFace.v2;
577 // newFace.n3 = newFace.v3;
578 //}
583 this.faces.Add(newFace); 579 this.faces.Add(newFace);
584 580
585 newFace.v1 = coordIndex + 1; 581 newFace.v1 = coordIndex + 1;
586 newFace.v2 = numTotalVerts - coordIndex - 2; 582 newFace.v2 = numTotalVerts - coordIndex - 2;
587 newFace.v3 = numTotalVerts - coordIndex - 1; 583 newFace.v3 = numTotalVerts - coordIndex - 1;
584 //if (this.calcVertexNormals)
585 //{
586 // newFace.n1 = newFace.v1;
587 // newFace.n2 = newFace.v2;
588 // newFace.n3 = newFace.v3;
589 //}
588 this.faces.Add(newFace); 590 this.faces.Add(newFace);
589 } 591 }
590 } 592 }
@@ -603,6 +605,12 @@ namespace PrimMesher
603 newFace.v1 = numTotalVerts - i - 1; 605 newFace.v1 = numTotalVerts - i - 1;
604 newFace.v2 = j; 606 newFace.v2 = j;
605 newFace.v3 = j + 1; 607 newFace.v3 = j + 1;
608 //if (this.calcVertexNormals)
609 //{
610 // newFace.n1 = newFace.v1;
611 // newFace.n2 = newFace.v2;
612 // newFace.n3 = newFace.v3;
613 //}
606 614
607 this.faces.Add(newFace); 615 this.faces.Add(newFace);
608 j += 1; 616 j += 1;
@@ -611,6 +619,12 @@ namespace PrimMesher
611 newFace.v1 = j; 619 newFace.v1 = j;
612 newFace.v2 = numTotalVerts - i - 2; 620 newFace.v2 = numTotalVerts - i - 2;
613 newFace.v3 = numTotalVerts - i - 1; 621 newFace.v3 = numTotalVerts - i - 1;
622 //if (this.calcVertexNormals)
623 //{
624 // newFace.n1 = newFace.v1;
625 // newFace.n2 = newFace.v2;
626 // newFace.n3 = newFace.v3;
627 //}
614 628
615 this.faces.Add(newFace); 629 this.faces.Add(newFace);
616 } 630 }
@@ -628,6 +642,12 @@ namespace PrimMesher
628 newFace.v1 = i; 642 newFace.v1 = i;
629 newFace.v2 = numTotalVerts - j - 2; 643 newFace.v2 = numTotalVerts - j - 2;
630 newFace.v3 = numTotalVerts - j - 1; 644 newFace.v3 = numTotalVerts - j - 1;
645 //if (this.calcVertexNormals)
646 //{
647 // newFace.n1 = newFace.v1;
648 // newFace.n2 = newFace.v2;
649 // newFace.n3 = newFace.v3;
650 //}
631 651
632 this.faces.Add(newFace); 652 this.faces.Add(newFace);
633 j += 1; 653 j += 1;
@@ -636,6 +656,12 @@ namespace PrimMesher
636 newFace.v1 = numTotalVerts - j - 1; 656 newFace.v1 = numTotalVerts - j - 1;
637 newFace.v2 = i; 657 newFace.v2 = i;
638 newFace.v3 = i + 1; 658 newFace.v3 = i + 1;
659 //if (this.calcVertexNormals)
660 //{
661 // newFace.n1 = newFace.v1;
662 // newFace.n2 = newFace.v2;
663 // newFace.n3 = newFace.v3;
664 //}
639 665
640 this.faces.Add(newFace); 666 this.faces.Add(newFace);
641 } 667 }
@@ -644,6 +670,11 @@ namespace PrimMesher
644 } 670 }
645 671
646 this.coords.AddRange(hollowCoords); 672 this.coords.AddRange(hollowCoords);
673 if (this.calcVertexNormals)
674 this.edgeNormals.AddRange(hollowNormals);
675
676 hollowCoords = null;
677 hollowNormals = null;
647 } 678 }
648 679
649 if (simpleFace && createFaces) 680 if (simpleFace && createFaces)
@@ -671,7 +702,7 @@ namespace PrimMesher
671 clone.coords.AddRange(this.coords); 702 clone.coords.AddRange(this.coords);
672 if (needFaces) 703 if (needFaces)
673 clone.faces.AddRange(this.faces); 704 clone.faces.AddRange(this.faces);
674 clone.normals.AddRange(this.normals); 705 clone.edgeNormals.AddRange(this.edgeNormals);
675 706
676 return clone; 707 return clone;
677 } 708 }
@@ -714,16 +745,16 @@ namespace PrimMesher
714 this.coords[i] = c; 745 this.coords[i] = c;
715 } 746 }
716 747
717 int numNormals = this.normals.Count; 748 int numNormals = this.edgeNormals.Count;
718 for (i = 0; i < numNormals; i++) 749 for (i = 0; i < numNormals; i++)
719 { 750 {
720 c = this.normals[i]; 751 c = this.edgeNormals[i];
721 Coord n = new Coord(c.X, c.Y, c.Z) * q; 752 Coord n = new Coord(c.X, c.Y, c.Z) * q;
722 753
723 c.X = n.X; 754 c.X = n.X;
724 c.Y = n.Y; 755 c.Y = n.Y;
725 c.Z = n.Z; 756 c.Z = n.Z;
726 this.normals[i] = c; 757 this.edgeNormals[i] = c;
727 } 758 }
728 } 759 }
729 760
@@ -763,12 +794,12 @@ namespace PrimMesher
763 794
764 if (this.calcVertexNormals) 795 if (this.calcVertexNormals)
765 { 796 {
766 int normalCount = this.normals.Count; 797 int normalCount = this.edgeNormals.Count;
767 if (normalCount > 0) 798 if (normalCount > 0)
768 { 799 {
769 Coord n = this.normals[normalCount - 1]; 800 Coord n = this.edgeNormals[normalCount - 1];
770 n.Z *= 1.0f; 801 n.Z = -n.Z;
771 this.normals[normalCount - 1] = n; 802 this.edgeNormals[normalCount - 1] = n;
772 } 803 }
773 } 804 }
774 } 805 }
@@ -858,6 +889,9 @@ namespace PrimMesher
858 public int stepsPerRevolution = 24; 889 public int stepsPerRevolution = 24;
859 890
860 public bool calcVertexNormals = false; 891 public bool calcVertexNormals = false;
892 private bool normalsProcessed = false;
893
894 private List<Coord> edgeNormals;
861 895
862 public string ParamsToDisplayString() 896 public string ParamsToDisplayString()
863 { 897 {
@@ -922,10 +956,16 @@ namespace PrimMesher
922 this.coords = new List<Coord>(); 956 this.coords = new List<Coord>();
923 this.faces = new List<Face>(); 957 this.faces = new List<Face>();
924 958
959 if (this.calcVertexNormals)
960 this.normals = new List<Coord>();
961
925 int step = 0; 962 int step = 0;
926 int steps = 1; 963 int steps = 1;
927 964
928 float length = this.pathCutEnd - this.pathCutBegin; 965 float length = this.pathCutEnd - this.pathCutBegin;
966 normalsProcessed = false;
967 if (this.calcVertexNormals)
968 this.edgeNormals = new List<Coord>();
929 969
930#if VIEWER 970#if VIEWER
931 if (this.sides == 3) 971 if (this.sides == 3)
@@ -1026,6 +1066,12 @@ namespace PrimMesher
1026 1066
1027 this.coords.AddRange(newLayer.coords); 1067 this.coords.AddRange(newLayer.coords);
1028 1068
1069 if (this.calcVertexNormals)
1070 {
1071 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
1072 this.normals.AddRange(newLayer.edgeNormals);
1073 }
1074
1029 if (percentOfPath <= this.pathCutBegin || percentOfPath >= this.pathCutEnd) 1075 if (percentOfPath <= this.pathCutBegin || percentOfPath >= this.pathCutEnd)
1030 this.faces.AddRange(newLayer.faces); 1076 this.faces.AddRange(newLayer.faces);
1031 1077
@@ -1047,10 +1093,21 @@ namespace PrimMesher
1047 newFace.v1 = i; 1093 newFace.v1 = i;
1048 newFace.v2 = i - numVerts; 1094 newFace.v2 = i - numVerts;
1049 newFace.v3 = i - numVerts + 1; 1095 newFace.v3 = i - numVerts + 1;
1096 if (this.calcVertexNormals)
1097 {
1098 newFace.n1 = newFace.v1;
1099 newFace.n2 = newFace.v2;
1100 newFace.n3 = newFace.v3;
1101 }
1050 this.faces.Add(newFace); 1102 this.faces.Add(newFace);
1051 1103
1052 newFace.v2 = i - numVerts + 1; 1104 newFace.v2 = i - numVerts + 1;
1053 newFace.v3 = i + 1; 1105 newFace.v3 = i + 1;
1106 if (this.calcVertexNormals)
1107 {
1108 newFace.n2 = newFace.v2;
1109 newFace.n3 = newFace.v3;
1110 }
1054 this.faces.Add(newFace); 1111 this.faces.Add(newFace);
1055 } 1112 }
1056 1113
@@ -1059,11 +1116,25 @@ namespace PrimMesher
1059 newFace.v1 = coordsLen - 1; 1116 newFace.v1 = coordsLen - 1;
1060 newFace.v2 = coordsLen - numVerts; 1117 newFace.v2 = coordsLen - numVerts;
1061 newFace.v3 = coordsLen; 1118 newFace.v3 = coordsLen;
1119 if (this.calcVertexNormals)
1120 {
1121 Coord n1 = SurfaceNormal(newFace);
1122 this.normals.Add(n1);
1123
1124 newFace.n1 = newFace.n2 = newFace.n3 = this.normals.Count - 1;
1125 }
1062 this.faces.Add(newFace); 1126 this.faces.Add(newFace);
1063 1127
1064 newFace.v1 = coordsLen + numVerts - 1; 1128 newFace.v1 = coordsLen + numVerts - 1;
1065 newFace.v2 = coordsLen - 1; 1129 newFace.v2 = coordsLen - 1;
1066 newFace.v3 = coordsLen; 1130 newFace.v3 = coordsLen;
1131 if (this.calcVertexNormals)
1132 {
1133 Coord n1 = SurfaceNormal(newFace);
1134 this.normals.Add(n1);
1135
1136 newFace.n1 = newFace.n2 = newFace.n3 = this.normals.Count - 1;
1137 }
1067 this.faces.Add(newFace); 1138 this.faces.Add(newFace);
1068 } 1139 }
1069 1140
@@ -1084,8 +1155,8 @@ namespace PrimMesher
1084 else done = true; 1155 else done = true;
1085 } 1156 }
1086 1157
1087 if (calcVertexNormals && sides < 5 && twistBegin == 0.0f && twistEnd == 0.0f) 1158 //if (calcVertexNormals && sides < 5 && twistBegin == 0.0f && twistEnd == 0.0f)
1088 this.CalcNormals(); 1159 // this.CalcNormals();
1089 } 1160 }
1090 1161
1091 public void ExtrudeCircular() 1162 public void ExtrudeCircular()
@@ -1093,9 +1164,14 @@ namespace PrimMesher
1093 this.coords = new List<Coord>(); 1164 this.coords = new List<Coord>();
1094 this.faces = new List<Face>(); 1165 this.faces = new List<Face>();
1095 1166
1167 if (this.calcVertexNormals)
1168 this.normals = new List<Coord>();
1169
1096 int step = 0; 1170 int step = 0;
1097 int steps = 24; 1171 int steps = 24;
1098 1172
1173 normalsProcessed = false;
1174
1099 float twistBegin = this.twistBegin / 360.0f * twoPi; 1175 float twistBegin = this.twistBegin / 360.0f * twoPi;
1100 float twistEnd = this.twistEnd / 360.0f * twoPi; 1176 float twistEnd = this.twistEnd / 360.0f * twoPi;
1101 float twistTotal = twistEnd - twistBegin; 1177 float twistTotal = twistEnd - twistBegin;
@@ -1248,6 +1324,12 @@ namespace PrimMesher
1248 1324
1249 this.coords.AddRange(newLayer.coords); 1325 this.coords.AddRange(newLayer.coords);
1250 1326
1327 if (this.calcVertexNormals)
1328 {
1329 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
1330 this.normals.AddRange(newLayer.edgeNormals);
1331 }
1332
1251 if (isEndLayer) 1333 if (isEndLayer)
1252 this.faces.AddRange(newLayer.faces); 1334 this.faces.AddRange(newLayer.faces);
1253 1335
@@ -1305,15 +1387,8 @@ namespace PrimMesher
1305 } 1387 }
1306 } 1388 }
1307 1389
1308 public Coord SurfaceNormal(int faceIndex) 1390 private Coord SurfaceNormal(Face face)
1309 { 1391 {
1310 int numFaces = faces.Count;
1311 if (faceIndex < 0 || faceIndex >= faces.Count)
1312 throw new Exception("faceIndex out of range");
1313
1314 //return new Coord(0.0f, 0.0f, 0.0f);
1315
1316 Face face = faces[faceIndex];
1317 Coord c1 = coords[face.v1]; 1392 Coord c1 = coords[face.v1];
1318 Coord c2 = coords[face.v2]; 1393 Coord c2 = coords[face.v2];
1319 Coord c3 = coords[face.v3]; 1394 Coord c3 = coords[face.v3];
@@ -1328,10 +1403,28 @@ namespace PrimMesher
1328 return normal; 1403 return normal;
1329 } 1404 }
1330 1405
1406 public Coord SurfaceNormal(int faceIndex)
1407 {
1408 int numFaces = faces.Count;
1409 if (faceIndex < 0 || faceIndex >= faces.Count)
1410 throw new Exception("faceIndex out of range");
1411
1412 //return new Coord(0.0f, 0.0f, 0.0f);
1413
1414 return SurfaceNormal(faces[faceIndex]);
1415 }
1416
1331 public void CalcNormals() 1417 public void CalcNormals()
1332 { 1418 {
1419 if (normalsProcessed)
1420 return;
1421
1422 normalsProcessed = true;
1423
1333 int numFaces = faces.Count; 1424 int numFaces = faces.Count;
1334 this.normals = new List<Coord>(); 1425
1426 if (!this.calcVertexNormals)
1427 this.normals = new List<Coord>();
1335 1428
1336 for (int i = 0; i < numFaces; i++) 1429 for (int i = 0; i < numFaces; i++)
1337 { 1430 {