aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Meshmerizer.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs115
1 files changed, 74 insertions, 41 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 99b2d84..5ca5f20 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -100,7 +100,6 @@ namespace OpenSim.Region.Physics.Meshing
100 { 100 {
101 m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedSculptMapPath, e.Message); 101 m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedSculptMapPath, e.Message);
102 } 102 }
103
104 } 103 }
105 104
106 /// <summary> 105 /// <summary>
@@ -156,7 +155,6 @@ namespace OpenSim.Region.Physics.Meshing
156 return box; 155 return box;
157 } 156 }
158 157
159
160 /// <summary> 158 /// <summary>
161 /// Creates a simple bounding box mesh for a complex input mesh 159 /// Creates a simple bounding box mesh for a complex input mesh
162 /// </summary> 160 /// </summary>
@@ -193,7 +191,6 @@ namespace OpenSim.Region.Physics.Meshing
193 m_log.Error(message); 191 m_log.Error(message);
194 m_log.Error("\nPrim Name: " + primName); 192 m_log.Error("\nPrim Name: " + primName);
195 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString()); 193 m_log.Error("****** PrimMesh Parameters ******\n" + primMesh.ParamsToDisplayString());
196
197 } 194 }
198 195
199 private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod) 196 private ulong GetMeshKey(PrimitiveBaseShape pbs, Vector3 size, float lod)
@@ -257,6 +254,52 @@ namespace OpenSim.Region.Physics.Meshing
257 return ((hash << 5) + hash) + (ulong)(c >> 8); 254 return ((hash << 5) + hash) + (ulong)(c >> 8);
258 } 255 }
259 256
257 /// <summary>
258 /// Add a submesh to an existing list of coords and faces.
259 /// </summary>
260 /// <param name="subMeshData"></param>
261 /// <param name="size">Size of entire object</param>
262 /// <param name="coords"></param>
263 /// <param name="faces"></param>
264 private void AddSubMesh(OSDMap subMeshData, Vector3 size, List<Coord> coords, List<Face> faces)
265 {
266 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap));
267
268 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
269 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
270 // geometry for this submesh.
271 if (subMeshData.ContainsKey("NoGeometry") && ((OSDBoolean)subMeshData["NoGeometry"]))
272 return;
273
274 OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshData["PositionDomain"])["Max"].AsVector3();
275 OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshData["PositionDomain"])["Min"].AsVector3();
276 ushort faceIndexOffset = (ushort)coords.Count;
277
278 byte[] posBytes = subMeshData["Position"].AsBinary();
279 for (int i = 0; i < posBytes.Length; i += 6)
280 {
281 ushort uX = Utils.BytesToUInt16(posBytes, i);
282 ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
283 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
284
285 Coord c = new Coord(
286 Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
287 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
288 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);
289
290 coords.Add(c);
291 }
292
293 byte[] triangleBytes = subMeshData["TriangleList"].AsBinary();
294 for (int i = 0; i < triangleBytes.Length; i += 6)
295 {
296 ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset);
297 ushort v2 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset);
298 ushort v3 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset);
299 Face f = new Face(v1, v2, v3);
300 faces.Add(f);
301 }
302 }
260 303
261 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 304 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
262 { 305 {
@@ -276,7 +319,7 @@ namespace OpenSim.Region.Physics.Meshing
276 if (!useMeshiesPhysicsMesh) 319 if (!useMeshiesPhysicsMesh)
277 return null; 320 return null;
278 321
279 m_log.Debug("[MESH]: experimental mesh proxy generation"); 322 m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
280 323
281 OSD meshOsd = null; 324 OSD meshOsd = null;
282 325
@@ -291,23 +334,38 @@ namespace OpenSim.Region.Physics.Meshing
291 { 334 {
292 try 335 try
293 { 336 {
294 meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data); 337 OSD osd = OSDParser.DeserializeLLSDBinary(data);
338 if (osd is OSDMap)
339 meshOsd = (OSDMap)osd;
340 else
341 {
342 m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
343 return null;
344 }
295 } 345 }
296 catch (Exception e) 346 catch (Exception e)
297 { 347 {
298 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); 348 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
299 } 349 }
350
300 start = data.Position; 351 start = data.Position;
301 } 352 }
302 353
303 if (meshOsd is OSDMap) 354 if (meshOsd is OSDMap)
304 { 355 {
356 OSDMap physicsParms = null;
305 OSDMap map = (OSDMap)meshOsd; 357 OSDMap map = (OSDMap)meshOsd;
306 OSDMap physicsParms = (OSDMap)map["physics_shape"]; // old asset format 358 if (map.ContainsKey("physics_shape"))
307 359 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
308 if (physicsParms.Count == 0) 360 else if (map.ContainsKey("physics_mesh"))
309 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 361 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
310 362
363 if (physicsParms == null)
364 {
365 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
366 return null;
367 }
368
311 int physOffset = physicsParms["offset"].AsInteger() + (int)start; 369 int physOffset = physicsParms["offset"].AsInteger() + (int)start;
312 int physSize = physicsParms["size"].AsInteger(); 370 int physSize = physicsParms["size"].AsInteger();
313 371
@@ -353,42 +411,13 @@ namespace OpenSim.Region.Physics.Meshing
353 // physics_shape is an array of OSDMaps, one for each submesh 411 // physics_shape is an array of OSDMaps, one for each submesh
354 if (decodedMeshOsd is OSDArray) 412 if (decodedMeshOsd is OSDArray)
355 { 413 {
414// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
415
356 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 416 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
357 foreach (OSD subMeshOsd in decodedMeshOsdArray) 417 foreach (OSD subMeshOsd in decodedMeshOsdArray)
358 { 418 {
359 if (subMeshOsd is OSDMap) 419 if (subMeshOsd is OSDMap)
360 { 420 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
361 OSDMap subMeshMap = (OSDMap)subMeshOsd;
362
363 OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3();
364 OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3();
365 ushort faceIndexOffset = (ushort)coords.Count;
366
367 byte[] posBytes = subMeshMap["Position"].AsBinary();
368 for (int i = 0; i < posBytes.Length; i += 6)
369 {
370 ushort uX = Utils.BytesToUInt16(posBytes, i);
371 ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
372 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
373
374 Coord c = new Coord(
375 Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
376 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
377 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);
378
379 coords.Add(c);
380 }
381
382 byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary();
383 for (int i = 0; i < triangleBytes.Length; i += 6)
384 {
385 ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset);
386 ushort v2 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset);
387 ushort v3 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset);
388 Face f = new Face(v1, v2, v3);
389 faces.Add(f);
390 }
391 }
392 } 421 }
393 } 422 }
394 } 423 }
@@ -511,7 +540,6 @@ namespace OpenSim.Region.Physics.Meshing
511 540
512 profileBegin = 0.5f * profileBegin + 0.5f; 541 profileBegin = 0.5f * profileBegin + 0.5f;
513 profileEnd = 0.5f * profileEnd + 0.5f; 542 profileEnd = 0.5f * profileEnd + 0.5f;
514
515 } 543 }
516 544
517 int hollowSides = sides; 545 int hollowSides = sides;
@@ -620,6 +648,7 @@ namespace OpenSim.Region.Physics.Meshing
620 Face f = faces[i]; 648 Face f = faces[i];
621 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3])); 649 mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3]));
622 } 650 }
651
623 return mesh; 652 return mesh;
624 } 653 }
625 654
@@ -630,6 +659,10 @@ namespace OpenSim.Region.Physics.Meshing
630 659
631 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) 660 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical)
632 { 661 {
662#if SPAM
663 m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName);
664#endif
665
633 Mesh mesh = null; 666 Mesh mesh = null;
634 ulong key = 0; 667 ulong key = 0;
635 668