diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/SculptMesh.cs | 198 |
1 files changed, 162 insertions, 36 deletions
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs index 9a5a776..9da74e6 100644 --- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs +++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs | |||
@@ -84,6 +84,128 @@ namespace PrimMesher | |||
84 | return sculptMesh; | 84 | return sculptMesh; |
85 | } | 85 | } |
86 | 86 | ||
87 | /// <summary> | ||
88 | /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications | ||
89 | /// Construct a sculpt mesh from a 2D array of floats | ||
90 | /// </summary> | ||
91 | /// <param name="zMap"></param> | ||
92 | /// <param name="xBegin"></param> | ||
93 | /// <param name="xEnd"></param> | ||
94 | /// <param name="yBegin"></param> | ||
95 | /// <param name="yEnd"></param> | ||
96 | /// <param name="viewerMode"></param> | ||
97 | public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode) | ||
98 | { | ||
99 | float xStep, yStep; | ||
100 | float uStep, vStep; | ||
101 | |||
102 | int numYElements = zMap.GetLength(0); | ||
103 | int numXElements = zMap.GetLength(1); | ||
104 | |||
105 | try | ||
106 | { | ||
107 | xStep = (xEnd - xBegin) / (float)(numXElements - 1); | ||
108 | yStep = (yEnd - yBegin) / (float)(numYElements - 1); | ||
109 | |||
110 | uStep = 1.0f / (numXElements - 1); | ||
111 | vStep = 1.0f / (numYElements - 1); | ||
112 | } | ||
113 | catch (DivideByZeroException) | ||
114 | { | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | coords = new List<Coord>(); | ||
119 | faces = new List<Face>(); | ||
120 | normals = new List<Coord>(); | ||
121 | uvs = new List<UVCoord>(); | ||
122 | |||
123 | viewerFaces = new List<ViewerFace>(); | ||
124 | |||
125 | int p1, p2, p3, p4; | ||
126 | |||
127 | int x, y; | ||
128 | int xStart = 0, yStart = 0; | ||
129 | |||
130 | for (y = yStart; y < numYElements; y++) | ||
131 | { | ||
132 | int rowOffset = y * numXElements; | ||
133 | |||
134 | for (x = xStart; x < numXElements; x++) | ||
135 | { | ||
136 | /* | ||
137 | * p1-----p2 | ||
138 | * | \ f2 | | ||
139 | * | \ | | ||
140 | * | f1 \| | ||
141 | * p3-----p4 | ||
142 | */ | ||
143 | |||
144 | |||
145 | p4 = rowOffset + x; | ||
146 | p3 = p4 - 1; | ||
147 | |||
148 | p2 = p4 - numXElements; | ||
149 | p1 = p3 - numXElements; | ||
150 | |||
151 | Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]); | ||
152 | this.coords.Add(c); | ||
153 | if (viewerMode) | ||
154 | { | ||
155 | this.normals.Add(new Coord()); | ||
156 | this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y)); | ||
157 | } | ||
158 | |||
159 | if (y > 0 && x > 0) | ||
160 | { | ||
161 | Face f1, f2; | ||
162 | |||
163 | //if (viewerMode) | ||
164 | //{ | ||
165 | // f1 = new Face(p1, p3, p4, p1, p3, p4); | ||
166 | // f1.uv1 = p1; | ||
167 | // f1.uv2 = p3; | ||
168 | // f1.uv3 = p4; | ||
169 | |||
170 | // f2 = new Face(p1, p4, p2, p1, p4, p2); | ||
171 | // f2.uv1 = p1; | ||
172 | // f2.uv2 = p4; | ||
173 | // f2.uv3 = p2; | ||
174 | //} | ||
175 | //else | ||
176 | //{ | ||
177 | // f1 = new Face(p1, p3, p4); | ||
178 | // f2 = new Face(p1, p4, p2); | ||
179 | //} | ||
180 | |||
181 | if (viewerMode) | ||
182 | { | ||
183 | f1 = new Face(p1, p4, p3, p1, p4, p3); | ||
184 | f1.uv1 = p1; | ||
185 | f1.uv2 = p4; | ||
186 | f1.uv3 = p3; | ||
187 | |||
188 | f2 = new Face(p1, p2, p4, p1, p2, p4); | ||
189 | f2.uv1 = p1; | ||
190 | f2.uv2 = p2; | ||
191 | f2.uv3 = p4; | ||
192 | } | ||
193 | else | ||
194 | { | ||
195 | f1 = new Face(p1, p4, p3); | ||
196 | f2 = new Face(p1, p2, p4); | ||
197 | } | ||
198 | |||
199 | this.faces.Add(f1); | ||
200 | this.faces.Add(f2); | ||
201 | } | ||
202 | } | ||
203 | } | ||
204 | |||
205 | if (viewerMode) | ||
206 | calcVertexNormals(SculptType.plane, numXElements, numYElements); | ||
207 | } | ||
208 | |||
87 | public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) | 209 | public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) |
88 | { | 210 | { |
89 | coords = new List<Coord>(); | 211 | coords = new List<Coord>(); |
@@ -142,6 +264,7 @@ namespace PrimMesher | |||
142 | bitmap.SetPixel(imageX, 0, newC1); | 264 | bitmap.SetPixel(imageX, 0, newC1); |
143 | bitmap.SetPixel(imageX, lastRow, newC2); | 265 | bitmap.SetPixel(imageX, lastRow, newC2); |
144 | } | 266 | } |
267 | |||
145 | } | 268 | } |
146 | 269 | ||
147 | 270 | ||
@@ -222,50 +345,53 @@ namespace PrimMesher | |||
222 | bitmap.Dispose(); | 345 | bitmap.Dispose(); |
223 | 346 | ||
224 | if (viewerMode) | 347 | if (viewerMode) |
225 | { // compute vertex normals by summing all the surface normals of all the triangles sharing | 348 | calcVertexNormals(sculptType, width, height); |
226 | // each vertex and then normalizing | 349 | } |
227 | int numFaces = this.faces.Count; | ||
228 | for (int i = 0; i < numFaces; i++) | ||
229 | { | ||
230 | Face face = this.faces[i]; | ||
231 | Coord surfaceNormal = face.SurfaceNormal(this.coords); | ||
232 | this.normals[face.v1] += surfaceNormal; | ||
233 | this.normals[face.v2] += surfaceNormal; | ||
234 | this.normals[face.v3] += surfaceNormal; | ||
235 | } | ||
236 | 350 | ||
237 | int numCoords = this.coords.Count; | 351 | private void calcVertexNormals(SculptType sculptType, int xSize, int ySize) |
238 | for (int i = 0; i < numCoords; i++) | 352 | { // compute vertex normals by summing all the surface normals of all the triangles sharing |
239 | this.coords[i].Normalize(); | 353 | // each vertex and then normalizing |
354 | int numFaces = this.faces.Count; | ||
355 | for (int i = 0; i < numFaces; i++) | ||
356 | { | ||
357 | Face face = this.faces[i]; | ||
358 | Coord surfaceNormal = face.SurfaceNormal(this.coords); | ||
359 | this.normals[face.v1] += surfaceNormal; | ||
360 | this.normals[face.v2] += surfaceNormal; | ||
361 | this.normals[face.v3] += surfaceNormal; | ||
362 | } | ||
240 | 363 | ||
241 | if (sculptType != SculptType.plane) | 364 | int numCoords = this.coords.Count; |
242 | { // blend the vertex normals at the cylinder seam | 365 | for (int i = 0; i < numCoords; i++) |
243 | pixelsAcross = width + 1; | 366 | this.coords[i].Normalize(); |
244 | for (imageY = 0; imageY < height; imageY++) | ||
245 | { | ||
246 | int rowOffset = imageY * pixelsAcross; | ||
247 | 367 | ||
248 | this.normals[rowOffset] = this.normals[rowOffset + width - 1] = (this.normals[rowOffset] + this.normals[rowOffset + width - 1]).Normalize(); | 368 | if (sculptType != SculptType.plane) |
249 | } | 369 | { // blend the vertex normals at the cylinder seam |
370 | int pixelsAcross = xSize + 1; | ||
371 | for (int y = 0; y < ySize; y++) | ||
372 | { | ||
373 | int rowOffset = y * pixelsAcross; | ||
374 | |||
375 | this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize(); | ||
250 | } | 376 | } |
377 | } | ||
251 | 378 | ||
252 | foreach (Face face in this.faces) | 379 | foreach (Face face in this.faces) |
253 | { | 380 | { |
254 | ViewerFace vf = new ViewerFace(0); | 381 | ViewerFace vf = new ViewerFace(0); |
255 | vf.v1 = this.coords[face.v1]; | 382 | vf.v1 = this.coords[face.v1]; |
256 | vf.v2 = this.coords[face.v2]; | 383 | vf.v2 = this.coords[face.v2]; |
257 | vf.v3 = this.coords[face.v3]; | 384 | vf.v3 = this.coords[face.v3]; |
258 | 385 | ||
259 | vf.n1 = this.normals[face.n1]; | 386 | vf.n1 = this.normals[face.n1]; |
260 | vf.n2 = this.normals[face.n2]; | 387 | vf.n2 = this.normals[face.n2]; |
261 | vf.n3 = this.normals[face.n3]; | 388 | vf.n3 = this.normals[face.n3]; |
262 | 389 | ||
263 | vf.uv1 = this.uvs[face.uv1]; | 390 | vf.uv1 = this.uvs[face.uv1]; |
264 | vf.uv2 = this.uvs[face.uv2]; | 391 | vf.uv2 = this.uvs[face.uv2]; |
265 | vf.uv3 = this.uvs[face.uv3]; | 392 | vf.uv3 = this.uvs[face.uv3]; |
266 | 393 | ||
267 | this.viewerFaces.Add(vf); | 394 | this.viewerFaces.Add(vf); |
268 | } | ||
269 | } | 395 | } |
270 | } | 396 | } |
271 | 397 | ||