diff options
author | Justin Clark-Casey (justincc) | 2011-07-30 02:34:50 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2011-07-30 02:34:50 +0100 |
commit | 310a6852201812f0c489f3806559dbbc3fd4b2d3 (patch) | |
tree | 5c4393db5f4abd4e766344976f470b9f57fd13aa | |
parent | refactor: extract code which generate points and faces from sculpt data into ... (diff) | |
download | opensim-SC-310a6852201812f0c489f3806559dbbc3fd4b2d3.zip opensim-SC-310a6852201812f0c489f3806559dbbc3fd4b2d3.tar.gz opensim-SC-310a6852201812f0c489f3806559dbbc3fd4b2d3.tar.bz2 opensim-SC-310a6852201812f0c489f3806559dbbc3fd4b2d3.tar.xz |
refactor: extract method that generates a physics mesh from prim shape data
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 258 |
1 files changed, 141 insertions, 117 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 9dfaaa2..e81b982 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -315,10 +315,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
315 | // "[MESH]: Creating physics proxy for {0}, shape {1}", | 315 | // "[MESH]: Creating physics proxy for {0}, shape {1}", |
316 | // primName, (OpenMetaverse.SculptType)primShape.SculptType); | 316 | // primName, (OpenMetaverse.SculptType)primShape.SculptType); |
317 | 317 | ||
318 | PrimMesh primMesh; | 318 | List<Coord> coords; |
319 | 319 | List<Face> faces; | |
320 | List<Coord> coords = new List<Coord>(); | ||
321 | List<Face> faces = new List<Face>(); | ||
322 | 320 | ||
323 | if (primShape.SculptEntry) | 321 | if (primShape.SculptEntry) |
324 | { | 322 | { |
@@ -327,126 +325,19 @@ namespace OpenSim.Region.Physics.Meshing | |||
327 | if (!useMeshiesPhysicsMesh) | 325 | if (!useMeshiesPhysicsMesh) |
328 | return null; | 326 | return null; |
329 | 327 | ||
330 | if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, coords, faces)) | 328 | if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces)) |
331 | return null; | 329 | return null; |
332 | } | 330 | } |
333 | else | 331 | else |
334 | { | 332 | { |
335 | if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, coords, faces)) | 333 | if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces)) |
336 | return null; | 334 | return null; |
337 | } | 335 | } |
338 | } | 336 | } |
339 | else | 337 | else |
340 | { | 338 | { |
341 | float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; | 339 | if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, out coords, out faces)) |
342 | float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; | 340 | return null; |
343 | float pathBegin = (float)primShape.PathBegin * 2.0e-5f; | ||
344 | float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f; | ||
345 | float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f; | ||
346 | float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f; | ||
347 | |||
348 | float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; | ||
349 | float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; | ||
350 | float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; | ||
351 | if (profileHollow > 0.95f) | ||
352 | profileHollow = 0.95f; | ||
353 | |||
354 | int sides = 4; | ||
355 | if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) | ||
356 | sides = 3; | ||
357 | else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) | ||
358 | sides = 24; | ||
359 | else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) | ||
360 | { // half circle, prim is a sphere | ||
361 | sides = 24; | ||
362 | |||
363 | profileBegin = 0.5f * profileBegin + 0.5f; | ||
364 | profileEnd = 0.5f * profileEnd + 0.5f; | ||
365 | } | ||
366 | |||
367 | int hollowSides = sides; | ||
368 | if (primShape.HollowShape == HollowShape.Circle) | ||
369 | hollowSides = 24; | ||
370 | else if (primShape.HollowShape == HollowShape.Square) | ||
371 | hollowSides = 4; | ||
372 | else if (primShape.HollowShape == HollowShape.Triangle) | ||
373 | hollowSides = 3; | ||
374 | |||
375 | primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); | ||
376 | |||
377 | if (primMesh.errorMessage != null) | ||
378 | if (primMesh.errorMessage.Length > 0) | ||
379 | m_log.Error("[ERROR] " + primMesh.errorMessage); | ||
380 | |||
381 | primMesh.topShearX = pathShearX; | ||
382 | primMesh.topShearY = pathShearY; | ||
383 | primMesh.pathCutBegin = pathBegin; | ||
384 | primMesh.pathCutEnd = pathEnd; | ||
385 | |||
386 | if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) | ||
387 | { | ||
388 | primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; | ||
389 | primMesh.twistEnd = primShape.PathTwist * 18 / 10; | ||
390 | primMesh.taperX = pathScaleX; | ||
391 | primMesh.taperY = pathScaleY; | ||
392 | |||
393 | if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) | ||
394 | { | ||
395 | ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); | ||
396 | if (profileBegin < 0.0f) profileBegin = 0.0f; | ||
397 | if (profileEnd > 1.0f) profileEnd = 1.0f; | ||
398 | } | ||
399 | #if SPAM | ||
400 | m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); | ||
401 | #endif | ||
402 | try | ||
403 | { | ||
404 | primMesh.ExtrudeLinear(); | ||
405 | } | ||
406 | catch (Exception ex) | ||
407 | { | ||
408 | ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); | ||
409 | return null; | ||
410 | } | ||
411 | } | ||
412 | else | ||
413 | { | ||
414 | primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; | ||
415 | primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; | ||
416 | primMesh.radius = 0.01f * primShape.PathRadiusOffset; | ||
417 | primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; | ||
418 | primMesh.skew = 0.01f * primShape.PathSkew; | ||
419 | primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; | ||
420 | primMesh.twistEnd = primShape.PathTwist * 36 / 10; | ||
421 | primMesh.taperX = primShape.PathTaperX * 0.01f; | ||
422 | primMesh.taperY = primShape.PathTaperY * 0.01f; | ||
423 | |||
424 | if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) | ||
425 | { | ||
426 | ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); | ||
427 | if (profileBegin < 0.0f) profileBegin = 0.0f; | ||
428 | if (profileEnd > 1.0f) profileEnd = 1.0f; | ||
429 | } | ||
430 | #if SPAM | ||
431 | m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); | ||
432 | #endif | ||
433 | try | ||
434 | { | ||
435 | primMesh.ExtrudeCircular(); | ||
436 | } | ||
437 | catch (Exception ex) | ||
438 | { | ||
439 | ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); | ||
440 | return null; | ||
441 | } | ||
442 | } | ||
443 | |||
444 | primMesh.DumpRaw(baseDir, primName, "primMesh"); | ||
445 | |||
446 | primMesh.Scale(size.X, size.Y, size.Z); | ||
447 | |||
448 | coords = primMesh.coords; | ||
449 | faces = primMesh.faces; | ||
450 | } | 341 | } |
451 | 342 | ||
452 | // Remove the reference to any JPEG2000 sculpt data so it can be GCed | 343 | // Remove the reference to any JPEG2000 sculpt data so it can be GCed |
@@ -484,10 +375,12 @@ namespace OpenSim.Region.Physics.Meshing | |||
484 | /// <param name="faces">Faces are added to this list by the method.</param> | 375 | /// <param name="faces">Faces are added to this list by the method.</param> |
485 | /// <returns>true if coords and faces were successfully generated, false if not</returns> | 376 | /// <returns>true if coords and faces were successfully generated, false if not</returns> |
486 | private bool GenerateCoordsAndFacesFromPrimMeshData( | 377 | private bool GenerateCoordsAndFacesFromPrimMeshData( |
487 | string primName, PrimitiveBaseShape primShape, Vector3 size, List<Coord> coords, List<Face> faces) | 378 | string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces) |
488 | { | 379 | { |
489 | m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); | 380 | m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); |
490 | 381 | ||
382 | coords = new List<Coord>(); | ||
383 | faces = new List<Face>(); | ||
491 | OSD meshOsd = null; | 384 | OSD meshOsd = null; |
492 | 385 | ||
493 | if (primShape.SculptData.Length <= 0) | 386 | if (primShape.SculptData.Length <= 0) |
@@ -603,8 +496,10 @@ namespace OpenSim.Region.Physics.Meshing | |||
603 | /// <param name="faces">Faces are added to this list by the method.</param> | 496 | /// <param name="faces">Faces are added to this list by the method.</param> |
604 | /// <returns>true if coords and faces were successfully generated, false if not</returns> | 497 | /// <returns>true if coords and faces were successfully generated, false if not</returns> |
605 | private bool GenerateCoordsAndFacesFromPrimSculptData( | 498 | private bool GenerateCoordsAndFacesFromPrimSculptData( |
606 | string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, List<Coord> coords, List<Face> faces) | 499 | string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces) |
607 | { | 500 | { |
501 | coords = new List<Coord>(); | ||
502 | faces = new List<Face>(); | ||
608 | PrimMesher.SculptMesh sculptMesh; | 503 | PrimMesher.SculptMesh sculptMesh; |
609 | Image idata = null; | 504 | Image idata = null; |
610 | string decodedSculptFileName = ""; | 505 | string decodedSculptFileName = ""; |
@@ -711,6 +606,135 @@ namespace OpenSim.Region.Physics.Meshing | |||
711 | return true; | 606 | return true; |
712 | } | 607 | } |
713 | 608 | ||
609 | /// <summary> | ||
610 | /// Generate the co-ords and faces necessary to construct a mesh from the shape data the accompanies a prim. | ||
611 | /// </summary> | ||
612 | /// <param name="primName"></param> | ||
613 | /// <param name="primShape"></param> | ||
614 | /// <param name="size"></param> | ||
615 | /// <param name="coords">Coords are added to this list by the method.</param> | ||
616 | /// <param name="faces">Faces are added to this list by the method.</param> | ||
617 | /// <returns>true if coords and faces were successfully generated, false if not</returns> | ||
618 | private bool GenerateCoordsAndFacesFromPrimShapeData( | ||
619 | string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces) | ||
620 | { | ||
621 | PrimMesh primMesh; | ||
622 | coords = new List<Coord>(); | ||
623 | faces = new List<Face>(); | ||
624 | |||
625 | float pathShearX = primShape.PathShearX < 128 ? (float)primShape.PathShearX * 0.01f : (float)(primShape.PathShearX - 256) * 0.01f; | ||
626 | float pathShearY = primShape.PathShearY < 128 ? (float)primShape.PathShearY * 0.01f : (float)(primShape.PathShearY - 256) * 0.01f; | ||
627 | float pathBegin = (float)primShape.PathBegin * 2.0e-5f; | ||
628 | float pathEnd = 1.0f - (float)primShape.PathEnd * 2.0e-5f; | ||
629 | float pathScaleX = (float)(primShape.PathScaleX - 100) * 0.01f; | ||
630 | float pathScaleY = (float)(primShape.PathScaleY - 100) * 0.01f; | ||
631 | |||
632 | float profileBegin = (float)primShape.ProfileBegin * 2.0e-5f; | ||
633 | float profileEnd = 1.0f - (float)primShape.ProfileEnd * 2.0e-5f; | ||
634 | float profileHollow = (float)primShape.ProfileHollow * 2.0e-5f; | ||
635 | if (profileHollow > 0.95f) | ||
636 | profileHollow = 0.95f; | ||
637 | |||
638 | int sides = 4; | ||
639 | if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) | ||
640 | sides = 3; | ||
641 | else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) | ||
642 | sides = 24; | ||
643 | else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) | ||
644 | { // half circle, prim is a sphere | ||
645 | sides = 24; | ||
646 | |||
647 | profileBegin = 0.5f * profileBegin + 0.5f; | ||
648 | profileEnd = 0.5f * profileEnd + 0.5f; | ||
649 | } | ||
650 | |||
651 | int hollowSides = sides; | ||
652 | if (primShape.HollowShape == HollowShape.Circle) | ||
653 | hollowSides = 24; | ||
654 | else if (primShape.HollowShape == HollowShape.Square) | ||
655 | hollowSides = 4; | ||
656 | else if (primShape.HollowShape == HollowShape.Triangle) | ||
657 | hollowSides = 3; | ||
658 | |||
659 | primMesh = new PrimMesh(sides, profileBegin, profileEnd, profileHollow, hollowSides); | ||
660 | |||
661 | if (primMesh.errorMessage != null) | ||
662 | if (primMesh.errorMessage.Length > 0) | ||
663 | m_log.Error("[ERROR] " + primMesh.errorMessage); | ||
664 | |||
665 | primMesh.topShearX = pathShearX; | ||
666 | primMesh.topShearY = pathShearY; | ||
667 | primMesh.pathCutBegin = pathBegin; | ||
668 | primMesh.pathCutEnd = pathEnd; | ||
669 | |||
670 | if (primShape.PathCurve == (byte)Extrusion.Straight || primShape.PathCurve == (byte) Extrusion.Flexible) | ||
671 | { | ||
672 | primMesh.twistBegin = primShape.PathTwistBegin * 18 / 10; | ||
673 | primMesh.twistEnd = primShape.PathTwist * 18 / 10; | ||
674 | primMesh.taperX = pathScaleX; | ||
675 | primMesh.taperY = pathScaleY; | ||
676 | |||
677 | if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) | ||
678 | { | ||
679 | ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); | ||
680 | if (profileBegin < 0.0f) profileBegin = 0.0f; | ||
681 | if (profileEnd > 1.0f) profileEnd = 1.0f; | ||
682 | } | ||
683 | #if SPAM | ||
684 | m_log.Debug("****** PrimMesh Parameters (Linear) ******\n" + primMesh.ParamsToDisplayString()); | ||
685 | #endif | ||
686 | try | ||
687 | { | ||
688 | primMesh.ExtrudeLinear(); | ||
689 | } | ||
690 | catch (Exception ex) | ||
691 | { | ||
692 | ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); | ||
693 | return false; | ||
694 | } | ||
695 | } | ||
696 | else | ||
697 | { | ||
698 | primMesh.holeSizeX = (200 - primShape.PathScaleX) * 0.01f; | ||
699 | primMesh.holeSizeY = (200 - primShape.PathScaleY) * 0.01f; | ||
700 | primMesh.radius = 0.01f * primShape.PathRadiusOffset; | ||
701 | primMesh.revolutions = 1.0f + 0.015f * primShape.PathRevolutions; | ||
702 | primMesh.skew = 0.01f * primShape.PathSkew; | ||
703 | primMesh.twistBegin = primShape.PathTwistBegin * 36 / 10; | ||
704 | primMesh.twistEnd = primShape.PathTwist * 36 / 10; | ||
705 | primMesh.taperX = primShape.PathTaperX * 0.01f; | ||
706 | primMesh.taperY = primShape.PathTaperY * 0.01f; | ||
707 | |||
708 | if (profileBegin < 0.0f || profileBegin >= profileEnd || profileEnd > 1.0f) | ||
709 | { | ||
710 | ReportPrimError("*** CORRUPT PRIM!! ***", primName, primMesh); | ||
711 | if (profileBegin < 0.0f) profileBegin = 0.0f; | ||
712 | if (profileEnd > 1.0f) profileEnd = 1.0f; | ||
713 | } | ||
714 | #if SPAM | ||
715 | m_log.Debug("****** PrimMesh Parameters (Circular) ******\n" + primMesh.ParamsToDisplayString()); | ||
716 | #endif | ||
717 | try | ||
718 | { | ||
719 | primMesh.ExtrudeCircular(); | ||
720 | } | ||
721 | catch (Exception ex) | ||
722 | { | ||
723 | ReportPrimError("Extrusion failure: exception: " + ex.ToString(), primName, primMesh); | ||
724 | return false; | ||
725 | } | ||
726 | } | ||
727 | |||
728 | primMesh.DumpRaw(baseDir, primName, "primMesh"); | ||
729 | |||
730 | primMesh.Scale(size.X, size.Y, size.Z); | ||
731 | |||
732 | coords = primMesh.coords; | ||
733 | faces = primMesh.faces; | ||
734 | |||
735 | return true; | ||
736 | } | ||
737 | |||
714 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 738 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
715 | { | 739 | { |
716 | return CreateMesh(primName, primShape, size, lod, false); | 740 | return CreateMesh(primName, primShape, size, lod, false); |