public static void RenderCrossXZ(Extents3D extents, float y, Vector3 handleOrigin, SnapResult3D snapResult)
        {
            if ((snapResult & SnapResult3D.MinX) != 0)
            {
                InfiniteLine(extents.min.x, y, handleOrigin.z, Axis.Z);
            }
            if ((snapResult & SnapResult3D.MaxX) != 0)
            {
                InfiniteLine(extents.max.x, y, handleOrigin.z, Axis.Z);
            }

            if ((snapResult & SnapResult3D.MinZ) != 0)
            {
                InfiniteLine(handleOrigin.x, y, extents.min.z, Axis.X);
            }
            if ((snapResult & SnapResult3D.MaxZ) != 0)
            {
                InfiniteLine(handleOrigin.x, y, extents.max.z, Axis.X);
            }

            if ((snapResult & SnapResult3D.PivotX) != 0)
            {
                InfiniteLine(handleOrigin.x, y, handleOrigin.z, Axis.Z);
            }
            if ((snapResult & SnapResult3D.PivotZ) != 0)
            {
                InfiniteLine(handleOrigin.x, y, handleOrigin.z, Axis.X);
            }
        }
 public static void RenderBox(Extents3D extents)
 {
     RenderSquareXZ(extents, extents.min.y);
     if (extents.min.y != extents.max.y)
     {
         RenderSquareXZ(extents, extents.max.y);
     }
 }
        public static void RenderSquareXZ(Extents3D extents, float y)
        {
            var v0 = new Vector3(extents.min.x, y, extents.min.z);
            var v1 = new Vector3(extents.min.x, y, extents.max.z);
            var v2 = new Vector3(extents.max.x, y, extents.max.z);
            var v3 = new Vector3(extents.max.x, y, extents.min.z);

            SceneHandles.DrawDottedLine(v0, v1, 1.0f);
            SceneHandles.DrawDottedLine(v1, v2, 1.0f);
            SceneHandles.DrawDottedLine(v2, v3, 1.0f);
            SceneHandles.DrawDottedLine(v3, v0, 1.0f);
        }
Beispiel #4
0
        public void Reset()
        {
            startWorldPlanePosition = Vector3.zero;
            worldSlidePlane         = new Plane(Vector3.up, 0);
            worldSlideGrid          = null;

            gridSlideExtents = new Extents3D(Vector3.zero);
            worldSlideOrigin = Vector3.zero;

            worldSlidePosition   = Vector3.zero;
            worldSnappedPosition = Vector3.zero;

            localToWorldMatrix = Matrix4x4.identity;

            snapResult = SnapResult3D.None;
        }
        public void Reset()
        {
            startWorldPlanePosition = Vector3.zero;
            worldSlidePlane         = new Plane(Vector3.up, 0);
            vectorX        = Vector3.right;
            vectorZ        = Vector3.forward;
            worldSlideGrid = null;

            gridSlideExtents = new Extents3D(Vector3.zero);
            worldSlideOrigin = Vector3.zero;

            worldSlidePosition   = Vector3.zero;
            worldSnappedPosition = Vector3.zero;

            localToWorldMatrix = Matrix4x4.identity;

            snapResult = SnapResult3D.None;
#if ENABLE_DEBUG_GRID
            Grid.debugGrid = null;
#endif
        }
Beispiel #6
0
 public void CalculateExtents(Vector3[] localPoints)
 {
     this.gridSlideExtents = this.worldSlideGrid.GetGridExtentsOfPointArray(localToWorldMatrix, localPoints);
 }
        public Vector3 SnapExtents3D(Extents3D extentsInGridSpace, Vector3 worldCurrentPosition, Vector3 worldStartPosition, out SnapResult3D snapResult, Axes enabledAxes = Axes.XYZ, bool ignoreStartPoint = false)
        {
            snapResult = SnapResult3D.None;
            if (!Snapping.BoundsSnappingActive && !Snapping.PivotSnappingActive)
            {
                return(worldCurrentPosition);
            }

            var offsetInWorldSpace = worldCurrentPosition - worldStartPosition;
            var offsetInGridSpace  = _worldToGridSpace.MultiplyVector(offsetInWorldSpace);
            var pivotInGridSpace   = _worldToGridSpace.MultiplyVector(worldCurrentPosition - Center);

            // Snap our extents in grid space
            var movedExtentsInGridspace = extentsInGridSpace + offsetInGridSpace;

            if ((enabledAxes & Axes.X) > 0)
            {
                var snappedPivot      = SnappingUtility.SnapValue(pivotInGridSpace.x, _spacing.x) - pivotInGridSpace.x;
                var snappedMinExtents = SnappingUtility.SnapValue(movedExtentsInGridspace.min.x, _spacing.x) - movedExtentsInGridspace.min.x;
                var snappedMaxExtents = SnappingUtility.SnapValue(movedExtentsInGridspace.max.x, _spacing.x) - movedExtentsInGridspace.max.x;

                // Figure out on which side of the extents is closest to the grid, use that offset for each axis
                var abs_pivot       = Snapping.PivotSnappingActive  ? SnappingUtility.Quantize(Mathf.Abs(snappedPivot)) : float.PositiveInfinity;
                var abs_min_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedMinExtents)) : float.PositiveInfinity;
                var abs_max_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedMaxExtents)) : float.PositiveInfinity;
                offsetInGridSpace.x += (abs_pivot < abs_min_extents && abs_pivot < abs_max_extents) ? snappedPivot : ((abs_min_extents < abs_max_extents) ? snappedMinExtents : snappedMaxExtents);
                if (abs_min_extents <= abs_max_extents && abs_min_extents <= abs_pivot)
                {
                    snapResult |= SnapResult3D.MinX;
                }
                if (abs_max_extents <= abs_min_extents && abs_max_extents <= abs_pivot)
                {
                    snapResult |= SnapResult3D.MaxX;
                }
                if (abs_pivot <= abs_min_extents && abs_pivot <= abs_max_extents)
                {
                    snapResult |= SnapResult3D.PivotX;
                }
            }

            if ((enabledAxes & Axes.Y) > 0)
            {
                var snappedPivot      = SnappingUtility.SnapValue(pivotInGridSpace.y, _spacing.y) - pivotInGridSpace.y;
                var snappedMinExtents = SnappingUtility.SnapValue(movedExtentsInGridspace.min.y, _spacing.y) - movedExtentsInGridspace.min.y;
                var snappedMaxExtents = SnappingUtility.SnapValue(movedExtentsInGridspace.max.y, _spacing.y) - movedExtentsInGridspace.max.y;

                // Figure out on which side of the extents is closest to the grid, use that offset for each axis
                var abs_pivot       = Snapping.PivotSnappingActive  ? SnappingUtility.Quantize(Mathf.Abs(snappedPivot)) : float.PositiveInfinity;
                var abs_min_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedMinExtents)) : float.PositiveInfinity;
                var abs_max_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedMaxExtents)) : float.PositiveInfinity;
                offsetInGridSpace.y += (abs_pivot < abs_min_extents && abs_pivot < abs_max_extents) ? snappedPivot : ((abs_min_extents < abs_max_extents) ? snappedMinExtents : snappedMaxExtents);
                if (abs_min_extents <= abs_max_extents && abs_min_extents <= abs_pivot)
                {
                    snapResult |= SnapResult3D.MinY;
                }
                if (abs_max_extents <= abs_min_extents && abs_max_extents <= abs_pivot)
                {
                    snapResult |= SnapResult3D.MaxY;
                }
                if (abs_pivot <= abs_min_extents && abs_pivot <= abs_max_extents)
                {
                    snapResult |= SnapResult3D.PivotY;
                }
            }

            if ((enabledAxes & Axes.Z) > 0)
            {
                var snappedPivot      = SnappingUtility.SnapValue(pivotInGridSpace.z, _spacing.z) - pivotInGridSpace.z;
                var snappedMinExtents = SnappingUtility.SnapValue(movedExtentsInGridspace.min.z, _spacing.z) - movedExtentsInGridspace.min.z;
                var snappedMaxExtents = SnappingUtility.SnapValue(movedExtentsInGridspace.max.z, _spacing.z) - movedExtentsInGridspace.max.z;

                // Figure out on which side of the extents is closest to the grid, use that offset for each axis
                var abs_pivot       = Snapping.PivotSnappingActive  ? SnappingUtility.Quantize(Mathf.Abs(snappedPivot)) : float.PositiveInfinity;
                var abs_min_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedMinExtents)) : float.PositiveInfinity;
                var abs_max_extents = Snapping.BoundsSnappingActive ? SnappingUtility.Quantize(Mathf.Abs(snappedMaxExtents)) : float.PositiveInfinity;
                offsetInGridSpace.z += (abs_pivot < abs_min_extents && abs_pivot < abs_max_extents) ? snappedPivot : ((abs_min_extents < abs_max_extents) ? snappedMinExtents : snappedMaxExtents);
                if (abs_min_extents <= abs_max_extents && abs_min_extents <= abs_pivot)
                {
                    snapResult |= SnapResult3D.MinZ;
                }
                if (abs_max_extents <= abs_min_extents && abs_max_extents <= abs_pivot)
                {
                    snapResult |= SnapResult3D.MaxZ;
                }
                if (abs_pivot <= abs_min_extents && abs_pivot <= abs_max_extents)
                {
                    snapResult |= SnapResult3D.PivotZ;
                }
            }



            var snappedOffsetInWorldSpace   = _gridToWorldSpace.MultiplyVector(offsetInGridSpace);
            var snappedPositionInWorldSpace = (worldStartPosition + snappedOffsetInWorldSpace);

            if (!ignoreStartPoint)
            {
                if (Mathf.Abs(worldCurrentPosition.x - snappedPositionInWorldSpace.x) > Mathf.Abs(offsetInWorldSpace.x))
                {
                    snappedPositionInWorldSpace.x = worldStartPosition.x;
                }
                if (Mathf.Abs(worldCurrentPosition.y - snappedPositionInWorldSpace.y) > Mathf.Abs(offsetInWorldSpace.y))
                {
                    snappedPositionInWorldSpace.y = worldStartPosition.y;
                }
                if (Mathf.Abs(worldCurrentPosition.z - snappedPositionInWorldSpace.z) > Mathf.Abs(offsetInWorldSpace.z))
                {
                    snappedPositionInWorldSpace.z = worldStartPosition.z;
                }
            }

            return(snappedPositionInWorldSpace);
        }
        public Vector3 SnapExtents3D(Extents3D extentsInGridSpace, Vector3 worldCurrentPosition, Vector3 worldStartPosition, Axes enabledAxes = Axes.XYZ)
        {
            SnapResult3D result;

            return(SnapExtents3D(extentsInGridSpace, worldCurrentPosition, worldStartPosition, out result, enabledAxes));
        }
        public static void RenderSnapping3D(Grid grid, Extents3D extents, Vector3 pivotPosition, SnapResult3D snapResult, bool ignorePivot = false)
        {
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }
            using (new SceneHandles.DrawingScope(grid.GridToWorldSpace))
            {
                if (extents.min.x == extents.max.x && (snapResult & SnapResult3D.MinX) != 0)
                {
                    snapResult &= ~SnapResult3D.MaxX;
                }
                if (extents.min.y == extents.max.y && (snapResult & SnapResult3D.MinY) != 0)
                {
                    snapResult &= ~SnapResult3D.MaxY;
                }
                if (extents.min.z == extents.max.z && (snapResult & SnapResult3D.MinZ) != 0)
                {
                    snapResult &= ~SnapResult3D.MaxZ;
                }

                if (ignorePivot)
                {
                    snapResult &= ~SnapResult3D.PivotX;
                    snapResult &= ~SnapResult3D.PivotY;
                    snapResult &= ~SnapResult3D.PivotZ;
                }
                else
                {
                    if (extents.min.x == pivotPosition.x && (snapResult & SnapResult3D.MinX) != 0)
                    {
                        snapResult &= ~SnapResult3D.PivotX;
                    }
                    if (extents.min.y == pivotPosition.y && (snapResult & SnapResult3D.MinY) != 0)
                    {
                        snapResult &= ~SnapResult3D.PivotY;
                    }
                    if (extents.min.z == pivotPosition.z && (snapResult & SnapResult3D.MinZ) != 0)
                    {
                        snapResult &= ~SnapResult3D.PivotZ;
                    }

                    if (extents.max.x == pivotPosition.x && (snapResult & SnapResult3D.MaxX) != 0)
                    {
                        snapResult &= ~SnapResult3D.PivotX;
                    }
                    if (extents.max.y == pivotPosition.y && (snapResult & SnapResult3D.MaxY) != 0)
                    {
                        snapResult &= ~SnapResult3D.PivotY;
                    }
                    if (extents.max.z == pivotPosition.z && (snapResult & SnapResult3D.MaxZ) != 0)
                    {
                        snapResult &= ~SnapResult3D.PivotZ;
                    }
                }

                float y = 0;
                if (extents.min.y > 0)
                {
                    y = extents.min.y;
                }
                else if (extents.max.y < 0)
                {
                    y = extents.max.y;
                }
                RenderCrossXZ(extents, y, pivotPosition, snapResult);
                RenderBox(extents);

                var color = SceneHandles.color;
                color.a           *= 0.5f;
                SceneHandles.color = color;

                if (y != 0)
                {
                    RenderSquareXZ(extents, 0);

                    if ((snapResult & SnapResult3D.MinX) != 0)
                    {
                        var center = new Vector3(extents.min.x, y, pivotPosition.z);
                        if ((snapResult & SnapResult3D.MinZ) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.min.z), new Vector3(center.x, center.y, extents.min.z), 4.0f);
                        }
                        if ((snapResult & SnapResult3D.MaxZ) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.max.z), new Vector3(center.x, center.y, extents.max.z), 4.0f);
                        }
                    }
                    if ((snapResult & SnapResult3D.MinZ) != 0)
                    {
                        var center = new Vector3(pivotPosition.x, y, extents.min.z);
                        if ((snapResult & SnapResult3D.MinX) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(extents.min.x, 0, center.z), new Vector3(extents.min.x, center.y, center.z), 4.0f);
                        }
                        if ((snapResult & SnapResult3D.MaxX) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(extents.max.x, 0, center.z), new Vector3(extents.max.x, center.y, center.z), 4.0f);
                        }
                    }

                    if ((snapResult & SnapResult3D.MaxX) != 0)
                    {
                        var center = new Vector3(extents.max.x, y, pivotPosition.z);
                        if ((snapResult & SnapResult3D.MinZ) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.min.z), new Vector3(center.x, center.y, extents.min.z), 4.0f);
                        }
                        if ((snapResult & SnapResult3D.MaxZ) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(center.x, 0, extents.max.z), new Vector3(center.x, center.y, extents.max.z), 4.0f);
                        }
                    }
                    if ((snapResult & SnapResult3D.MaxZ) != 0)
                    {
                        var center = new Vector3(pivotPosition.x, y, extents.max.z);
                        if ((snapResult & SnapResult3D.MinX) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(extents.min.x, 0, center.z), new Vector3(extents.min.x, center.y, center.z), 4.0f);
                        }
                        if ((snapResult & SnapResult3D.MaxX) != 0)
                        {
                            SceneHandles.DrawDottedLine(new Vector3(extents.max.x, 0, center.z), new Vector3(extents.max.x, center.y, center.z), 4.0f);
                        }
                    }
                }
            }
        }
 public static void RenderSnapping3D(Grid grid, Extents3D extents, SnapResult3D snapResult)
 {
     RenderSnapping3D(grid, extents, extents.min, snapResult, true);
 }
        public Vector3 SnapExtents3D(Extents3D extentsInGridSpace, Vector3 worldCurrentPosition, Vector3 worldStartPosition, Grid worldSlideGrid, out SnapResult3D snapResult, Axes enabledAxes = Axes.XYZ, bool ignoreStartPoint = false)
        {
            s_CustomSnapPoints.Clear();
            // TODO: have a method that handles multiple dimensions at the same time
            var haveCustomSnapping = Snapping.GetCustomSnappingPoints(worldStartPosition, worldCurrentPosition, worldSlideGrid, 0, s_CustomSnapPoints);

            var boundsActive = Snapping.BoundsSnappingActive;
            var pivotActive  = Snapping.PivotSnappingActive;

            snapResult = SnapResult3D.None;
            if (!boundsActive && !pivotActive && !haveCustomSnapping)
            {
                return(worldCurrentPosition);
            }

            const float kMinPointSnap = 0.25f;
            float       minPointSnap  = !(boundsActive || pivotActive) ? kMinPointSnap : float.PositiveInfinity;


            var offsetInWorldSpace = worldCurrentPosition - worldStartPosition;
            var offsetInGridSpace  = _worldToGridSpace.MultiplyVector(offsetInWorldSpace);
            var pivotInGridSpace   = _worldToGridSpace.MultiplyVector(worldCurrentPosition - Center);

            // Snap our extents in grid space
            var movedExtentsInGridspace = extentsInGridSpace + offsetInGridSpace;


            var snappedOffset    = Vector3.zero;
            var absSnappedOffset = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);

            var enabledAxisLookup = new[] { (enabledAxes & Axes.X) > 0, (enabledAxes & Axes.Y) > 0, (enabledAxes & Axes.Z) > 0 };

            var quantized_pivot       = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
            var quantized_min_extents = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
            var quantized_max_extents = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);

            for (int i = 0; i < 3; i++)
            {
                if (!enabledAxisLookup[i])
                {
                    continue;
                }

                if (pivotActive)
                {
                    (float abs_pivot_offset, float snappedPivot, float quantized_offset) = Snapping.SnapPoint(pivotInGridSpace[i], _spacing[i]);
                    quantized_pivot[i] = quantized_offset;
                    if (absSnappedOffset[i] > abs_pivot_offset)
                    {
                        absSnappedOffset[i] = abs_pivot_offset; snappedOffset[i] = snappedPivot;
                    }
                }

                if (boundsActive)
                {
                    (float abs_bounds_distance, float snappedBoundsOffset, float quantized_min, float quantized_max) = Snapping.SnapBounds(movedExtentsInGridspace[i], _spacing[i]);
                    quantized_min_extents[i] = quantized_min;
                    quantized_max_extents[i] = quantized_max;

                    if (absSnappedOffset[i] > abs_bounds_distance)
                    {
                        absSnappedOffset[i] = abs_bounds_distance; snappedOffset[i] = snappedBoundsOffset;
                    }
                }
            }

            if (haveCustomSnapping)
            {
                (Vector3 abs_distance, Vector3 snappedCustomOffset) = Snapping.SnapCustom(s_CustomSnapPoints, pivotInGridSpace, enabledAxes, minPointSnap, s_CustomDistances);
                if (absSnappedOffset.sqrMagnitude > abs_distance.sqrMagnitude)
                {
                    absSnappedOffset = abs_distance; snappedOffset = snappedCustomOffset;
                }
            }

            // Snap against drag start position
            if (!ignoreStartPoint)
            {
                if (Mathf.Abs(snappedOffset.x) > Mathf.Abs(offsetInGridSpace.x))
                {
                    offsetInGridSpace.x = snappedOffset.x = 0;
                }
                if (Mathf.Abs(snappedOffset.y) > Mathf.Abs(offsetInGridSpace.y))
                {
                    offsetInGridSpace.y = snappedOffset.y = 0;
                }
                if (Mathf.Abs(snappedOffset.z) > Mathf.Abs(offsetInGridSpace.z))
                {
                    offsetInGridSpace.z = snappedOffset.z = 0;
                }
            }

            var quantizedOffset = new Vector3(SnappingUtility.Quantize(snappedOffset.x),
                                              SnappingUtility.Quantize(snappedOffset.y),
                                              SnappingUtility.Quantize(snappedOffset.z));

            // Figure out what kind of snapping visualization to show, this needs to be done afterwards since
            // while we're snapping each type of snap can override the next one.
            // Yet at the same time it's possible to snap with multiple snap-types at the same time.

            if (boundsActive)
            {
                if (quantized_min_extents.x == quantizedOffset.x)
                {
                    snapResult |= SnapResult3D.MinX;
                }
                if (quantized_max_extents.x == quantizedOffset.x)
                {
                    snapResult |= SnapResult3D.MaxX;
                }

                if (quantized_min_extents.y == quantizedOffset.y)
                {
                    snapResult |= SnapResult3D.MinY;
                }
                if (quantized_max_extents.y == quantizedOffset.y)
                {
                    snapResult |= SnapResult3D.MaxY;
                }

                if (quantized_min_extents.z == quantizedOffset.z)
                {
                    snapResult |= SnapResult3D.MinZ;
                }
                if (quantized_max_extents.z == quantizedOffset.z)
                {
                    snapResult |= SnapResult3D.MaxZ;
                }
            }

            if (pivotActive)
            {
                if (quantized_pivot.x == quantizedOffset.x)
                {
                    snapResult |= SnapResult3D.PivotX;
                }
                if (quantized_pivot.y == quantizedOffset.y)
                {
                    snapResult |= SnapResult3D.PivotY;
                }
                if (quantized_pivot.z == quantizedOffset.z)
                {
                    snapResult |= SnapResult3D.PivotZ;
                }
            }

            if (haveCustomSnapping)
            {
                Snapping.SendCustomSnappedEvents(quantizedOffset, s_CustomDistances, 0);
            }

            if (absSnappedOffset.x == 0 &&
                absSnappedOffset.y == 0 &&
                absSnappedOffset.z == 0)
            {
                return(worldStartPosition);
            }

            var snappedOffsetInWorldSpace   = _gridToWorldSpace.MultiplyVector(offsetInGridSpace - snappedOffset);
            var snappedPositionInWorldSpace = (worldStartPosition + snappedOffsetInWorldSpace);

            //Debug.Log($"{(float3)snappedOffsetInWorldSpace} {(float3)snappedOffset} {(float3)snappedPositionInWorldSpace}");

            return(snappedPositionInWorldSpace);
        }