aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Physics/Meshing/HelperTypes.cs77
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs151
2 files changed, 168 insertions, 60 deletions
diff --git a/OpenSim/Region/Physics/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
index 6c4a163..7b17a3f 100644
--- a/OpenSim/Region/Physics/Meshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
@@ -39,6 +39,83 @@ public class Vertex : PhysicsVector, IComparable<Vertex>
39 { 39 {
40 } 40 }
41 41
42 public float length()
43 {
44 return (float)Math.Sqrt(X * X + Y * Y + Z * Z);
45 }
46
47 public Vertex normalize()
48 {
49 float tlength = length();
50 if (tlength != 0)
51 {
52 return new Vertex(X / tlength, Y / tlength, Z / tlength);
53 }
54 else
55 {
56 return new Vertex(0, 0, 0);
57 }
58 }
59
60 public Vertex cross(Vertex v)
61 {
62 return new Vertex(Y * v.Z - Z * v.Y, Z * v.X - X * v.Z, X * v.Y - Y * v.X);
63 }
64
65 public static Vertex operator +(Vertex v1, Vertex v2)
66 {
67 return new Vertex(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
68 }
69
70 public static Vertex operator -(Vertex v1, Vertex v2)
71 {
72 return new Vertex(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
73 }
74
75 public static Vertex operator *(Vertex v1, Vertex v2)
76 {
77 return new Vertex(v1.X * v2.X, v1.Y * v2.Y, v1.Z * v2.Z);
78 }
79
80 public static Vertex operator +(Vertex v1, float am)
81 {
82 v1.X += am;
83 v1.Y += am;
84 v1.Z += am;
85 return v1;
86 }
87 public static Vertex operator -(Vertex v1, float am)
88 {
89 v1.X -= am;
90 v1.Y -= am;
91 v1.Z -= am;
92 return v1;
93 }
94 public static Vertex operator *(Vertex v1, float am)
95 {
96 v1.X *= am;
97 v1.Y *= am;
98 v1.Z *= am;
99 return v1;
100 }
101 public static Vertex operator /(Vertex v1, float am)
102 {
103 if (am == 0f)
104 {
105 return new Vertex(0f,0f,0f);
106 }
107 v1.X /= am;
108 v1.Y /= am;
109 v1.Z /= am;
110 return v1;
111 }
112
113
114 public float dot(Vertex v)
115 {
116 return X * v.X + Y * v.Y + Z * v.Z;
117 }
118
42 public Vertex(PhysicsVector v) 119 public Vertex(PhysicsVector v)
43 : base(v.X, v.Y, v.Z) 120 : base(v.X, v.Y, v.Z)
44 { 121 {
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index d668aa3..80f5bd1 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -989,8 +989,17 @@ namespace OpenSim.Region.Physics.Meshing
989 return result; 989 return result;
990 } 990 }
991 private static Mesh CreateSphereMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) 991 private static Mesh CreateSphereMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
992 // Builds the z (+ and -) surfaces of a box shaped prim
993 { 992 {
993 // Builds an icosahedral geodesic sphere
994 // based on an article by Paul Bourke
995 // http://local.wasp.uwa.edu.au/~pbourke/
996 // articles:
997 // http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonmesh/
998 // and
999 // http://local.wasp.uwa.edu.au/~pbourke/geometry/polyhedra/index.html
1000
1001 // Still have more to do here.
1002
994 UInt16 hollowFactor = primShape.ProfileHollow; 1003 UInt16 hollowFactor = primShape.ProfileHollow;
995 UInt16 profileBegin = primShape.ProfileBegin; 1004 UInt16 profileBegin = primShape.ProfileBegin;
996 UInt16 profileEnd = primShape.ProfileEnd; 1005 UInt16 profileEnd = primShape.ProfileEnd;
@@ -999,13 +1008,17 @@ namespace OpenSim.Region.Physics.Meshing
999 UInt16 pathShearX = primShape.PathShearX; 1008 UInt16 pathShearX = primShape.PathShearX;
1000 UInt16 pathShearY = primShape.PathShearY; 1009 UInt16 pathShearY = primShape.PathShearY;
1001 Mesh m = new Mesh(); 1010 Mesh m = new Mesh();
1002 float radius = 0.6f; 1011
1012 float LOD = 0.2f;
1013 float diameter = 0.5f;// Our object will result in -0.5 to 0.5
1003 float sq5 = (float) Math.Sqrt(5.0); 1014 float sq5 = (float) Math.Sqrt(5.0);
1004 float phi = (1 + sq5) * 0.5f; 1015 float phi = (1 + sq5) * 0.5f;
1005 float rat = (float) Math.Sqrt(10f + (2f * sq5)) / (4f * phi); 1016 float rat = (float) Math.Sqrt(10f + (2f * sq5)) / (4f * phi);
1006 float a = (radius / rat) * 0.5f; 1017 float a = (diameter / rat) * 0.5f;
1007 float b = (radius / rat) / (2.0f * phi); 1018 float b = (diameter / rat) / (2.0f * phi);
1019
1008 1020
1021 // 12 Icosahedron vertexes
1009 Vertex v1 = new Vertex(0f, b, -a); 1022 Vertex v1 = new Vertex(0f, b, -a);
1010 Vertex v2 = new Vertex(b, a, 0f); 1023 Vertex v2 = new Vertex(b, a, 0f);
1011 Vertex v3 = new Vertex(-b, a, 0f); 1024 Vertex v3 = new Vertex(-b, a, 0f);
@@ -1018,72 +1031,47 @@ namespace OpenSim.Region.Physics.Meshing
1018 Vertex v10 = new Vertex(-a, 0f, -b); 1031 Vertex v10 = new Vertex(-a, 0f, -b);
1019 Vertex v11 = new Vertex(b, -a, 0); 1032 Vertex v11 = new Vertex(b, -a, 0);
1020 Vertex v12 = new Vertex(-b, -a, 0); 1033 Vertex v12 = new Vertex(-b, -a, 0);
1021 m.Add(v1); 1034
1022 m.Add(v2); 1035
1023 m.Add(v3); 1036
1024 m.Add(v4); 1037 // Base Faces of the Icosahedron (20)
1025 m.Add(v5); 1038 SphereLODTriangle(v1, v2, v3, diameter, LOD, m);
1026 m.Add(v6); 1039 SphereLODTriangle(v4, v3, v2, diameter, LOD, m);
1027 m.Add(v7); 1040 SphereLODTriangle(v4, v5, v6, diameter, LOD, m);
1028 m.Add(v8); 1041 SphereLODTriangle(v4, v9, v5, diameter, LOD, m);
1029 m.Add(v9); 1042 SphereLODTriangle(v1, v7, v8, diameter, LOD, m);
1030 m.Add(v10); 1043 SphereLODTriangle(v1, v10, v7, diameter, LOD, m);
1031 m.Add(v11); 1044 SphereLODTriangle(v5, v11, v12, diameter, LOD, m);
1032 m.Add(v12); 1045 SphereLODTriangle(v7, v12, v11, diameter, LOD, m);
1033 1046 SphereLODTriangle(v3, v6, v10, diameter, LOD, m);
1034 Triangle t1 = new Triangle(v1, v2, v3); 1047 SphereLODTriangle(v12, v10, v6, diameter, LOD, m);
1035 Triangle t2 = new Triangle(v4, v3, v2); 1048 SphereLODTriangle(v2, v8, v9, diameter, LOD, m);
1036 Triangle t3 = new Triangle(v4, v5, v6); 1049 SphereLODTriangle(v11, v9, v8, diameter, LOD, m);
1037 Triangle t4 = new Triangle(v4, v9, v5); 1050 SphereLODTriangle(v4, v6, v3, diameter, LOD, m);
1038 Triangle t5 = new Triangle(v1, v7, v8); 1051 SphereLODTriangle(v4, v2, v9, diameter, LOD, m);
1039 Triangle t6 = new Triangle(v1, v10, v7); 1052 SphereLODTriangle(v1, v3, v10, diameter, LOD, m);
1040 Triangle t7 = new Triangle(v5, v11, v12); 1053 SphereLODTriangle(v1, v8, v2, diameter, LOD, m);
1041 Triangle t8 = new Triangle(v7, v12, v11); 1054 SphereLODTriangle(v7, v10, v12, diameter, LOD, m);
1042 Triangle t9 = new Triangle(v3, v6, v10); 1055 SphereLODTriangle(v7, v11, v8, diameter, LOD, m);
1043 Triangle t10 = new Triangle(v12, v10, v6); 1056 SphereLODTriangle(v5, v12, v6, diameter, LOD, m);
1044 Triangle t11 = new Triangle(v2, v8, v9); 1057 SphereLODTriangle(v5, v9, v11, diameter, LOD, m);
1045 Triangle t12 = new Triangle(v11, v9, v8); 1058
1046 Triangle t13 = new Triangle(v4, v6, v3); 1059 // Scale the mesh based on our prim scale
1047 Triangle t14 = new Triangle(v4, v2, v9);
1048 Triangle t15 = new Triangle(v1, v3, v10);
1049 Triangle t16 = new Triangle(v1, v8, v2);
1050 Triangle t17 = new Triangle(v7, v10, v12);
1051 Triangle t18 = new Triangle(v7, v11, v8);
1052 Triangle t19 = new Triangle(v5, v12, v6);
1053 Triangle t20 = new Triangle(v5, v9, v11);
1054 m.Add(t1);
1055 m.Add(t2);
1056 m.Add(t3);
1057 m.Add(t4);
1058 m.Add(t5);
1059 m.Add(t6);
1060 m.Add(t7);
1061 m.Add(t8);
1062 m.Add(t9);
1063 m.Add(t10);
1064 m.Add(t11);
1065 m.Add(t12);
1066 m.Add(t13);
1067 m.Add(t14);
1068 m.Add(t15);
1069 m.Add(t16);
1070 m.Add(t17);
1071 m.Add(t18);
1072 m.Add(t19);
1073 m.Add(t20);
1074
1075 // strechy!
1076 foreach (Vertex v in m.vertices) 1060 foreach (Vertex v in m.vertices)
1077 { 1061 {
1078 v.X *= size.X; 1062 v.X *= size.X;
1079 v.Y *= size.Y; 1063 v.Y *= size.Y;
1080 v.Z *= size.Z; 1064 v.Z *= size.Z;
1081 } 1065 }
1066
1067 // This was built with the normals pointing inside..
1068 // therefore we have to invert the normals
1082 foreach (Triangle t in m.triangles) 1069 foreach (Triangle t in m.triangles)
1083 { 1070 {
1084 t.invertNormal(); 1071 t.invertNormal();
1085 } 1072 }
1086 m.DumpRaw(baseDir, primName, "Z extruded"); 1073 // Dump the faces for visualization in blender.
1074 m.DumpRaw(baseDir, primName, "Icosahedron");
1087 1075
1088 return m; 1076 return m;
1089 } 1077 }
@@ -1149,6 +1137,49 @@ namespace OpenSim.Region.Physics.Meshing
1149 } 1137 }
1150 } 1138 }
1151 1139
1140 public static Vertex midUnitRadialPoint(Vertex a, Vertex b, float radius)
1141 {
1142 Vertex midpoint = new Vertex(a + b) * 0.5f;
1143 return (midpoint.normalize() * radius);
1144 }
1145
1146 public static void SphereLODTriangle(Vertex a, Vertex b, Vertex c, float diameter, float LOD, Mesh m)
1147 {
1148 Vertex aa = a - b;
1149 Vertex ba = b - c;
1150 Vertex da = c - a;
1151
1152 if (((aa.length() < LOD) && (ba.length() < LOD) && (da.length() < LOD)))
1153 {
1154 // We don't want duplicate verticies. Duplicates cause the scale algorithm to produce a spikeball
1155 // spikes are novel, but we want ellipsoids.
1156
1157 if (!m.vertices.Contains(a))
1158 m.Add(a);
1159 if (!m.vertices.Contains(b))
1160 m.Add(b);
1161 if (!m.vertices.Contains(c))
1162 m.Add(c);
1163
1164 // Add the triangle to the mesh
1165 Triangle t = new Triangle(a, b, c);
1166 m.Add(t);
1167 }
1168 else
1169 {
1170 Vertex ab = midUnitRadialPoint(a, b, diameter);
1171 Vertex bc = midUnitRadialPoint(b, c, diameter);
1172 Vertex ca = midUnitRadialPoint(c, a, diameter);
1173
1174 // Recursive! Splits the triangle up into 4 smaller triangles
1175 SphereLODTriangle(a, ab, ca, diameter, LOD, m);
1176 SphereLODTriangle(ab, b, bc, diameter, LOD, m);
1177 SphereLODTriangle(ca, bc, c, diameter, LOD, m);
1178 SphereLODTriangle(ab, bc, ca, diameter, LOD, m);
1179
1180 }
1181 }
1182
1152 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size) 1183 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
1153 { 1184 {
1154 Mesh mesh = null; 1185 Mesh mesh = null;