diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/HelperTypes.cs | 77 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 151 |
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; |