Пример #1
0
        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.CalculateBinormal(surfaceGridUp);

                    var activeGridFromWorldRotation     = Quaternion.LookRotation(activeGridUp, activeGridForward);
                    var worldFromActiveGridRotation     = Quaternion.Inverse(activeGridFromWorldRotation);
                    var surfaceGridFromWorldRotation    = Quaternion.LookRotation(surfaceGridUp, surfaceGridForward);
                    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.SignedRaycast(forwardRay, out dist))
                    {
                        var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist)
                        {
                            bestDist = abs_dist; surfaceGridCenter = forwardRay.GetPoint(dist);
                        }
                    }
                    if (surfaceGridPlane.SignedRaycast(backRay, out dist))
                    {
                        var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist)
                        {
                            bestDist = abs_dist; surfaceGridCenter = backRay.GetPoint(dist);
                        }
                    }
                    if (surfaceGridPlane.SignedRaycast(leftRay, out dist))
                    {
                        var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist)
                        {
                            bestDist = abs_dist; surfaceGridCenter = leftRay.GetPoint(dist);
                        }
                    }
                    if (surfaceGridPlane.SignedRaycast(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.SignedRaycast(upRay, out dist))
                        {
                            var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist)
                            {
                                bestDist = abs_dist; surfaceGridCenter = upRay.GetPoint(dist);
                            }
                        }
                        if (surfaceGridPlane.SignedRaycast(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);
        }