aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorDahlia Trimble2008-10-19 09:04:25 +0000
committerDahlia Trimble2008-10-19 09:04:25 +0000
commitb6396bc9a73ee8dbb2cef8708f7876e21a448f0c (patch)
treeb4105613e29909c0cc3afbbc78cbd318509c0292 /OpenSim/Region/Physics
parent* Null check before UseCircuitCode Check or the server crashes on packet loss! (diff)
downloadopensim-SC_OLD-b6396bc9a73ee8dbb2cef8708f7876e21a448f0c.zip
opensim-SC_OLD-b6396bc9a73ee8dbb2cef8708f7876e21a448f0c.tar.gz
opensim-SC_OLD-b6396bc9a73ee8dbb2cef8708f7876e21a448f0c.tar.bz2
opensim-SC_OLD-b6396bc9a73ee8dbb2cef8708f7876e21a448f0c.tar.xz
More progress towards implementing vertex normals - not complete yet.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/Meshing/PrimMesher.cs487
1 files changed, 371 insertions, 116 deletions
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
index 98c7b5b..4814c4a 100644
--- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs
+++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
@@ -192,8 +192,23 @@ namespace PrimMesher
192 } 192 }
193 } 193 }
194 194
195 public struct UVCoord
196 {
197 public float U;
198 public float V;
199
200
201 public UVCoord(float u, float v)
202 {
203 this.U = u;
204 this.V = v;
205 }
206 }
207
195 public struct Face 208 public struct Face
196 { 209 {
210 public int primFace;
211
197 // vertices 212 // vertices
198 public int v1; 213 public int v1;
199 public int v2; 214 public int v2;
@@ -204,8 +219,15 @@ namespace PrimMesher
204 public int n2; 219 public int n2;
205 public int n3; 220 public int n3;
206 221
222 //// UVs
223 //public int uv1;
224 //public int uv2;
225 //public int uv3;
226
207 public Face(int v1, int v2, int v3) 227 public Face(int v1, int v2, int v3)
208 { 228 {
229 primFace = 0;
230
209 this.v1 = v1; 231 this.v1 = v1;
210 this.v2 = v2; 232 this.v2 = v2;
211 this.v3 = v3; 233 this.v3 = v3;
@@ -213,10 +235,16 @@ namespace PrimMesher
213 this.n1 = 0; 235 this.n1 = 0;
214 this.n2 = 0; 236 this.n2 = 0;
215 this.n3 = 0; 237 this.n3 = 0;
238
239 //this.uv1 = 0;
240 //this.uv2 = 0;
241 //this.uv3 = 0;
216 } 242 }
217 243
218 public Face(int v1, int v2, int v3, int n1, int n2, int n3) 244 public Face(int v1, int v2, int v3, int n1, int n2, int n3)
219 { 245 {
246 primFace = 0;
247
220 this.v1 = v1; 248 this.v1 = v1;
221 this.v2 = v2; 249 this.v2 = v2;
222 this.v3 = v3; 250 this.v3 = v3;
@@ -224,6 +252,85 @@ namespace PrimMesher
224 this.n1 = n1; 252 this.n1 = n1;
225 this.n2 = n2; 253 this.n2 = n2;
226 this.n3 = n3; 254 this.n3 = n3;
255
256 //this.uv1 = 0;
257 //this.uv2 = 0;
258 //this.uv3 = 0;
259 }
260 }
261
262 public struct ViewerFace
263 {
264 public int primFaceNumber;
265
266 public Coord v1;
267 public Coord v2;
268 public Coord v3;
269
270 public Coord n1;
271 public Coord n2;
272 public Coord n3;
273
274 public UVCoord uv1;
275 public UVCoord uv2;
276 public UVCoord uv3;
277
278 public ViewerFace(int primFaceNumber)
279 {
280 this.primFaceNumber = primFaceNumber;
281
282 this.v1 = new Coord();
283 this.v2 = new Coord();
284 this.v3 = new Coord();
285
286 this.n1 = new Coord();
287 this.n2 = new Coord();
288 this.n3 = new Coord();
289
290 this.uv1 = new UVCoord();
291 this.uv2 = new UVCoord();
292 this.uv3 = new UVCoord();
293 }
294
295 public void Scale(float x, float y, float z)
296 {
297 this.v1.X *= x;
298 this.v1.Y *= y;
299 this.v1.Z *= z;
300
301 this.v2.X *= x;
302 this.v2.Y *= y;
303 this.v2.Z *= z;
304
305 this.v3.X *= x;
306 this.v3.Y *= y;
307 this.v3.Z *= z;
308 }
309
310 public void AddRot(Quat q)
311 {
312 this.v1 *= q;
313 this.v2 *= q;
314 this.v3 *= q;
315
316 this.n1 *= q;
317 this.n2 *= q;
318 this.n3 *= q;
319 }
320
321 public void CalcSurfaceNormal()
322 {
323
324 Coord edge1 = new Coord(this.n2.X - this.n1.X, this.n2.Y - this.n1.Y, this.n2.Z - this.n1.Z);
325 Coord edge2 = new Coord(this.n3.X - this.n1.X, this.n3.Y - this.n1.Y, this.n3.Z - this.n1.Z);
326
327 //Coord normal = Coord.Cross(edge1, edge2).Normalize();
328
329 //this.n1 = normal;
330 //this.n2 = normal;
331 //this.n3 = normal;
332
333 this.n1 = this.n2 = this.n3 = Coord.Cross(edge1, edge2).Normalize();
227 } 334 }
228 } 335 }
229 336
@@ -415,7 +522,13 @@ namespace PrimMesher
415 522
416 internal List<Coord> coords; 523 internal List<Coord> coords;
417 internal List<Face> faces; 524 internal List<Face> faces;
418 internal List<Coord> edgeNormals; 525 internal List<Coord> vertexNormals;
526 internal Coord faceNormal = new Coord(0.0f, 0.0f, 1.0f);
527 internal Coord cutNormal1 = new Coord();
528 internal Coord cutNormal2 = new Coord();
529
530 internal int numOuterVerts = 0;
531 internal int numHollowVerts = 0;
419 532
420 internal bool calcVertexNormals = false; 533 internal bool calcVertexNormals = false;
421 534
@@ -423,7 +536,7 @@ namespace PrimMesher
423 { 536 {
424 this.coords = new List<Coord>(); 537 this.coords = new List<Coord>();
425 this.faces = new List<Face>(); 538 this.faces = new List<Face>();
426 this.edgeNormals = new List<Coord>(); 539 this.vertexNormals = new List<Coord>();
427 } 540 }
428 541
429 public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals) 542 public Profile(int sides, float profileStart, float profileEnd, float hollow, int hollowSides, bool createFaces, bool calcVertexNormals)
@@ -431,13 +544,15 @@ namespace PrimMesher
431 this.calcVertexNormals = calcVertexNormals; 544 this.calcVertexNormals = calcVertexNormals;
432 this.coords = new List<Coord>(); 545 this.coords = new List<Coord>();
433 this.faces = new List<Face>(); 546 this.faces = new List<Face>();
434 this.edgeNormals = new List<Coord>(); 547 this.vertexNormals = new List<Coord>();
435 Coord center = new Coord(0.0f, 0.0f, 0.0f); 548 Coord center = new Coord(0.0f, 0.0f, 0.0f);
436 549
437 List<Coord> hollowCoords = new List<Coord>(); 550 List<Coord> hollowCoords = new List<Coord>();
438 List<Coord> hollowNormals = new List<Coord>(); 551 List<Coord> hollowNormals = new List<Coord>();
439 552
553 //Quat rot180 = new Quat(new Coord(0.0f, 0.0f, 1.0f), (float)Math.PI); ;
440 bool hasHollow = (hollow > 0.0f); 554 bool hasHollow = (hollow > 0.0f);
555
441 bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f); 556 bool hasProfileCut = (profileStart > 0.0f || profileEnd < 1.0f);
442 557
443 AngleList angles = new AngleList(); 558 AngleList angles = new AngleList();
@@ -463,6 +578,8 @@ namespace PrimMesher
463 return; 578 return;
464 } 579 }
465 580
581 this.numOuterVerts = angles.angles.Count;
582
466 // flag to create as few triangles as possible for 3 or 4 side profile 583 // flag to create as few triangles as possible for 3 or 4 side profile
467 bool simpleFace = (sides < 5 && !(hasHollow || hasProfileCut)); 584 bool simpleFace = (sides < 5 && !(hasHollow || hasProfileCut));
468 585
@@ -480,12 +597,13 @@ namespace PrimMesher
480 return; 597 return;
481 } 598 }
482 } 599 }
600 this.numHollowVerts = hollowAngles.angles.Count;
483 } 601 }
484 else if (!simpleFace) 602 else if (!simpleFace)
485 { 603 {
486 this.coords.Add(center); 604 this.coords.Add(center);
487 if (this.calcVertexNormals && sides > 4) 605 if (this.calcVertexNormals)// && sides > 4)
488 this.edgeNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); 606 this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
489 } 607 }
490 608
491 float z = 0.0f; 609 float z = 0.0f;
@@ -504,12 +622,18 @@ namespace PrimMesher
504 622
505 hollowCoords.Add(newVert); 623 hollowCoords.Add(newVert);
506 if (this.calcVertexNormals) 624 if (this.calcVertexNormals)
625 {
626 //Coord hollowNormal = new Coord(angle.X, angle.Y, 0.0f);
627 //hollowNormal *= rot180;
628 //hollowNormals.Add(hollowNormal);
507 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); 629 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
630 }
508 } 631 }
509 } 632 }
510 633
511 int index = 0; 634 int index = 0;
512 int numAngles = angles.angles.Count; 635 int numAngles = angles.angles.Count;
636
513 for (int i = 0; i < numAngles; i++) 637 for (int i = 0; i < numAngles; i++)
514 { 638 {
515 angle = angles.angles[i]; 639 angle = angles.angles[i];
@@ -518,7 +642,7 @@ namespace PrimMesher
518 newVert.Z = z; 642 newVert.Z = z;
519 this.coords.Add(newVert); 643 this.coords.Add(newVert);
520 if (this.calcVertexNormals) 644 if (this.calcVertexNormals)
521 this.edgeNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); 645 this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f));
522 646
523 if (hollow > 0.0f) 647 if (hollow > 0.0f)
524 { 648 {
@@ -529,7 +653,12 @@ namespace PrimMesher
529 newVert.Z = z; 653 newVert.Z = z;
530 hollowCoords.Add(newVert); 654 hollowCoords.Add(newVert);
531 if (this.calcVertexNormals) 655 if (this.calcVertexNormals)
656 {
657 //Coord hollowNormal = new Coord(angle.X, angle.Y, 0.0f);
658 //hollowNormal *= rot180;
659 //hollowNormals.Add(hollowNormal);
532 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); 660 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
661 }
533 } 662 }
534 } 663 }
535 else if (!simpleFace && createFaces && angle.angle > 0.0001f) 664 else if (!simpleFace && createFaces && angle.angle > 0.0001f)
@@ -538,12 +667,7 @@ namespace PrimMesher
538 newFace.v1 = 0; 667 newFace.v1 = 0;
539 newFace.v2 = index; 668 newFace.v2 = index;
540 newFace.v3 = index + 1; 669 newFace.v3 = index + 1;
541 //if (this.calcVertexNormals) 670
542 //{
543 // newFace.n1 = newFace.v1;
544 // newFace.n2 = newFace.v2;
545 // newFace.n3 = newFace.v3;
546 //}
547 this.faces.Add(newFace); 671 this.faces.Add(newFace);
548 } 672 }
549 index += 1; 673 index += 1;
@@ -570,23 +694,11 @@ namespace PrimMesher
570 newFace.v1 = coordIndex; 694 newFace.v1 = coordIndex;
571 newFace.v2 = coordIndex + 1; 695 newFace.v2 = coordIndex + 1;
572 newFace.v3 = numTotalVerts - coordIndex - 1; 696 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 //}
579 this.faces.Add(newFace); 697 this.faces.Add(newFace);
580 698
581 newFace.v1 = coordIndex + 1; 699 newFace.v1 = coordIndex + 1;
582 newFace.v2 = numTotalVerts - coordIndex - 2; 700 newFace.v2 = numTotalVerts - coordIndex - 2;
583 newFace.v3 = numTotalVerts - coordIndex - 1; 701 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 //}
590 this.faces.Add(newFace); 702 this.faces.Add(newFace);
591 } 703 }
592 } 704 }
@@ -605,12 +717,6 @@ namespace PrimMesher
605 newFace.v1 = numTotalVerts - i - 1; 717 newFace.v1 = numTotalVerts - i - 1;
606 newFace.v2 = j; 718 newFace.v2 = j;
607 newFace.v3 = j + 1; 719 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 //}
614 720
615 this.faces.Add(newFace); 721 this.faces.Add(newFace);
616 j += 1; 722 j += 1;
@@ -619,12 +725,6 @@ namespace PrimMesher
619 newFace.v1 = j; 725 newFace.v1 = j;
620 newFace.v2 = numTotalVerts - i - 2; 726 newFace.v2 = numTotalVerts - i - 2;
621 newFace.v3 = numTotalVerts - i - 1; 727 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 //}
628 728
629 this.faces.Add(newFace); 729 this.faces.Add(newFace);
630 } 730 }
@@ -642,12 +742,6 @@ namespace PrimMesher
642 newFace.v1 = i; 742 newFace.v1 = i;
643 newFace.v2 = numTotalVerts - j - 2; 743 newFace.v2 = numTotalVerts - j - 2;
644 newFace.v3 = numTotalVerts - j - 1; 744 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 //}
651 745
652 this.faces.Add(newFace); 746 this.faces.Add(newFace);
653 j += 1; 747 j += 1;
@@ -656,12 +750,6 @@ namespace PrimMesher
656 newFace.v1 = numTotalVerts - j - 1; 750 newFace.v1 = numTotalVerts - j - 1;
657 newFace.v2 = i; 751 newFace.v2 = i;
658 newFace.v3 = i + 1; 752 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 //}
665 753
666 this.faces.Add(newFace); 754 this.faces.Add(newFace);
667 } 755 }
@@ -671,10 +759,7 @@ namespace PrimMesher
671 759
672 this.coords.AddRange(hollowCoords); 760 this.coords.AddRange(hollowCoords);
673 if (this.calcVertexNormals) 761 if (this.calcVertexNormals)
674 this.edgeNormals.AddRange(hollowNormals); 762 this.vertexNormals.AddRange(hollowNormals);
675
676 hollowCoords = null;
677 hollowNormals = null;
678 } 763 }
679 764
680 if (simpleFace && createFaces) 765 if (simpleFace && createFaces)
@@ -688,6 +773,33 @@ namespace PrimMesher
688 } 773 }
689 } 774 }
690 775
776 if (calcVertexNormals && hasProfileCut)
777 {
778 if (hasHollow)
779 {
780 this.cutNormal1.X = -this.vertexNormals[0].Y - this.vertexNormals[this.vertexNormals.Count - 1].Y;
781 this.cutNormal1.Y = this.vertexNormals[0].X - this.vertexNormals[this.vertexNormals.Count - 1].X;
782
783 int lastOuterVertIndex = this.numOuterVerts - 1;
784 this.cutNormal2.X = -this.vertexNormals[lastOuterVertIndex].Y - this.vertexNormals[lastOuterVertIndex + 1].Y;
785 this.cutNormal2.Y = this.vertexNormals[lastOuterVertIndex].X - this.vertexNormals[lastOuterVertIndex + 1].X;
786 }
787 else
788 {
789 this.cutNormal1.X = this.vertexNormals[1].Y;
790 this.cutNormal1.Y = -this.vertexNormals[1].X;
791
792 this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 1].Y;
793 this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 1].X;
794
795 }
796 this.cutNormal1.Normalize();
797 this.cutNormal2.Normalize();
798 }
799
800 hollowCoords = null;
801 hollowNormals = null;
802
691 } 803 }
692 804
693 public Profile Clone() 805 public Profile Clone()
@@ -702,7 +814,15 @@ namespace PrimMesher
702 clone.coords.AddRange(this.coords); 814 clone.coords.AddRange(this.coords);
703 if (needFaces) 815 if (needFaces)
704 clone.faces.AddRange(this.faces); 816 clone.faces.AddRange(this.faces);
705 clone.edgeNormals.AddRange(this.edgeNormals); 817 if ((clone.calcVertexNormals = this.calcVertexNormals) == true)
818 {
819 clone.vertexNormals.AddRange(this.vertexNormals);
820 clone.faceNormal = this.faceNormal;
821 clone.cutNormal1 = this.cutNormal1;
822 clone.cutNormal2 = this.cutNormal2;
823 }
824 clone.numOuterVerts = this.numOuterVerts;
825 clone.numHollowVerts = this.numHollowVerts;
706 826
707 return clone; 827 return clone;
708 } 828 }
@@ -745,16 +865,23 @@ namespace PrimMesher
745 this.coords[i] = c; 865 this.coords[i] = c;
746 } 866 }
747 867
748 int numNormals = this.edgeNormals.Count; 868 if (this.calcVertexNormals)
749 for (i = 0; i < numNormals; i++)
750 { 869 {
751 c = this.edgeNormals[i]; 870 int numNormals = this.vertexNormals.Count;
752 Coord n = new Coord(c.X, c.Y, c.Z) * q; 871 for (i = 0; i < numNormals; i++)
872 {
873 c = this.vertexNormals[i];
874 Coord n = new Coord(c.X, c.Y, c.Z) * q;
753 875
754 c.X = n.X; 876 c.X = n.X;
755 c.Y = n.Y; 877 c.Y = n.Y;
756 c.Z = n.Z; 878 c.Z = n.Z;
757 this.edgeNormals[i] = c; 879 this.vertexNormals[i] = c;
880 }
881
882 this.faceNormal *= q;
883 this.cutNormal1 *= q;
884 this.cutNormal2 *= q;
758 } 885 }
759 } 886 }
760 887
@@ -794,14 +921,18 @@ namespace PrimMesher
794 921
795 if (this.calcVertexNormals) 922 if (this.calcVertexNormals)
796 { 923 {
797 int normalCount = this.edgeNormals.Count; 924 int normalCount = this.vertexNormals.Count;
798 if (normalCount > 0) 925 if (normalCount > 0)
799 { 926 {
800 Coord n = this.edgeNormals[normalCount - 1]; 927 Coord n = this.vertexNormals[normalCount - 1];
801 n.Z = -n.Z; 928 n.Z = -n.Z;
802 this.edgeNormals[normalCount - 1] = n; 929 this.vertexNormals[normalCount - 1] = n;
803 } 930 }
804 } 931 }
932
933 this.faceNormal.X = -this.faceNormal.X;
934 this.faceNormal.Y = -this.faceNormal.Y;
935 this.faceNormal.Z = -this.faceNormal.Z;
805 } 936 }
806 937
807 public void AddValue2FaceVertexIndices(int num) 938 public void AddValue2FaceVertexIndices(int num)
@@ -866,11 +997,13 @@ namespace PrimMesher
866 public List<Coord> normals; 997 public List<Coord> normals;
867 public List<Face> faces; 998 public List<Face> faces;
868 999
869 public int sides = 4; 1000 public List<ViewerFace> viewerFaces;
870 public int hollowSides = 4; 1001
871 public float profileStart = 0.0f; 1002 private int sides = 4;
872 public float profileEnd = 1.0f; 1003 private int hollowSides = 4;
873 public float hollow = 0.0f; 1004 private float profileStart = 0.0f;
1005 private float profileEnd = 1.0f;
1006 private float hollow = 0.0f;
874 public int twistBegin = 0; 1007 public int twistBegin = 0;
875 public int twistEnd = 0; 1008 public int twistEnd = 0;
876 public float topShearX = 0.0f; 1009 public float topShearX = 0.0f;
@@ -888,10 +1021,10 @@ namespace PrimMesher
888 public float revolutions = 1.0f; 1021 public float revolutions = 1.0f;
889 public int stepsPerRevolution = 24; 1022 public int stepsPerRevolution = 24;
890 1023
1024 private bool hasProfileCut = false;
891 public bool calcVertexNormals = false; 1025 public bool calcVertexNormals = false;
892 private bool normalsProcessed = false; 1026 private bool normalsProcessed = false;
893 1027 public bool viewerMode = false;
894 //private List<Coord> edgeNormals;
895 1028
896 public string ParamsToDisplayString() 1029 public string ParamsToDisplayString()
897 { 1030 {
@@ -949,6 +1082,8 @@ namespace PrimMesher
949 this.hollow = 1.0f; 1082 this.hollow = 1.0f;
950 if (hollow < 0.0f) 1083 if (hollow < 0.0f)
951 this.hollow = 0.0f; 1084 this.hollow = 0.0f;
1085
1086 this.hasProfileCut = (this.profileStart > 0.0f || this.profileEnd < 1.0f);
952 } 1087 }
953 1088
954 public void ExtrudeLinear() 1089 public void ExtrudeLinear()
@@ -956,6 +1091,12 @@ namespace PrimMesher
956 this.coords = new List<Coord>(); 1091 this.coords = new List<Coord>();
957 this.faces = new List<Face>(); 1092 this.faces = new List<Face>();
958 1093
1094 if (this.viewerMode)
1095 {
1096 this.viewerFaces = new List<ViewerFace>();
1097 this.calcVertexNormals = true;
1098 }
1099
959 if (this.calcVertexNormals) 1100 if (this.calcVertexNormals)
960 this.normals = new List<Coord>(); 1101 this.normals = new List<Coord>();
961 1102
@@ -964,18 +1105,15 @@ namespace PrimMesher
964 1105
965 float length = this.pathCutEnd - this.pathCutBegin; 1106 float length = this.pathCutEnd - this.pathCutBegin;
966 normalsProcessed = false; 1107 normalsProcessed = false;
967 //if (this.calcVertexNormals)
968 // this.edgeNormals = new List<Coord>();
969 1108
970#if VIEWER 1109 if (this.viewerMode && this.sides == 3)
971 if (this.sides == 3)
972 { 1110 {
973 // prisms don't taper well so add some vertical resolution 1111 // prisms don't taper well so add some vertical resolution
974 // other prims may benefit from this but just do prisms for now 1112 // other prims may benefit from this but just do prisms for now
975 if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01) 1113 if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01)
976 steps = (int)(steps * 4.5 * length); 1114 steps = (int)(steps * 4.5 * length);
977 } 1115 }
978#endif 1116
979 1117
980 float twistBegin = this.twistBegin / 360.0f * twoPi; 1118 float twistBegin = this.twistBegin / 360.0f * twoPi;
981 float twistEnd = this.twistEnd / 360.0f * twoPi; 1119 float twistEnd = this.twistEnd / 360.0f * twoPi;
@@ -1021,15 +1159,14 @@ namespace PrimMesher
1021 else if (this.sides == 24 && this.hollowSides == 4) 1159 else if (this.sides == 24 && this.hollowSides == 4)
1022 hollow *= 1.414f; 1160 hollow *= 1.414f;
1023 1161
1024 bool hasProfileCut = false;
1025 if (profileStart > 0.0f || profileEnd < 1.0f)
1026 hasProfileCut = true;
1027
1028 Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals); 1162 Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals);
1029 1163
1030 if (initialProfileRot != 0.0f) 1164 if (initialProfileRot != 0.0f)
1031 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); 1165 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
1032 1166
1167 Coord lastCutNormal1 = new Coord();
1168 Coord lastCutNormal2 = new Coord();
1169
1033 bool done = false; 1170 bool done = false;
1034 while (!done) 1171 while (!done)
1035 { 1172 {
@@ -1057,8 +1194,31 @@ namespace PrimMesher
1057 newLayer.AddPos(xOffset, yOffset, zOffset); 1194 newLayer.AddPos(xOffset, yOffset, zOffset);
1058 1195
1059 if (step == 0) 1196 if (step == 0)
1197 {
1060 newLayer.FlipNormals(); 1198 newLayer.FlipNormals();
1061 1199
1200 // add the top faces to the viewerFaces list here
1201 if (this.viewerMode)
1202 {
1203 Coord faceNormal = newLayer.faceNormal;
1204 ViewerFace newViewerFace = new ViewerFace();
1205 newViewerFace.primFaceNumber = 0;
1206 foreach (Face face in newLayer.faces)
1207 {
1208 newViewerFace.v1 = newLayer.coords[face.v1];
1209 newViewerFace.v2 = newLayer.coords[face.v2];
1210 newViewerFace.v3 = newLayer.coords[face.v3];
1211
1212 newViewerFace.n1 = faceNormal;
1213 newViewerFace.n2 = faceNormal;
1214 newViewerFace.n3 = faceNormal;
1215
1216 this.viewerFaces.Add(newViewerFace);
1217 }
1218
1219 }
1220 }
1221
1062 // append this layer 1222 // append this layer
1063 1223
1064 int coordsLen = this.coords.Count; 1224 int coordsLen = this.coords.Count;
@@ -1069,7 +1229,7 @@ namespace PrimMesher
1069 if (this.calcVertexNormals) 1229 if (this.calcVertexNormals)
1070 { 1230 {
1071 newLayer.AddValue2FaceNormalIndices(this.normals.Count); 1231 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
1072 this.normals.AddRange(newLayer.edgeNormals); 1232 this.normals.AddRange(newLayer.vertexNormals);
1073 } 1233 }
1074 1234
1075 if (percentOfPath <= this.pathCutBegin || percentOfPath >= this.pathCutEnd) 1235 if (percentOfPath <= this.pathCutBegin || percentOfPath >= this.pathCutEnd)
@@ -1085,61 +1245,112 @@ namespace PrimMesher
1085 int startVert = coordsLen + 1; 1245 int startVert = coordsLen + 1;
1086 int endVert = this.coords.Count - 1; 1246 int endVert = this.coords.Count - 1;
1087 1247
1088 if (sides < 5 || hasProfileCut || hollow > 0.0f) 1248 if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
1089 startVert--; 1249 startVert--;
1090 1250
1091 for (int i = startVert; i < endVert; i++) 1251 for (int i = startVert; i < endVert; i++)
1092 { 1252 {
1253 int whichVert = i - startVert;
1254
1093 newFace.v1 = i; 1255 newFace.v1 = i;
1094 newFace.v2 = i - numVerts; 1256 newFace.v2 = i - numVerts;
1095 newFace.v3 = i - numVerts + 1; 1257 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 }
1102 this.faces.Add(newFace); 1258 this.faces.Add(newFace);
1103 1259
1104 newFace.v2 = i - numVerts + 1; 1260 newFace.v2 = i - numVerts + 1;
1105 newFace.v3 = i + 1; 1261 newFace.v3 = i + 1;
1106 if (this.calcVertexNormals) 1262 this.faces.Add(newFace);
1263
1264 if (this.viewerMode)
1107 { 1265 {
1108 newFace.n2 = newFace.v2; 1266 // add the side faces to the list of viewerFaces here
1109 newFace.n3 = newFace.v3; 1267 ViewerFace newViewerFace1 = new ViewerFace();
1268 ViewerFace newViewerFace2 = new ViewerFace();
1269
1270 newViewerFace1.v1 = this.coords[i];
1271 newViewerFace1.v2 = this.coords[i - numVerts];
1272 newViewerFace1.v3 = this.coords[i - numVerts + 1];
1273
1274 newViewerFace2.v1 = this.coords[i];
1275 newViewerFace2.v2 = this.coords[i - numVerts + 1];
1276 newViewerFace2.v3 = this.coords[i + 1];
1277
1278 if (whichVert == newLayer.numOuterVerts - 1 && hasProfileCut)
1279 { // start profile cut faces
1280
1281 newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal1;
1282 newViewerFace1.n3 = newLayer.cutNormal1;
1283
1284 newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal1;
1285 newViewerFace2.n2 = lastCutNormal1;
1286 }
1287
1288 else // periphery faces
1289 {
1290 if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts))
1291 {
1292 newViewerFace1.CalcSurfaceNormal();
1293 newViewerFace2.CalcSurfaceNormal();
1294 }
1295 else
1296 {
1297 newViewerFace1.n1 = this.normals[i];
1298 newViewerFace1.n2 = this.normals[i - numVerts];
1299 newViewerFace1.n3 = this.normals[i - numVerts + 1];
1300
1301 newViewerFace2.n1 = this.normals[i];
1302 newViewerFace2.n2 = this.normals[i - numVerts + 1];
1303 newViewerFace2.n3 = this.normals[i + 1];
1304 }
1305 }
1306
1307 this.viewerFaces.Add(newViewerFace1);
1308 this.viewerFaces.Add(newViewerFace2);
1309
1110 } 1310 }
1111 this.faces.Add(newFace);
1112 } 1311 }
1113 1312
1114 if (hasProfileCut) 1313 if (this.hasProfileCut)
1115 { 1314 { // add the end cut face to the list of viewerFaces here
1315 // the first cut face was filled in the above loop
1116 newFace.v1 = coordsLen - 1; 1316 newFace.v1 = coordsLen - 1;
1117 newFace.v2 = coordsLen - numVerts; 1317 newFace.v2 = coordsLen - numVerts;
1118 newFace.v3 = coordsLen; 1318 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 }
1126 this.faces.Add(newFace); 1319 this.faces.Add(newFace);
1127 1320
1128 newFace.v1 = coordsLen + numVerts - 1; 1321 newFace.v1 = coordsLen + numVerts - 1;
1129 newFace.v2 = coordsLen - 1; 1322 newFace.v2 = coordsLen - 1;
1130 newFace.v3 = coordsLen; 1323 newFace.v3 = coordsLen;
1131 if (this.calcVertexNormals) 1324 this.faces.Add(newFace);
1325
1326 if (this.viewerMode)
1132 { 1327 {
1133 Coord n1 = SurfaceNormal(newFace); 1328 ViewerFace newViewerFace = new ViewerFace();
1134 this.normals.Add(n1); 1329 newViewerFace.v1 = this.coords[coordsLen - 1]; // last vert in prior layer
1330 newViewerFace.v2 = this.coords[coordsLen - numVerts]; // first vert in prior layer
1331 newViewerFace.v3 = this.coords[coordsLen]; // first vert in new layer
1332
1333 newViewerFace.n2 = newViewerFace.n1 = lastCutNormal2;
1334 newViewerFace.n3 = newLayer.cutNormal2;
1135 1335
1136 newFace.n1 = newFace.n2 = newFace.n3 = this.normals.Count - 1; 1336 this.viewerFaces.Add(newViewerFace);
1337
1338 newViewerFace.v1 = this.coords[coordsLen + numVerts - 1]; // last vert in new layer
1339 newViewerFace.v2 = this.coords[coordsLen - 1]; // last vert in prior layer
1340 newViewerFace.v3 = this.coords[coordsLen]; // first vert in new layer
1341
1342 newViewerFace.n3 = newViewerFace.n1 = newLayer.cutNormal2;
1343 newViewerFace.n2 = lastCutNormal2;
1344
1345 this.viewerFaces.Add(newViewerFace);
1137 } 1346 }
1138 this.faces.Add(newFace);
1139 } 1347 }
1140 1348
1141 } 1349 }
1142 1350
1351 lastCutNormal1 = newLayer.cutNormal1;
1352 lastCutNormal2 = newLayer.cutNormal2;
1353
1143 // calc the step for the next iteration of the loop 1354 // calc the step for the next iteration of the loop
1144 1355
1145 if (step < steps) 1356 if (step < steps)
@@ -1153,10 +1364,27 @@ namespace PrimMesher
1153 done = true; 1364 done = true;
1154 } 1365 }
1155 else done = true; 1366 else done = true;
1156 }
1157 1367
1158 //if (calcVertexNormals && sides < 5 && twistBegin == 0.0f && twistEnd == 0.0f) 1368 if (done && viewerMode)
1159 // this.CalcNormals(); 1369 {
1370 // add the bottom faces to the viewerFaces list here
1371 Coord faceNormal = newLayer.faceNormal;
1372 ViewerFace newViewerFace = new ViewerFace();
1373 newViewerFace.primFaceNumber = 0;
1374 foreach (Face face in newLayer.faces)
1375 {
1376 newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
1377 newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
1378 newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
1379
1380 newViewerFace.n1 = faceNormal;
1381 newViewerFace.n2 = faceNormal;
1382 newViewerFace.n3 = faceNormal;
1383
1384 this.viewerFaces.Add(newViewerFace);
1385 }
1386 }
1387 }
1160 } 1388 }
1161 1389
1162 public void ExtrudeCircular() 1390 public void ExtrudeCircular()
@@ -1164,6 +1392,12 @@ namespace PrimMesher
1164 this.coords = new List<Coord>(); 1392 this.coords = new List<Coord>();
1165 this.faces = new List<Face>(); 1393 this.faces = new List<Face>();
1166 1394
1395 if (this.viewerMode)
1396 {
1397 this.viewerFaces = new List<ViewerFace>();
1398 this.calcVertexNormals = true;
1399 }
1400
1167 if (this.calcVertexNormals) 1401 if (this.calcVertexNormals)
1168 this.normals = new List<Coord>(); 1402 this.normals = new List<Coord>();
1169 1403
@@ -1242,10 +1476,6 @@ namespace PrimMesher
1242 } 1476 }
1243 } 1477 }
1244 1478
1245 bool hasProfileCut = false;
1246 if (profileStart > 0.0f || profileEnd < 1.0f)
1247 hasProfileCut = true;
1248
1249 bool needEndFaces = false; 1479 bool needEndFaces = false;
1250 if (this.pathCutBegin != 0.0 || this.pathCutEnd != 1.0) 1480 if (this.pathCutBegin != 0.0 || this.pathCutEnd != 1.0)
1251 needEndFaces = true; 1481 needEndFaces = true;
@@ -1327,7 +1557,7 @@ namespace PrimMesher
1327 if (this.calcVertexNormals) 1557 if (this.calcVertexNormals)
1328 { 1558 {
1329 newLayer.AddValue2FaceNormalIndices(this.normals.Count); 1559 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
1330 this.normals.AddRange(newLayer.edgeNormals); 1560 this.normals.AddRange(newLayer.vertexNormals);
1331 } 1561 }
1332 1562
1333 if (isEndLayer) 1563 if (isEndLayer)
@@ -1342,7 +1572,7 @@ namespace PrimMesher
1342 int startVert = coordsLen + 1; 1572 int startVert = coordsLen + 1;
1343 int endVert = this.coords.Count - 1; 1573 int endVert = this.coords.Count - 1;
1344 1574
1345 if (sides < 5 || hasProfileCut || hollow > 0.0f) 1575 if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
1346 startVert--; 1576 startVert--;
1347 1577
1348 for (int i = startVert; i < endVert; i++) 1578 for (int i = startVert; i < endVert; i++)
@@ -1356,9 +1586,33 @@ namespace PrimMesher
1356 newFace.v2 = i - numVerts + 1; 1586 newFace.v2 = i - numVerts + 1;
1357 newFace.v3 = i + 1; 1587 newFace.v3 = i + 1;
1358 this.faces.Add(newFace); 1588 this.faces.Add(newFace);
1589
1590 if (this.viewerMode)
1591 {
1592 // add the side faces to the list of viewerFaces here
1593 ViewerFace newViewerFace = new ViewerFace();
1594 newViewerFace.v1 = this.coords[i];
1595 newViewerFace.v2 = this.coords[i - numVerts];
1596 newViewerFace.v3 = this.coords[i - numVerts + 1];
1597
1598 newViewerFace.n1 = this.normals[i];
1599 newViewerFace.n2 = this.normals[i - numVerts];
1600 newViewerFace.n3 = this.normals[i - numVerts + 1];
1601
1602 this.viewerFaces.Add(newViewerFace);
1603
1604 newViewerFace.v2 = this.coords[i - numVerts + 1];
1605 newViewerFace.v3 = this.coords[i + 1];
1606
1607 newViewerFace.n2 = this.normals[i - numVerts + 1];
1608 newViewerFace.n3 = this.normals[i + 1];
1609
1610 this.viewerFaces.Add(newViewerFace);
1611
1612 }
1359 } 1613 }
1360 1614
1361 if (hasProfileCut) 1615 if (this.hasProfileCut)
1362 { 1616 {
1363 newFace.v1 = coordsLen - 1; 1617 newFace.v1 = coordsLen - 1;
1364 newFace.v2 = coordsLen - numVerts; 1618 newFace.v2 = coordsLen - numVerts;
@@ -1405,6 +1659,7 @@ namespace PrimMesher
1405 1659
1406 public Coord SurfaceNormal(int faceIndex) 1660 public Coord SurfaceNormal(int faceIndex)
1407 { 1661 {
1662 int numFaces = faces.Count;
1408 if (faceIndex < 0 || faceIndex >= faces.Count) 1663 if (faceIndex < 0 || faceIndex >= faces.Count)
1409 throw new Exception("faceIndex out of range"); 1664 throw new Exception("faceIndex out of range");
1410 1665