diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 321 |
1 files changed, 294 insertions, 27 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index c9c52c0..7667e91 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | |||
@@ -41,6 +41,7 @@ using Nini.Config; | |||
41 | using System.Reflection; | 41 | using System.Reflection; |
42 | using System.IO; | 42 | using System.IO; |
43 | using ComponentAce.Compression.Libs.zlib; | 43 | using ComponentAce.Compression.Libs.zlib; |
44 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | ||
44 | 45 | ||
45 | namespace OpenSim.Region.Physics.Meshing | 46 | namespace OpenSim.Region.Physics.Meshing |
46 | { | 47 | { |
@@ -256,7 +257,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
256 | /// <param name="size"></param> | 257 | /// <param name="size"></param> |
257 | /// <param name="lod"></param> | 258 | /// <param name="lod"></param> |
258 | /// <returns></returns> | 259 | /// <returns></returns> |
259 | private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 260 | private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool convex) |
260 | { | 261 | { |
261 | // m_log.DebugFormat( | 262 | // m_log.DebugFormat( |
262 | // "[MESH]: Creating physics proxy for {0}, shape {1}", | 263 | // "[MESH]: Creating physics proxy for {0}, shape {1}", |
@@ -272,7 +273,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
272 | if (!useMeshiesPhysicsMesh) | 273 | if (!useMeshiesPhysicsMesh) |
273 | return null; | 274 | return null; |
274 | 275 | ||
275 | if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces)) | 276 | if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces, convex)) |
276 | return null; | 277 | return null; |
277 | } | 278 | } |
278 | else | 279 | else |
@@ -296,22 +297,20 @@ namespace OpenSim.Region.Physics.Meshing | |||
296 | int numCoords = coords.Count; | 297 | int numCoords = coords.Count; |
297 | int numFaces = faces.Count; | 298 | int numFaces = faces.Count; |
298 | 299 | ||
299 | // Create the list of vertices | ||
300 | List<Vertex> vertices = new List<Vertex>(); | ||
301 | for (int i = 0; i < numCoords; i++) | ||
302 | { | ||
303 | Coord c = coords[i]; | ||
304 | vertices.Add(new Vertex(c.X, c.Y, c.Z)); | ||
305 | } | ||
306 | |||
307 | Mesh mesh = new Mesh(); | 300 | Mesh mesh = new Mesh(); |
308 | // Add the corresponding triangles to the mesh | 301 | // Add the corresponding triangles to the mesh |
309 | for (int i = 0; i < numFaces; i++) | 302 | for (int i = 0; i < numFaces; i++) |
310 | { | 303 | { |
311 | Face f = faces[i]; | 304 | Face f = faces[i]; |
312 | mesh.Add(new Triangle(vertices[f.v1], vertices[f.v2], vertices[f.v3])); | 305 | mesh.Add(new Triangle(coords[f.v1].X, coords[f.v1].Y, coords[f.v1].Z, |
306 | coords[f.v2].X, coords[f.v2].Y, coords[f.v2].Z, | ||
307 | coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z)); | ||
313 | } | 308 | } |
314 | 309 | ||
310 | |||
311 | // mesh.DumpRaw("c:\\lixo", "lixo", "lixo"); | ||
312 | mesh.DumpRaw(".", "lixo", "lixo"); | ||
313 | |||
315 | return mesh; | 314 | return mesh; |
316 | } | 315 | } |
317 | 316 | ||
@@ -325,10 +324,12 @@ namespace OpenSim.Region.Physics.Meshing | |||
325 | /// <param name="faces">Faces are added to this list by the method.</param> | 324 | /// <param name="faces">Faces are added to this list by the method.</param> |
326 | /// <returns>true if coords and faces were successfully generated, false if not</returns> | 325 | /// <returns>true if coords and faces were successfully generated, false if not</returns> |
327 | private bool GenerateCoordsAndFacesFromPrimMeshData( | 326 | private bool GenerateCoordsAndFacesFromPrimMeshData( |
328 | string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces) | 327 | string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces, bool convex) |
329 | { | 328 | { |
330 | // m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); | 329 | // m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); |
331 | 330 | ||
331 | bool usemesh = false; | ||
332 | |||
332 | coords = new List<Coord>(); | 333 | coords = new List<Coord>(); |
333 | faces = new List<Face>(); | 334 | faces = new List<Face>(); |
334 | OSD meshOsd = null; | 335 | OSD meshOsd = null; |
@@ -365,14 +366,25 @@ namespace OpenSim.Region.Physics.Meshing | |||
365 | { | 366 | { |
366 | OSDMap physicsParms = null; | 367 | OSDMap physicsParms = null; |
367 | OSDMap map = (OSDMap)meshOsd; | 368 | OSDMap map = (OSDMap)meshOsd; |
368 | if (map.ContainsKey("physics_shape")) | 369 | |
369 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format | 370 | if (!convex) |
370 | else if (map.ContainsKey("physics_mesh")) | 371 | { |
371 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format | 372 | if (map.ContainsKey("physics_shape")) |
373 | physicsParms = (OSDMap)map["physics_shape"]; // old asset format | ||
374 | else if (map.ContainsKey("physics_mesh")) | ||
375 | physicsParms = (OSDMap)map["physics_mesh"]; // new asset format | ||
376 | |||
377 | if (physicsParms != null) | ||
378 | usemesh = true; | ||
379 | } | ||
380 | |||
381 | if(!usemesh && (map.ContainsKey("physics_convex"))) | ||
382 | physicsParms = (OSDMap)map["physics_convex"]; | ||
383 | |||
372 | 384 | ||
373 | if (physicsParms == null) | 385 | if (physicsParms == null) |
374 | { | 386 | { |
375 | m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); | 387 | m_log.Warn("[MESH]: unknown mesh type"); |
376 | return false; | 388 | return false; |
377 | } | 389 | } |
378 | 390 | ||
@@ -416,19 +428,269 @@ namespace OpenSim.Region.Physics.Meshing | |||
416 | return false; | 428 | return false; |
417 | } | 429 | } |
418 | 430 | ||
419 | OSDArray decodedMeshOsdArray = null; | 431 | if (usemesh) |
432 | { | ||
433 | OSDArray decodedMeshOsdArray = null; | ||
420 | 434 | ||
421 | // physics_shape is an array of OSDMaps, one for each submesh | 435 | // physics_shape is an array of OSDMaps, one for each submesh |
422 | if (decodedMeshOsd is OSDArray) | 436 | if (decodedMeshOsd is OSDArray) |
437 | { | ||
438 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); | ||
439 | |||
440 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | ||
441 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | ||
442 | { | ||
443 | if (subMeshOsd is OSDMap) | ||
444 | AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); | ||
445 | } | ||
446 | } | ||
447 | } | ||
448 | else | ||
423 | { | 449 | { |
424 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); | 450 | OSDMap cmap = (OSDMap)decodedMeshOsd; |
451 | if (cmap == null) | ||
452 | return false; | ||
453 | |||
454 | byte[] data; | ||
455 | const float invMaxU16 = 1.0f / 65535f; | ||
456 | int t1; | ||
457 | int t2; | ||
458 | int t3; | ||
459 | int i; | ||
460 | |||
461 | List<float3> vs = new List<float3>(); | ||
462 | |||
463 | float3 f3; | ||
464 | PHullResult hullr = new PHullResult(); | ||
465 | |||
466 | Coord c; | ||
467 | Face f; | ||
468 | |||
469 | Vector3 range; | ||
470 | Vector3 min; | ||
471 | int nverts; | ||
472 | int nindexs; | ||
473 | |||
474 | if (cmap.ContainsKey("Max")) | ||
475 | range = cmap["Max"].AsVector3(); | ||
476 | else | ||
477 | range = new Vector3(0.5f, 0.5f, 0.5f); | ||
478 | |||
479 | if (cmap.ContainsKey("Min")) | ||
480 | min = cmap["Min"].AsVector3(); | ||
481 | else | ||
482 | min = new Vector3(-0.5f, -0.5f, -0.5f); | ||
483 | |||
484 | range = range - min; | ||
485 | range *= invMaxU16; | ||
486 | |||
487 | if (!convex && cmap.ContainsKey("HullList") && cmap.ContainsKey("Positions")) | ||
488 | { | ||
489 | List<int> hsizes = new List<int>(); | ||
490 | int totalpoints = 0; | ||
491 | data = cmap["HullList"].AsBinary(); | ||
492 | for (i = 0; i < data.Length; i++) | ||
493 | { | ||
494 | t1 = data[i]; | ||
495 | if (t1 == 0) | ||
496 | t1 = 256; | ||
497 | totalpoints += t1; | ||
498 | hsizes.Add(t1); | ||
499 | } | ||
500 | |||
501 | data = cmap["Positions"].AsBinary(); | ||
502 | int ptr = 0; | ||
503 | int vertsoffset = 0; | ||
504 | |||
505 | if (totalpoints == data.Length / 6) // 2 bytes per coord, 3 coords per point | ||
506 | { | ||
507 | foreach (int hullsize in hsizes) | ||
508 | { | ||
509 | for (i = 0; i < hullsize; i++ ) | ||
510 | { | ||
511 | t1 = data[ptr++]; | ||
512 | t1 += data[ptr++] << 8; | ||
513 | t2 = data[ptr++]; | ||
514 | t2 += data[ptr++] << 8; | ||
515 | t3 = data[ptr++]; | ||
516 | t3 += data[ptr++] << 8; | ||
517 | |||
518 | f3 = new float3((t1 * range.X + min.X) * size.X, | ||
519 | (t2 * range.Y + min.Y) * size.Y, | ||
520 | (t3 * range.Z + min.Z) * size.Z); | ||
521 | vs.Add(f3); | ||
522 | } | ||
523 | |||
524 | if(hullsize <3) | ||
525 | { | ||
526 | vs.Clear(); | ||
527 | continue; | ||
528 | } | ||
529 | |||
530 | if (hullsize <5) | ||
531 | { | ||
532 | foreach (float3 point in vs) | ||
533 | { | ||
534 | c.X = point.x; | ||
535 | c.Y = point.y; | ||
536 | c.Z = point.z; | ||
537 | coords.Add(c); | ||
538 | } | ||
539 | f = new Face(vertsoffset, vertsoffset + 1, vertsoffset + 2); | ||
540 | faces.Add(f); | ||
541 | |||
542 | if (hullsize == 4) | ||
543 | { | ||
544 | // not sure about orientation.. | ||
545 | f = new Face(vertsoffset, vertsoffset + 2, vertsoffset + 3); | ||
546 | faces.Add(f); | ||
547 | f = new Face(vertsoffset, vertsoffset + 3, vertsoffset + 1); | ||
548 | faces.Add(f); | ||
549 | f = new Face(vertsoffset + 3, vertsoffset + 2, vertsoffset + 1); | ||
550 | faces.Add(f); | ||
551 | } | ||
552 | vertsoffset += vs.Count; | ||
553 | vs.Clear(); | ||
554 | continue; | ||
555 | } | ||
425 | 556 | ||
426 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | 557 | if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f)) |
427 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | 558 | { |
559 | vs.Clear(); | ||
560 | continue; | ||
561 | } | ||
562 | |||
563 | nverts = hullr.Vertices.Count; | ||
564 | nindexs = hullr.Indices.Count; | ||
565 | |||
566 | if (nindexs % 3 != 0) | ||
567 | { | ||
568 | vs.Clear(); | ||
569 | continue; | ||
570 | } | ||
571 | |||
572 | for (i = 0; i < nverts; i++) | ||
573 | { | ||
574 | c.X = hullr.Vertices[i].x; | ||
575 | c.Y = hullr.Vertices[i].y; | ||
576 | c.Z = hullr.Vertices[i].z; | ||
577 | coords.Add(c); | ||
578 | } | ||
579 | |||
580 | |||
581 | for (i = 0; i < nindexs; i += 3) | ||
582 | { | ||
583 | t1 = hullr.Indices[i]; | ||
584 | if (t1 > nverts) | ||
585 | break; | ||
586 | t2 = hullr.Indices[i + 1]; | ||
587 | if (t2 > nverts) | ||
588 | break; | ||
589 | t3 = hullr.Indices[i + 2]; | ||
590 | if (t3 > nverts) | ||
591 | break; | ||
592 | f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3); | ||
593 | faces.Add(f); | ||
594 | } | ||
595 | vertsoffset += nverts; | ||
596 | vs.Clear(); | ||
597 | } | ||
598 | } | ||
599 | if (coords.Count > 0 && faces.Count > 0) | ||
600 | return true; | ||
601 | |||
602 | } | ||
603 | |||
604 | vs.Clear(); | ||
605 | |||
606 | if (cmap.ContainsKey("BoundingVerts")) | ||
428 | { | 607 | { |
429 | if (subMeshOsd is OSDMap) | 608 | data = cmap["BoundingVerts"].AsBinary(); |
430 | AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); | 609 | |
610 | for (i = 0; i < data.Length; ) | ||
611 | { | ||
612 | t1 = data[i++]; | ||
613 | t1 += data[i++] << 8; | ||
614 | t2 = data[i++]; | ||
615 | t2 += data[i++] << 8; | ||
616 | t3 = data[i++]; | ||
617 | t3 += data[i++] << 8; | ||
618 | |||
619 | f3 = new float3((t1 * range.X + min.X) * size.X, | ||
620 | (t2 * range.Y + min.Y) * size.Y, | ||
621 | (t3 * range.Z + min.Z) * size.Z); | ||
622 | vs.Add(f3); | ||
623 | } | ||
624 | |||
625 | if (vs.Count < 3) | ||
626 | { | ||
627 | vs.Clear(); | ||
628 | return false; | ||
629 | } | ||
630 | |||
631 | if (vs.Count < 5) | ||
632 | { | ||
633 | foreach (float3 point in vs) | ||
634 | { | ||
635 | c.X = point.x; | ||
636 | c.Y = point.y; | ||
637 | c.Z = point.z; | ||
638 | coords.Add(c); | ||
639 | } | ||
640 | f = new Face(0, 1, 2); | ||
641 | faces.Add(f); | ||
642 | |||
643 | if (vs.Count == 4) | ||
644 | { | ||
645 | // not sure about orientation.. | ||
646 | f = new Face(0, 2, 3); | ||
647 | faces.Add(f); | ||
648 | f = new Face(0, 3, 1); | ||
649 | faces.Add(f); | ||
650 | f = new Face( 3, 2, 1); | ||
651 | faces.Add(f); | ||
652 | } | ||
653 | vs.Clear(); | ||
654 | return true; | ||
655 | } | ||
656 | |||
657 | if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f)) | ||
658 | return false; | ||
659 | |||
660 | nverts = hullr.Vertices.Count; | ||
661 | nindexs = hullr.Indices.Count; | ||
662 | |||
663 | if (nindexs % 3 != 0) | ||
664 | return false; | ||
665 | |||
666 | for (i = 0; i < nverts; i++) | ||
667 | { | ||
668 | c.X = hullr.Vertices[i].x; | ||
669 | c.Y = hullr.Vertices[i].y; | ||
670 | c.Z = hullr.Vertices[i].z; | ||
671 | coords.Add(c); | ||
672 | } | ||
673 | for (i = 0; i < nindexs; i += 3) | ||
674 | { | ||
675 | t1 = hullr.Indices[i]; | ||
676 | if (t1 > nverts) | ||
677 | break; | ||
678 | t2 = hullr.Indices[i + 1]; | ||
679 | if (t2 > nverts) | ||
680 | break; | ||
681 | t3 = hullr.Indices[i + 2]; | ||
682 | if (t3 > nverts) | ||
683 | break; | ||
684 | f = new Face(t1, t2, t3); | ||
685 | faces.Add(f); | ||
686 | } | ||
687 | |||
688 | if (coords.Count > 0 && faces.Count > 0) | ||
689 | return true; | ||
431 | } | 690 | } |
691 | else | ||
692 | return false; | ||
693 | |||
432 | } | 694 | } |
433 | } | 695 | } |
434 | 696 | ||
@@ -714,11 +976,16 @@ namespace OpenSim.Region.Physics.Meshing | |||
714 | 976 | ||
715 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 977 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
716 | { | 978 | { |
717 | return CreateMesh(primName, primShape, size, lod, false); | 979 | return CreateMesh(primName, primShape, size, lod, false,false); |
718 | } | 980 | } |
719 | 981 | ||
720 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) | 982 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) |
721 | { | 983 | { |
984 | return CreateMesh(primName, primShape, size, lod, false,false); | ||
985 | } | ||
986 | |||
987 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) | ||
988 | { | ||
722 | #if SPAM | 989 | #if SPAM |
723 | m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); | 990 | m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); |
724 | #endif | 991 | #endif |
@@ -736,7 +1003,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
736 | if (size.Y < 0.01f) size.Y = 0.01f; | 1003 | if (size.Y < 0.01f) size.Y = 0.01f; |
737 | if (size.Z < 0.01f) size.Z = 0.01f; | 1004 | if (size.Z < 0.01f) size.Z = 0.01f; |
738 | 1005 | ||
739 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod); | 1006 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); |
740 | 1007 | ||
741 | if (mesh != null) | 1008 | if (mesh != null) |
742 | { | 1009 | { |