aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/PrimMesher.cs
diff options
context:
space:
mode:
authorDahlia Trimble2008-11-05 10:22:41 +0000
committerDahlia Trimble2008-11-05 10:22:41 +0000
commit5fffc04ae67381cebc1f20f062873ee889151ac6 (patch)
tree439909d1db7f35cc0de81dbcde6490b540dffa43 /OpenSim/Region/Physics/Meshing/PrimMesher.cs
parentMantis#2557. Thank you kindly, Diva for a patch that: (diff)
downloadopensim-SC-5fffc04ae67381cebc1f20f062873ee889151ac6.zip
opensim-SC-5fffc04ae67381cebc1f20f062873ee889151ac6.tar.gz
opensim-SC-5fffc04ae67381cebc1f20f062873ee889151ac6.tar.bz2
opensim-SC-5fffc04ae67381cebc1f20f062873ee889151ac6.tar.xz
Add more vertex normals and UV coordinates. Sync with primmesher.dll forge project.
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/PrimMesher.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/PrimMesher.cs172
1 files changed, 123 insertions, 49 deletions
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
index 741010d..72da5cf 100644
--- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs
+++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
@@ -121,6 +121,15 @@ namespace PrimMesher
121 return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z); 121 return (float)Math.Sqrt(this.X * this.X + this.Y * this.Y + this.Z * this.Z);
122 } 122 }
123 123
124 public Coord Invert()
125 {
126 this.X = -this.X;
127 this.Y = -this.Y;
128 this.Z = -this.Z;
129
130 return this;
131 }
132
124 public Coord Normalize() 133 public Coord Normalize()
125 { 134 {
126 const float MAG_THRESHOLD = 0.0000001f; 135 const float MAG_THRESHOLD = 0.0000001f;
@@ -369,6 +378,14 @@ namespace PrimMesher
369 new Angle(1.0f, 1.0f, 0.0f) 378 new Angle(1.0f, 1.0f, 0.0f)
370 }; 379 };
371 380
381 private Coord[] normals3 =
382 {
383 new Coord(0.25f, 0.4330127019f, 0.0f).Normalize(),
384 new Coord(-0.5f, 0.0f, 0.0f).Normalize(),
385 new Coord(0.25f, -0.4330127019f, 0.0f).Normalize(),
386 new Coord(0.25f, 0.4330127019f, 0.0f).Normalize()
387 };
388
372 private Angle[] angles4 = 389 private Angle[] angles4 =
373 { 390 {
374 new Angle(0.0f, 1.0f, 0.0f), 391 new Angle(0.0f, 1.0f, 0.0f),
@@ -378,6 +395,15 @@ namespace PrimMesher
378 new Angle(1.0f, 1.0f, 0.0f) 395 new Angle(1.0f, 1.0f, 0.0f)
379 }; 396 };
380 397
398 private Coord[] normals4 =
399 {
400 new Coord(0.5f, 0.5f, 0.0f).Normalize(),
401 new Coord(-0.5f, 0.5f, 0.0f).Normalize(),
402 new Coord(-0.5f, -0.5f, 0.0f).Normalize(),
403 new Coord(0.5f, -0.5f, 0.0f).Normalize(),
404 new Coord(0.5f, 0.5f, 0.0f).Normalize()
405 };
406
381 private Angle[] angles24 = 407 private Angle[] angles24 =
382 { 408 {
383 new Angle(0.0f, 1.0f, 0.0f), 409 new Angle(0.0f, 1.0f, 0.0f),
@@ -427,10 +453,13 @@ namespace PrimMesher
427 } 453 }
428 454
429 internal List<Angle> angles; 455 internal List<Angle> angles;
456 internal List<Coord> normals;
430 457
431 internal void makeAngles(int sides, float startAngle, float stopAngle) 458 internal void makeAngles(int sides, float startAngle, float stopAngle)
432 { 459 {
433 angles = new List<Angle>(); 460 angles = new List<Angle>();
461 normals = new List<Coord>();
462
434 double twoPi = System.Math.PI * 2.0; 463 double twoPi = System.Math.PI * 2.0;
435 float twoPiInv = 1.0f / (float)twoPi; 464 float twoPiInv = 1.0f / (float)twoPi;
436 465
@@ -459,7 +488,13 @@ namespace PrimMesher
459 endAngleIndex++; 488 endAngleIndex++;
460 489
461 for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++) 490 for (int angleIndex = startAngleIndex; angleIndex < endAngleIndex + 1; angleIndex++)
491 {
462 angles.Add(sourceAngles[angleIndex]); 492 angles.Add(sourceAngles[angleIndex]);
493 if (sides == 3)
494 normals.Add(normals3[angleIndex]);
495 else if (sides == 4)
496 normals.Add(normals4[angleIndex]);
497 }
463 498
464 if (startAngle > 0.0f) 499 if (startAngle > 0.0f)
465 angles[0] = interpolatePoints(startAngle, angles[0], angles[1]); 500 angles[0] = interpolatePoints(startAngle, angles[0], angles[1]);
@@ -639,8 +674,12 @@ namespace PrimMesher
639 hollowCoords.Add(newVert); 674 hollowCoords.Add(newVert);
640 if (this.calcVertexNormals) 675 if (this.calcVertexNormals)
641 { 676 {
642 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); 677 if (sides < 5)
643 hollowUs.Add(angle.angle); 678 hollowNormals.Add(hollowAngles.normals[i].Invert());
679 else
680 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
681
682 hollowUs.Add(angle.angle * hollow);
644 } 683 }
645 } 684 }
646 } 685 }
@@ -650,6 +689,7 @@ namespace PrimMesher
650 689
651 for (int i = 0; i < numAngles; i++) 690 for (int i = 0; i < numAngles; i++)
652 { 691 {
692 int iNext = i == numAngles ? i + 1 : 0;
653 angle = angles.angles[i]; 693 angle = angles.angles[i];
654 newVert.X = angle.X * xScale; 694 newVert.X = angle.X * xScale;
655 newVert.Y = angle.Y * yScale; 695 newVert.Y = angle.Y * yScale;
@@ -657,14 +697,18 @@ namespace PrimMesher
657 this.coords.Add(newVert); 697 this.coords.Add(newVert);
658 if (this.calcVertexNormals) 698 if (this.calcVertexNormals)
659 { 699 {
660 this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f)); 700
661 if (sides < 5) 701 if (sides < 5)
662 { 702 {
703 this.vertexNormals.Add(angles.normals[i]);
663 float u = angle.angle; 704 float u = angle.angle;
664 this.us.Add(u); 705 this.us.Add(u);
665 } 706 }
666 else 707 else
708 {
709 this.vertexNormals.Add(new Coord(angle.X, angle.Y, 0.0f));
667 this.us.Add(angle.angle); 710 this.us.Add(angle.angle);
711 }
668 } 712 }
669 713
670 if (hollow > 0.0f) 714 if (hollow > 0.0f)
@@ -677,8 +721,15 @@ namespace PrimMesher
677 hollowCoords.Add(newVert); 721 hollowCoords.Add(newVert);
678 if (this.calcVertexNormals) 722 if (this.calcVertexNormals)
679 { 723 {
680 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f)); 724 if (sides < 5)
681 hollowUs.Add(angle.angle); 725 {
726 hollowNormals.Add(angles.normals[i].Invert());
727 }
728
729 else
730 hollowNormals.Add(new Coord(-angle.X, -angle.Y, 0.0f));
731
732 hollowUs.Add(angle.angle * hollow);
682 } 733 }
683 } 734 }
684 } 735 }
@@ -805,20 +856,22 @@ namespace PrimMesher
805 { 856 {
806 if (hasHollow) 857 if (hasHollow)
807 { 858 {
808 this.cutNormal1.X = -this.vertexNormals[0].Y - this.vertexNormals[this.vertexNormals.Count - 1].Y;
809 this.cutNormal1.Y = this.vertexNormals[0].X - this.vertexNormals[this.vertexNormals.Count - 1].X;
810
811 int lastOuterVertIndex = this.numOuterVerts - 1; 859 int lastOuterVertIndex = this.numOuterVerts - 1;
812 this.cutNormal2.X = -this.vertexNormals[lastOuterVertIndex].Y - this.vertexNormals[lastOuterVertIndex + 1].Y; 860
813 this.cutNormal2.Y = this.vertexNormals[lastOuterVertIndex].X - this.vertexNormals[lastOuterVertIndex + 1].X; 861 this.cutNormal1.X = this.coords[0].Y - this.coords[this.coords.Count - 1].Y;
862 this.cutNormal1.Y = -(this.coords[0].X - this.coords[this.coords.Count - 1].X);
863
864 this.cutNormal2.X = this.coords[lastOuterVertIndex + 1].Y - this.coords[lastOuterVertIndex].Y;
865 this.cutNormal2.Y = -(this.coords[lastOuterVertIndex + 1].X - this.coords[lastOuterVertIndex].X);
814 } 866 }
867
815 else 868 else
816 { 869 {
817 this.cutNormal1.X = this.vertexNormals[1].Y; 870 this.cutNormal1.X = this.vertexNormals[1].Y;
818 this.cutNormal1.Y = -this.vertexNormals[1].X; 871 this.cutNormal1.Y = -this.vertexNormals[1].X;
819 872
820 this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 1].Y; 873 this.cutNormal2.X = -this.vertexNormals[this.vertexNormals.Count - 2].Y;
821 this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 1].X; 874 this.cutNormal2.Y = this.vertexNormals[this.vertexNormals.Count - 2].X;
822 875
823 } 876 }
824 this.cutNormal1.Normalize(); 877 this.cutNormal1.Normalize();
@@ -837,7 +890,7 @@ namespace PrimMesher
837 { 890 {
838 this.faceUVs = new List<UVCoord>(); 891 this.faceUVs = new List<UVCoord>();
839 foreach (Coord c in this.coords) 892 foreach (Coord c in this.coords)
840 this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y)); 893 this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y)));
841 } 894 }
842 895
843 public Profile Clone() 896 public Profile Clone()
@@ -963,7 +1016,7 @@ namespace PrimMesher
963 for (i = 0; i < numfaceUVs; i++) 1016 for (i = 0; i < numfaceUVs; i++)
964 { 1017 {
965 UVCoord uv = this.faceUVs[i]; 1018 UVCoord uv = this.faceUVs[i];
966 uv.U = 1.0f - uv.U; 1019 uv.V = 1.0f - uv.V;
967 this.faceUVs[i] = uv; 1020 this.faceUVs[i] = uv;
968 } 1021 }
969 } 1022 }
@@ -1250,8 +1303,7 @@ namespace PrimMesher
1250 if (this.viewerMode) 1303 if (this.viewerMode)
1251 { 1304 {
1252 Coord faceNormal = newLayer.faceNormal; 1305 Coord faceNormal = newLayer.faceNormal;
1253 ViewerFace newViewerFace = new ViewerFace(); 1306 ViewerFace newViewerFace = new ViewerFace(0);
1254 newViewerFace.primFaceNumber = 0;
1255 foreach (Face face in newLayer.faces) 1307 foreach (Face face in newLayer.faces)
1256 { 1308 {
1257 newViewerFace.v1 = newLayer.coords[face.v1]; 1309 newViewerFace.v1 = newLayer.coords[face.v1];
@@ -1325,29 +1377,30 @@ namespace PrimMesher
1325 primFaceNum = 2; 1377 primFaceNum = 2;
1326 ViewerFace newViewerFace1 = new ViewerFace(primFaceNum); 1378 ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
1327 ViewerFace newViewerFace2 = new ViewerFace(primFaceNum); 1379 ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
1380
1328 float u1 = newLayer.us[whichVert]; 1381 float u1 = newLayer.us[whichVert];
1329 float u2 = 1.0f; 1382 float u2 = 1.0f;
1330 if (whichVert < newLayer.us.Count - 1) 1383 if (whichVert < newLayer.us.Count - 1)
1331 u2 = newLayer.us[whichVert + 1]; 1384 u2 = newLayer.us[whichVert + 1];
1332 int whichOuterVert = (hasProfileCut && hasHollow) ? whichVert - 1 : whichVert; 1385
1333 if (sides < 5 && whichOuterVert < sides) 1386 if (whichVert == cut1Vert || whichVert == cut2Vert)
1334 { 1387 {
1388 u1 = 0.0f;
1389 u2 = 1.0f;
1390 }
1391 else if (sides < 5)
1392 { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
1393 // to reflect the entire texture width
1335 u1 *= sides; 1394 u1 *= sides;
1336 u2 *= sides; 1395 u2 *= sides;
1337 u1 -= whichOuterVert; 1396 u2 -= (int)u1;
1338 u2 -= whichOuterVert; 1397 u1 -= (int)u1;
1339 if (u2 < 0.1f) 1398 if (u2 < 0.1f)
1340 u2 = 1.0f; 1399 u2 = 1.0f;
1341 1400
1342 newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1; 1401 newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
1343 } 1402 }
1344 1403
1345 if (whichVert == cut1Vert || whichVert == cut2Vert)
1346 {
1347 u1 = 0.0f;
1348 u2 = 1.0f;
1349 }
1350
1351 newViewerFace1.uv1.U = u1; 1404 newViewerFace1.uv1.U = u1;
1352 newViewerFace1.uv2.U = u1; 1405 newViewerFace1.uv2.U = u1;
1353 newViewerFace1.uv3.U = u2; 1406 newViewerFace1.uv3.U = u2;
@@ -1375,27 +1428,24 @@ namespace PrimMesher
1375 // profile cut faces 1428 // profile cut faces
1376 if (whichVert == cut1Vert) 1429 if (whichVert == cut1Vert)
1377 { 1430 {
1431 newViewerFace1.n1 = newLayer.cutNormal1;
1432 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
1378 1433
1379 newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal1; 1434 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
1380 newViewerFace1.n3 = newLayer.cutNormal1;
1381
1382 newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal1;
1383 newViewerFace2.n2 = lastCutNormal1; 1435 newViewerFace2.n2 = lastCutNormal1;
1384 } 1436 }
1385 else if (whichVert == cut2Vert) 1437 else if (whichVert == cut2Vert)
1386 { 1438 {
1439 newViewerFace1.n1 = newLayer.cutNormal2;
1440 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
1387 1441
1388 newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal2; 1442 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
1389 newViewerFace1.n3 = newLayer.cutNormal2;
1390
1391 newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal2;
1392 newViewerFace2.n2 = lastCutNormal2; 1443 newViewerFace2.n2 = lastCutNormal2;
1393 } 1444 }
1394 1445
1395 else // outer and hollow faces 1446 else // outer and hollow faces
1396 { 1447 {
1397 //if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) 1448 if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts))
1398 if (sides < 5)
1399 { 1449 {
1400 newViewerFace1.CalcSurfaceNormal(); 1450 newViewerFace1.CalcSurfaceNormal();
1401 newViewerFace2.CalcSurfaceNormal(); 1451 newViewerFace2.CalcSurfaceNormal();
@@ -1727,6 +1777,18 @@ namespace PrimMesher
1727 u1 = 0.0f; 1777 u1 = 0.0f;
1728 u2 = 1.0f; 1778 u2 = 1.0f;
1729 } 1779 }
1780 else if (sides < 5)
1781 { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
1782 // to reflect the entire texture width
1783 u1 *= sides;
1784 u2 *= sides;
1785 u2 -= (int)u1;
1786 u1 -= (int)u1;
1787 if (u2 < 0.1f)
1788 u2 = 1.0f;
1789
1790 newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
1791 }
1730 1792
1731 newViewerFace1.uv1.U = u1; 1793 newViewerFace1.uv1.U = u1;
1732 newViewerFace1.uv2.U = u1; 1794 newViewerFace1.uv2.U = u1;
@@ -1752,32 +1814,44 @@ namespace PrimMesher
1752 newViewerFace2.v2 = this.coords[iNext - numVerts]; 1814 newViewerFace2.v2 = this.coords[iNext - numVerts];
1753 newViewerFace2.v3 = this.coords[iNext]; 1815 newViewerFace2.v3 = this.coords[iNext];
1754 1816
1817 // profile cut faces
1755 if (whichVert == cut1Vert) 1818 if (whichVert == cut1Vert)
1756 { 1819 {
1820 newViewerFace1.n1 = newLayer.cutNormal1;
1821 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
1757 1822
1758 newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal1; 1823 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
1759 newViewerFace1.n3 = newLayer.cutNormal1;
1760
1761 newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal1;
1762 newViewerFace2.n2 = lastCutNormal1; 1824 newViewerFace2.n2 = lastCutNormal1;
1763 } 1825 }
1764 else if (whichVert == cut2Vert) 1826 else if (whichVert == cut2Vert)
1765 { 1827 {
1828 newViewerFace1.n1 = newLayer.cutNormal2;
1829 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
1766 1830
1767 newViewerFace1.n2 = newViewerFace1.n1 = lastCutNormal2; 1831 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
1768 newViewerFace1.n3 = newLayer.cutNormal2;
1769
1770 newViewerFace2.n3 = newViewerFace2.n1 = newLayer.cutNormal2;
1771 newViewerFace2.n2 = lastCutNormal2; 1832 newViewerFace2.n2 = lastCutNormal2;
1772 } 1833 }
1773
1774 else // periphery faces 1834 else // periphery faces
1775 { 1835 {
1776 //if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)) 1836 if (sides < 5 && whichVert < newLayer.numOuterVerts)
1777 if (sides < 5)
1778 { 1837 {
1779 newViewerFace1.CalcSurfaceNormal(); 1838 newViewerFace1.n1 = this.normals[i];
1780 newViewerFace2.CalcSurfaceNormal(); 1839 newViewerFace1.n2 = this.normals[i - numVerts];
1840 newViewerFace1.n3 = this.normals[i - numVerts];
1841
1842 newViewerFace2.n1 = this.normals[i];
1843 newViewerFace2.n2 = this.normals[i - numVerts];
1844 newViewerFace2.n3 = this.normals[i];
1845 }
1846 else if (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)
1847 {
1848 newViewerFace1.n1 = this.normals[iNext];
1849 newViewerFace1.n2 = this.normals[iNext - numVerts];
1850 newViewerFace1.n3 = this.normals[iNext - numVerts];
1851
1852 newViewerFace2.n1 = this.normals[iNext];
1853 newViewerFace2.n2 = this.normals[iNext - numVerts];
1854 newViewerFace2.n3 = this.normals[iNext];
1781 } 1855 }
1782 else 1856 else
1783 { 1857 {