public Object2ObjectSnapData GetObject2ObjectSnapData(GameObject gameObject) { if (_objectToSnapData.ContainsKey(gameObject)) { return(_objectToSnapData[gameObject]); } Object2ObjectSnapData snapData = new Object2ObjectSnapData(); if (!snapData.Initialize(gameObject)) { return(null); } _objectToSnapData.Add(gameObject, snapData); return(snapData); }
public static SnapResult CalculateSnapResult(GameObject root, Config snapConfig) { if (snapConfig.IgnoreDestObjects == null) { snapConfig.IgnoreDestObjects = new List <GameObject>(); } List <GameObject> sourceObjects = root.GetAllChildrenAndSelf(); if (sourceObjects.Count > MaxSourceObjects) { return(new SnapResult(SnapFailReson.MaxObjectsExceeded)); } List <GameObject> sourceMeshObjects = root.GetMeshObjectsInHierarchy(); List <GameObject> sourceSpriteObjects = root.GetSpriteObjectsInHierarchy(); if (sourceMeshObjects.Count == 0 && sourceSpriteObjects.Count == 0) { return(new SnapResult(SnapFailReson.InvalidSourceObjects)); } ObjectBounds.QueryConfig boundsQConfig = new ObjectBounds.QueryConfig(); boundsQConfig.ObjectTypes = GameObjectType.Mesh | GameObjectType.Sprite; Vector3 overlapSizeAdd = Vector3.one * snapConfig.SnapRadius * 2.0f; List <BoxFace> allSnapFaces = BoxMath.AllBoxFaces; bool tryMatchAreas = (snapConfig.Prefs & Prefs.TryMatchArea) != 0; bool foundMatchingAreas = false; List <SnapSortData> sortedSnapData = new List <SnapSortData>(10); SnapSortData sortData = new SnapSortData(); foreach (GameObject sourceObject in sourceObjects) { OBB overlapOBB = ObjectBounds.CalcWorldOBB(sourceObject, boundsQConfig); overlapOBB.Size = overlapOBB.Size + overlapSizeAdd; List <GameObject> nearbyObjects = RTScene.Get.OverlapBox(overlapOBB); nearbyObjects.RemoveAll(item => item.transform.IsChildOf(root.transform) || snapConfig.IgnoreDestObjects.Contains(item) || !LayerEx.IsLayerBitSet(snapConfig.DestinationLayers, item.layer)); if (nearbyObjects.Count == 0) { continue; } Object2ObjectSnapData sourceSnapData = Object2ObjectSnapDataDb.Get.GetObject2ObjectSnapData(sourceObject); if (sourceSnapData == null) { continue; } sortData.SrcObject = sourceObject; foreach (BoxFace srcSnapFace in allSnapFaces) { BoxFaceAreaDesc srcAreaDesc = sourceSnapData.GetWorldSnapAreaDesc(srcSnapFace); OBB srcAreaBounds = sourceSnapData.GetWorldSnapAreaBounds(srcSnapFace); List <Vector3> srcAreaPts = srcAreaBounds.GetCenterAndCornerPoints(); sortData.SrcSnapFace = srcSnapFace; foreach (GameObject destObject in nearbyObjects) { Object2ObjectSnapData destSnapData = Object2ObjectSnapDataDb.Get.GetObject2ObjectSnapData(destObject); if (destSnapData == null) { continue; } sortData.DestObject = destObject; foreach (BoxFace destSnapFace in allSnapFaces) { sortData.DestSnapFace = destSnapFace; BoxFaceAreaDesc destAreaDesc = destSnapData.GetWorldSnapAreaDesc(destSnapFace); sortData.FaceAreasMatch = false; if (tryMatchAreas && destAreaDesc.AreaType == srcAreaDesc.AreaType) { sortData.FaceAreaDiff = Mathf.Abs(destAreaDesc.Area - srcAreaDesc.Area); if (sortData.FaceAreaDiff <= 1000.0f) { sortData.FaceAreasMatch = true; } } OBB destAreaBounds = destSnapData.GetWorldSnapAreaBounds(destSnapFace); List <Vector3> destAreaPts = destAreaBounds.GetCenterAndCornerPoints(); foreach (Vector3 srcPt in srcAreaPts) { sortData.SnapPivot = srcPt; foreach (Vector3 destPt in destAreaPts) { sortData.SnapDistance = (destPt - srcPt).magnitude; if (sortData.SnapDistance < snapConfig.SnapRadius) { sortData.SnapDest = destPt; sortedSnapData.Add(sortData); if (sortData.FaceAreasMatch) { foundMatchingAreas = true; } } } } } } } } if (sortedSnapData.Count != 0) { if (!tryMatchAreas || !foundMatchingAreas) { sortedSnapData.Sort(delegate(SnapSortData s0, SnapSortData s1) { return(s0.SnapDistance.CompareTo(s1.SnapDistance)); }); } else { while (true) { if (!sortedSnapData[0].FaceAreasMatch) { sortedSnapData.RemoveAt(0); } else { break; } } sortedSnapData.Sort(delegate(SnapSortData s0, SnapSortData s1) { return(s0.FaceAreaDiff.CompareTo(s1.FaceAreaDiff)); }); } return(new SnapResult(sortedSnapData[0].SnapPivot, sortedSnapData[0].SnapDest, sortedSnapData[0].SnapDistance)); } return(new SnapResult(SnapFailReson.NoDestinationFound)); }