diff options
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Meshmerizer.cs')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index a5fe45b..b79e1a1 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 | { |
@@ -304,6 +347,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
304 | { | 347 | { |
305 | m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); | 348 | m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); |
306 | } | 349 | } |
350 | |||
307 | start = data.Position; | 351 | start = data.Position; |
308 | } | 352 | } |
309 | 353 | ||
@@ -315,9 +359,10 @@ namespace OpenSim.Region.Physics.Meshing | |||
315 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format | 359 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format |
316 | else if (map.ContainsKey("physics_mesh")) | 360 | else if (map.ContainsKey("physics_mesh")) |
317 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format | 361 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format |
362 | |||
318 | if (physicsParms == null) | 363 | if (physicsParms == null) |
319 | { | 364 | { |
320 | m_log.Warn("[Mesh]: no recognized physics mesh found in mesh asset"); | 365 | m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); |
321 | return null; | 366 | return null; |
322 | } | 367 | } |
323 | 368 | ||
@@ -366,42 +411,13 @@ namespace OpenSim.Region.Physics.Meshing | |||
366 | // physics_shape is an array of OSDMaps, one for each submesh | 411 | // physics_shape is an array of OSDMaps, one for each submesh |
367 | if (decodedMeshOsd is OSDArray) | 412 | if (decodedMeshOsd is OSDArray) |
368 | { | 413 | { |
414 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); | ||
415 | |||
369 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | 416 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; |
370 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | 417 | foreach (OSD subMeshOsd in decodedMeshOsdArray) |
371 | { | 418 | { |
372 | if (subMeshOsd is OSDMap) | 419 | if (subMeshOsd is OSDMap) |
373 | { | 420 | AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); |
374 | OSDMap subMeshMap = (OSDMap)subMeshOsd; | ||
375 | |||
376 | OpenMetaverse.Vector3 posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"].AsVector3(); | ||
377 | OpenMetaverse.Vector3 posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"].AsVector3(); | ||
378 | ushort faceIndexOffset = (ushort)coords.Count; | ||
379 | |||
380 | byte[] posBytes = subMeshMap["Position"].AsBinary(); | ||
381 | for (int i = 0; i < posBytes.Length; i += 6) | ||
382 | { | ||
383 | ushort uX = Utils.BytesToUInt16(posBytes, i); | ||
384 | ushort uY = Utils.BytesToUInt16(posBytes, i + 2); | ||
385 | ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); | ||
386 | |||
387 | Coord c = new Coord( | ||
388 | Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X, | ||
389 | Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y, | ||
390 | Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z); | ||
391 | |||
392 | coords.Add(c); | ||
393 | } | ||
394 | |||
395 | byte[] triangleBytes = subMeshMap["TriangleList"].AsBinary(); | ||
396 | for (int i = 0; i < triangleBytes.Length; i += 6) | ||
397 | { | ||
398 | ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i) + faceIndexOffset); | ||
399 | ushort v2 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2) + faceIndexOffset); | ||
400 | ushort v3 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4) + faceIndexOffset); | ||
401 | Face f = new Face(v1, v2, v3); | ||
402 | faces.Add(f); | ||
403 | } | ||
404 | } | ||
405 | } | 421 | } |
406 | } | 422 | } |
407 | } | 423 | } |
@@ -524,7 +540,6 @@ namespace OpenSim.Region.Physics.Meshing | |||
524 | 540 | ||
525 | profileBegin = 0.5f * profileBegin + 0.5f; | 541 | profileBegin = 0.5f * profileBegin + 0.5f; |
526 | profileEnd = 0.5f * profileEnd + 0.5f; | 542 | profileEnd = 0.5f * profileEnd + 0.5f; |
527 | |||
528 | } | 543 | } |
529 | 544 | ||
530 | int hollowSides = sides; | 545 | int hollowSides = sides; |
@@ -633,6 +648,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
633 | Face f = faces[i]; | 648 | Face f = faces[i]; |
634 | 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])); |
635 | } | 650 | } |
651 | |||
636 | return mesh; | 652 | return mesh; |
637 | } | 653 | } |
638 | 654 | ||
@@ -643,6 +659,10 @@ namespace OpenSim.Region.Physics.Meshing | |||
643 | 659 | ||
644 | 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) |
645 | { | 661 | { |
662 | #if SPAM | ||
663 | m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); | ||
664 | #endif | ||
665 | |||
646 | Mesh mesh = null; | 666 | Mesh mesh = null; |
647 | ulong key = 0; | 667 | ulong key = 0; |
648 | 668 | ||