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