aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs222
1 files changed, 123 insertions, 99 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 8a9260c..f97449c 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -301,131 +301,155 @@ namespace OpenSim.Region.Physics.Meshing
301 } 301 }
302 } 302 }
303 303
304 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 304 /// <summary>
305 /// Generate the co-ords and faces necessary to construct a mesh from the mesh data the accompanies a prim.
306 /// </summary>
307 /// <param name="primName"></param>
308 /// <param name="primShape"></param>
309 /// <param name="size"></param>
310 /// <param name="coords">Coords are added to this list by the method.</param>
311 /// <param name="faces">Faces are added to this list by the method.</param>
312 /// <returns>true if coords and faces were successfully generated, false if not</returns>
313 private bool GenerateCoordsAndFacesFromPrimMeshData(string primName, PrimitiveBaseShape primShape, Vector3 size, List<Coord> coords, List<Face> faces)
305 { 314 {
306// m_log.DebugFormat( 315 m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
307// "[MESH]: Creating physics proxy for {0}, shape {1}",
308// primName, (OpenMetaverse.SculptType)primShape.SculptType);
309 316
310 PrimMesh primMesh; 317 OSD meshOsd = null;
311 PrimMesher.SculptMesh sculptMesh;
312
313 List<Coord> coords = new List<Coord>();
314 List<Face> faces = new List<Face>();
315 318
316 Image idata = null; 319 if (primShape.SculptData.Length <= 0)
317 string decodedSculptFileName = ""; 320 {
321 m_log.Error("[MESH]: asset data is zero length");
322 return false;
323 }
318 324
319 if (primShape.SculptEntry) 325 long start = 0;
326 using (MemoryStream data = new MemoryStream(primShape.SculptData))
320 { 327 {
321 if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) 328 try
322 { 329 {
323 if (!useMeshiesPhysicsMesh) 330 OSD osd = OSDParser.DeserializeLLSDBinary(data);
324 return null; 331 if (osd is OSDMap)
325 332 meshOsd = (OSDMap)osd;
326 m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); 333 else
327
328 OSD meshOsd = null;
329
330 if (primShape.SculptData.Length <= 0)
331 { 334 {
332 m_log.Error("[MESH]: asset data is zero length"); 335 m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
333 return null; 336 return false;
334 } 337 }
338 }
339 catch (Exception e)
340 {
341 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
342 }
335 343
336 long start = 0; 344 start = data.Position;
337 using (MemoryStream data = new MemoryStream(primShape.SculptData)) 345 }
338 {
339 try
340 {
341 OSD osd = OSDParser.DeserializeLLSDBinary(data);
342 if (osd is OSDMap)
343 meshOsd = (OSDMap)osd;
344 else
345 {
346 m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
347 return null;
348 }
349 }
350 catch (Exception e)
351 {
352 m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString());
353 }
354
355 start = data.Position;
356 }
357 346
358 if (meshOsd is OSDMap) 347 if (meshOsd is OSDMap)
359 { 348 {
360 OSDMap physicsParms = null; 349 OSDMap physicsParms = null;
361 OSDMap map = (OSDMap)meshOsd; 350 OSDMap map = (OSDMap)meshOsd;
362 if (map.ContainsKey("physics_shape")) 351 if (map.ContainsKey("physics_shape"))
363 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 352 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
364 else if (map.ContainsKey("physics_mesh")) 353 else if (map.ContainsKey("physics_mesh"))
365 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 354 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
366 355
367 if (physicsParms == null) 356 if (physicsParms == null)
368 { 357 {
369 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); 358 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset");
370 return null; 359 return false;
371 } 360 }
372 361
373 int physOffset = physicsParms["offset"].AsInteger() + (int)start; 362 int physOffset = physicsParms["offset"].AsInteger() + (int)start;
374 int physSize = physicsParms["size"].AsInteger(); 363 int physSize = physicsParms["size"].AsInteger();
375 364
376 if (physOffset < 0 || physSize == 0) 365 if (physOffset < 0 || physSize == 0)
377 return null; // no mesh data in asset 366 return false; // no mesh data in asset
378 367
379 OSD decodedMeshOsd = new OSD(); 368 OSD decodedMeshOsd = new OSD();
380 byte[] meshBytes = new byte[physSize]; 369 byte[] meshBytes = new byte[physSize];
381 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); 370 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
382// byte[] decompressed = new byte[physSize * 5]; 371// byte[] decompressed = new byte[physSize * 5];
383 try 372 try
373 {
374 using (MemoryStream inMs = new MemoryStream(meshBytes))
375 {
376 using (MemoryStream outMs = new MemoryStream())
384 { 377 {
385 using (MemoryStream inMs = new MemoryStream(meshBytes)) 378 using (ZOutputStream zOut = new ZOutputStream(outMs))
386 { 379 {
387 using (MemoryStream outMs = new MemoryStream()) 380 byte[] readBuffer = new byte[2048];
381 int readLen = 0;
382 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
388 { 383 {
389 using (ZOutputStream zOut = new ZOutputStream(outMs)) 384 zOut.Write(readBuffer, 0, readLen);
390 {
391 byte[] readBuffer = new byte[2048];
392 int readLen = 0;
393 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
394 {
395 zOut.Write(readBuffer, 0, readLen);
396 }
397 zOut.Flush();
398 outMs.Seek(0, SeekOrigin.Begin);
399
400 byte[] decompressedBuf = outMs.GetBuffer();
401
402 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
403 }
404 } 385 }
386 zOut.Flush();
387 outMs.Seek(0, SeekOrigin.Begin);
388
389 byte[] decompressedBuf = outMs.GetBuffer();
390
391 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
405 } 392 }
406 } 393 }
407 catch (Exception e) 394 }
408 { 395 }
409 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); 396 catch (Exception e)
410 return null; 397 {
411 } 398 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
399 return false;
400 }
412 401
413 OSDArray decodedMeshOsdArray = null; 402 OSDArray decodedMeshOsdArray = null;
414 403
415 // physics_shape is an array of OSDMaps, one for each submesh 404 // physics_shape is an array of OSDMaps, one for each submesh
416 if (decodedMeshOsd is OSDArray) 405 if (decodedMeshOsd is OSDArray)
417 { 406 {
418// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 407// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
419 408
420 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 409 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
421 foreach (OSD subMeshOsd in decodedMeshOsdArray) 410 foreach (OSD subMeshOsd in decodedMeshOsdArray)
422 { 411 {
423 if (subMeshOsd is OSDMap) 412 if (subMeshOsd is OSDMap)
424 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 413 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
425 }
426 }
427 } 414 }
428 } 415 }
416 }
417
418 return true;
419 }
420
421 /// <summary>
422 /// Create a physics mesh from data that comes with the prim. The actual data used depends on the prim type.
423 /// </summary>
424 /// <param name="primName"></param>
425 /// <param name="primShape"></param>
426 /// <param name="size"></param>
427 /// <param name="lod"></param>
428 /// <returns></returns>
429 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
430 {
431// m_log.DebugFormat(
432// "[MESH]: Creating physics proxy for {0}, shape {1}",
433// primName, (OpenMetaverse.SculptType)primShape.SculptType);
434
435 PrimMesh primMesh;
436 PrimMesher.SculptMesh sculptMesh;
437
438 List<Coord> coords = new List<Coord>();
439 List<Face> faces = new List<Face>();
440
441 Image idata = null;
442 string decodedSculptFileName = "";
443
444 if (primShape.SculptEntry)
445 {
446 if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh)
447 {
448 if (!useMeshiesPhysicsMesh)
449 return null;
450
451 GeneratePointsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces);
452 }
429 else 453 else
430 { 454 {
431 if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) 455 if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)