static Vector3?GetPointAtPosition(Vector2 mousePosition, Rect dragArea) { UnitySceneExtensions.Grid.HoverGrid = null; if (s_CurrentPointIndex == 0) { s_StartIntersection = ChiselClickSelectionManager.GetPlaneIntersection(mousePosition, dragArea); if (s_StartIntersection != null) { // TODO: try to cache this .. var activeGridUp = UnitySceneExtensions.Grid.ActiveGrid.Up; var activeGridForward = UnitySceneExtensions.Grid.ActiveGrid.Forward; var activeGridCenter = UnitySceneExtensions.Grid.ActiveGrid.Center; var surfaceGridPlane = s_StartIntersection.plane; var surfaceGridUp = surfaceGridPlane.normal; var surfaceGridForward = MathExtensions.CalculateTangent(surfaceGridUp); // Q: why if this is not negated, we end up-side-down? var activeGridFromWorldRotation = Quaternion.LookRotation(activeGridForward, activeGridUp); var worldFromActiveGridRotation = Quaternion.Inverse(activeGridFromWorldRotation); var surfaceGridFromWorldRotation = Quaternion.LookRotation(surfaceGridForward, surfaceGridUp); var activeGridToSurfaceGridRotation = surfaceGridFromWorldRotation * worldFromActiveGridRotation; // Make sure the center of the new grid is as close to the active grid center as possible Vector3 surfaceGridCenter = activeGridCenter; var forwardRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.up); var backRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.down); var leftRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.left); var rightRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.right); var upRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.forward); var downRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.back); var bestDist = float.PositiveInfinity; float dist; if (surfaceGridPlane.UnsignedRaycast(forwardRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = forwardRay.GetPoint(dist); } } if (surfaceGridPlane.UnsignedRaycast(backRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = backRay.GetPoint(dist); } } if (surfaceGridPlane.UnsignedRaycast(leftRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = leftRay.GetPoint(dist); } } if (surfaceGridPlane.UnsignedRaycast(rightRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = rightRay.GetPoint(dist); } } if (bestDist > 100000) // prefer rays on the active-grid, only go up/down from the active-grid when we have no other choice { if (surfaceGridPlane.UnsignedRaycast(upRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = upRay.GetPoint(dist); } } if (surfaceGridPlane.UnsignedRaycast(downRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = downRay.GetPoint(dist); } } } // TODO: try to snap the new surface grid point in other directions on the active-grid? (do we need to?) s_Transform = Matrix4x4.TRS(surfaceGridCenter - activeGridCenter, activeGridToSurfaceGridRotation, Vector3.one) * UnitySceneExtensions.Grid.ActiveGrid.GridToWorldSpace; s_InvTransform = s_Transform.inverse; s_Snapping2D.Initialize(new UnitySceneExtensions.Grid(s_Transform), mousePosition, s_StartIntersection.point, UnityEditor.Handles.matrix); } } if (s_StartIntersection != null) { if (s_Snapping2D.DragTo(mousePosition, SnappingMode.Always)) { UnitySceneExtensions.Grid.HoverGrid = s_Snapping2D.WorldSlideGrid; return(s_Snapping2D.WorldSnappedPosition); } } return(null); }