Object2ObjectBoxSnapDataFactory.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #if UNITY_EDITOR
  2. using UnityEngine;
  3. using System;
  4. using System.Collections.Generic;
  5. namespace O3DWB
  6. {
  7. public static class Object2ObjectBoxSnapDataFactory
  8. {
  9. public static Object2ObjectBoxSnapData Create(GameObject meshObject)
  10. {
  11. if (meshObject == null) return null;
  12. Mesh objectMesh = meshObject.GetMeshFromFilterOrSkinnedMeshRenderer();
  13. if (objectMesh == null) return null;
  14. Renderer renderer = meshObject.GetRenderer();
  15. if (renderer == null || !renderer.enabled) return null;
  16. Octave3DMesh octaveMesh = Octave3DMeshDatabase.Get().GetOctave3DMesh(objectMesh);
  17. if (octaveMesh == null) return null;
  18. List<Box> modelVertOverlapBoxes = BuildModelVertOverlapBoxes(octaveMesh);
  19. var snapBoxIDs = Object2ObjectBoxSnapData.GetAllSnapBoxIDs();
  20. var modelSnapBoxes = new List<Box>(snapBoxIDs.Length);
  21. Box modelMeshBox = octaveMesh.ModelAABB;
  22. BoxFace[] meshBoxFaces = Object2ObjectBoxSnapData.GetBoxFaceToSnapBoxIDMap();
  23. foreach (var snapBox in snapBoxIDs)
  24. {
  25. Box overlapBox = modelVertOverlapBoxes[(int)snapBox];
  26. List<Vector3> overlappedVerts = octaveMesh.GetOverlappedModelVerts(overlapBox);
  27. Plane meshFacePlane = modelMeshBox.GetBoxFacePlane(meshBoxFaces[(int)snapBox]);
  28. overlappedVerts = meshFacePlane.ProjectAllPoints(overlappedVerts);
  29. modelSnapBoxes.Add(Box.FromPoints(overlappedVerts));
  30. }
  31. return new Object2ObjectBoxSnapData(meshObject, modelSnapBoxes);
  32. }
  33. private static List<Box> BuildModelVertOverlapBoxes(Octave3DMesh octaveMesh)
  34. {
  35. const float overlapAmount = 0.2f;
  36. float halfOverlapAmount = overlapAmount * 0.5f;
  37. Box modelMeshBox = octaveMesh.ModelAABB;
  38. Vector3 meshBoxSize = modelMeshBox.Size;
  39. BoxFace[] meshBoxFaces = Object2ObjectBoxSnapData.GetBoxFaceToSnapBoxIDMap();
  40. // Must have 1 to 1 mapping with Object2ObjectBoxSnapData.SnapBox enum
  41. const float sizeEps = 0.001f;
  42. Vector3[] overlapBoxSizes = new Vector3[]
  43. {
  44. // Left and right
  45. new Vector3(overlapAmount, meshBoxSize.y + sizeEps, meshBoxSize.z + sizeEps),
  46. new Vector3(overlapAmount, meshBoxSize.y + sizeEps, meshBoxSize.z + sizeEps),
  47. // Bottom and top
  48. new Vector3(meshBoxSize.x + sizeEps, overlapAmount, meshBoxSize.z + sizeEps),
  49. new Vector3(meshBoxSize.x + sizeEps, overlapAmount, meshBoxSize.z + sizeEps),
  50. // Back and front
  51. new Vector3(meshBoxSize.x + sizeEps, meshBoxSize.y + sizeEps, overlapAmount),
  52. new Vector3(meshBoxSize.x + sizeEps, meshBoxSize.y + sizeEps, overlapAmount),
  53. };
  54. var overlapBoxes = new List<Box>();
  55. for (int boxFaceIndex = 0; boxFaceIndex < meshBoxFaces.Length; ++boxFaceIndex)
  56. {
  57. BoxFace meshBoxFace = meshBoxFaces[boxFaceIndex];
  58. Vector3 faceCenter = modelMeshBox.GetBoxFaceCenter(meshBoxFace);
  59. Vector3 faceNormal = modelMeshBox.GetBoxFacePlane(meshBoxFace).normal;
  60. Vector3 overlapCenter = faceCenter - faceNormal * halfOverlapAmount;
  61. overlapBoxes.Add(new Box(overlapCenter, overlapBoxSizes[boxFaceIndex]));
  62. }
  63. return overlapBoxes;
  64. }
  65. }
  66. }
  67. #endif