Beispiel #1
0
        public IFloodArea FetchWalkableFlood(Position center, int floodRange)
        {
            // performance: maybe we should keep a few last calculated results for center-floodRange pairs

            if (_cachedFloodArea == null)
            {
                _cachedFloodArea = new FloodArea(center, floodRange);
            }

            int expectedMatrixSize = floodRange * 2 + 1;

            if (_cachedFloodArea.ArraySize < expectedMatrixSize)
            {
                _cachedFloodArea.IncreaseMatrix(expectedMatrixSize);
            }

            if (_cachedFloodArea.Center != center)
            {
                _cachedFloodArea.Center = center;
                int boundsSize = floodRange * 2;
                _cachedFloodArea.Bounds = new Bounds(center.x - floodRange, center.y - floodRange, boundsSize, boundsSize);
            }

            var findHighestMark = new FindHighestMarkNeighbourProcessor();
            var parameters      = new FloodParameters(center.x, center.y)
            {
                Qualifier          = (x, y) => _grid.IsWalkable(new Position(x, y)),
                BoundsRestriction  = BoundsUtilities.ToFloodBounds(_cachedFloodArea.Bounds),
                NeighbourProcessor = findHighestMark.Process
            };
            Position furthestPosition = center;

            _floodSpiller.SpillFlood(parameters, _cachedFloodArea.ValueMatrix);
            _cachedFloodArea.FurthestPosition = furthestPosition;

            return(_cachedFloodArea);
        }
Beispiel #2
0
        public static void Flip(CSGBrush[] brushes, Matrix4x4 flipMatrix, string undoDescription = "Flip brushes")
        {
            var fail = false;

            Undo.IncrementCurrentGroup();
            Undo.RegisterCompleteObjectUndo(brushes.ToArray <UnityEngine.Object>(), undoDescription);

            var isGlobal = Tools.pivotRotation == PivotRotation.Global;

            var centerAll = BoundsUtilities.GetCenter(brushes);

            for (var t = 0; t < brushes.Length; t++)
            {
                var brush    = brushes[t];
                var position = brush.transform.position;

                Matrix4x4 brushFlip;
                Vector3   brushCenter;
                if (isGlobal)
                {
                    brushFlip = brush.transform.localToWorldMatrix *
                                flipMatrix *
                                brush.transform.worldToLocalMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll) - position;
                }
                else
                {
                    brushFlip   = flipMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll);
                }

                brushFlip = Matrix4x4.TRS(brushCenter, Quaternion.identity, Vector3.one) *
                            brushFlip *
                            Matrix4x4.TRS(-brushCenter, Quaternion.identity, Vector3.one);

                brush.EnsureInitialized();
                var shape = brush.Shape;
                for (var s = 0; s < shape.Surfaces.Length; s++)
                {
                    var plane = shape.Surfaces[s].Plane;

                    var normal   = brushFlip.MultiplyVector(plane.normal);
                    var biNormal = brushFlip.MultiplyVector(shape.Surfaces[s].BiNormal);
                    var tangent  = brushFlip.MultiplyVector(shape.Surfaces[s].Tangent);

                    var pointOnPlane = plane.pointOnPlane;
                    pointOnPlane = brushFlip.MultiplyPoint(pointOnPlane);

                    shape.Surfaces[s].Plane    = new CSGPlane(normal, pointOnPlane);
                    shape.Surfaces[s].BiNormal = biNormal;
                    shape.Surfaces[s].Tangent  = tangent;
                }

                var controlMesh = brush.ControlMesh;
                var vertices    = controlMesh.Vertices;
                for (var v = 0; v < vertices.Length; v++)
                {
                    vertices[v] = brushFlip.MultiplyPoint(vertices[v]);
                }

                var polygons = controlMesh.Polygons;
                for (var p = 0; p < polygons.Length; p++)
                {
                    Array.Reverse(polygons[p].EdgeIndices);
                }

                var edges        = controlMesh.Edges;
                var twinVertices = new short[edges.Length];
                for (var e = 0; e < edges.Length; e++)
                {
                    twinVertices[e] = edges[edges[e].TwinIndex].VertexIndex;
                }

                for (var e = 0; e < edges.Length; e++)
                {
                    edges[e].VertexIndex = twinVertices[e];
                }

                brush.ControlMesh.SetDirty();
                EditorUtility.SetDirty(brush);

                InternalCSGModelManager.CheckSurfaceModifications(brush, true);

                ControlMeshUtility.RebuildShape(brush);
            }
            if (fail)
            {
                Debug.LogWarning("Failed to perform operation");
                Undo.RevertAllInCurrentGroup();
            }
            InternalCSGModelManager.Refresh();
        }
    static bool GetFullBounds(GameObject go, out Bounds bounds, out Vector3 worldCenter)
    {
        bounds      = new Bounds();
        worldCenter = new Vector3();

        var rens = go.GetComponentsInChildren <Renderer>();

        if (rens.Length > 0)
        {
            for (int i = 0; i < rens.Length; i++)
            {
                if (i == 0)
                {
                    bounds = rens[i].bounds;
                }
                else
                {
                    bounds.Encapsulate(rens[i].bounds);
                }
            }
            worldCenter = bounds.center;
            return(true);
        }

        var cols = go.GetComponentsInChildren <Collider>();

        if (cols.Length > 0)
        {
            for (int i = 0; i < cols.Length; i++)
            {
                if (i == 0)
                {
                    bounds = cols[i].bounds;
                }
                else
                {
                    bounds.Encapsulate(cols[i].bounds);
                }
            }
            worldCenter = go.transform.TransformPoint(bounds.center);
            return(true);
        }

        var brush = go.GetComponent <CSGBrush>();

        if (brush)
        {
            var brushBounds = BoundsUtilities.GetBounds(brush);
            worldCenter = brushBounds.Center;
            bounds      = new Bounds()
            {
                center  = brushBounds.Center,
                extents = brushBounds.Size * .5f,
                max     = brushBounds.Max,
                min     = brushBounds.Min,
                size    = brushBounds.Size
            };
            return(true);
        }

        return(false);
    }
Beispiel #4
0
 private void Awake()
 {
     _boundsUtilities = GameObject.Find("Table").GetComponent <BoundsUtilities>();
 }
        internal static AABB Do(AABB bounds, Quaternion worldToLocalRotation, bool showEdgePoints = true)
        {
            for (int i = 0; i < sideControlIDs.Length; i++)
            {
                sideControlIDs[i] = GUIUtility.GetControlID(BoundsHash, FocusType.Passive);
            }

            for (int i = 0; i < edgeControlIDs.Length; i++)
            {
                edgeControlIDs[i] = GUIUtility.GetControlID(BoundsHash, FocusType.Passive);
            }

            UpdateColors(bounds, worldToLocalRotation, showEdgePoints);

            var evt = Event.current;

            switch (evt.type)
            {
            case EventType.Repaint:
            {
                Render(bounds, worldToLocalRotation, showEdgePoints);
                break;
            }
            }

            //var isStatic = (!Tools.hidden && EditorApplication.isPlaying && ContainsStatic(Selection.gameObjects));

            //var prevDisabled = CSGHandles.disabled;


            var localToWorldRotation = Quaternion.Inverse(worldToLocalRotation);
            var localToWorld         = Matrix4x4.TRS(Vector3.zero, localToWorldRotation, Vector3.one);

            var origMatrix = Handles.matrix;

            Handles.matrix = localToWorld;

            RealtimeCSG.Helpers.CSGHandles.InitFunction init = delegate
            {
                originalBounds = bounds;
            };
            RealtimeCSG.Helpers.CSGHandles.InitFunction shutdown = delegate
            {
                originalBounds = bounds;
            };

            var toggleSnapping = (Event.current.modifiers & EventModifiers.Control) == EventModifiers.Control;
            var doSnapping     = RealtimeCSG.CSGSettings.SnapToGrid ^ toggleSnapping;

            for (int i = 0; i < sidePoints.Length; i++)
            {
                Handles.color = sideColors[(i * 2) + 1];

                var position = sidePoints[i];
                var normal   = BoundsUtilities.AABBSideNormal[i];
                var size     = sideSizes[i];
                var id       = sideControlIDs[i];
                EditorGUI.BeginChangeCheck();
                position = CSGSlider1D.Do(id, position, normal, size, CSGHandles.HoverArrowHandleCap, doSnapping, null, init, shutdown);
                if (EditorGUI.EndChangeCheck())
                {
                    var originalPoint = BoundsUtilities.GetBoundsSidePoint(originalBounds, i);
                    bounds = originalBounds;

                    var delta = Vector3.Dot(normal, (position - originalPoint));
                    if (normal.x < 0)
                    {
                        bounds.MinX -= delta;
                    }
                    else if (normal.x > 0)
                    {
                        bounds.MaxX += delta;
                    }
                    else if (normal.y < 0)
                    {
                        bounds.MinY -= delta;
                    }
                    else if (normal.y > 0)
                    {
                        bounds.MaxY += delta;
                    }
                    else if (normal.z < 0)
                    {
                        bounds.MinZ -= delta;
                    }
                    else if (normal.z > 0)
                    {
                        bounds.MaxZ += delta;
                    }
                }
            }

            if (showEdgePoints)
            {
                for (int i = 0; i < edgePoints.Length; i++)
                {
                    Handles.color = edgeColors[(i * 2) + 1];

                    var position    = edgePoints[i];
                    var sideIndices = BoundsUtilities.AABBEdgeSides[i];
                    var normal      = BoundsUtilities.AABBEdgeTangents[i];
                    var direction1  = BoundsUtilities.AABBSideNormal[sideIndices[0]];
                    var direction2  = BoundsUtilities.AABBSideNormal[sideIndices[1]];
                    var size        = edgeSizes[i] / 20.0f;
                    var id          = edgeControlIDs[i];
                    EditorGUI.BeginChangeCheck();
                    position = CSGHandles.Slider2D(id, position, Vector3.zero, normal, direction1, direction2, size, null, doSnapping, null, init, shutdown);
                    if (EditorGUI.EndChangeCheck())
                    {
                        var originalPoint = BoundsUtilities.GetBoundsEdgePoint(originalBounds, i);
                        bounds = originalBounds;

                        var delta = (position - originalPoint);
                        var sides = BoundsUtilities.AABBEdgeCubeSides[i];
                        switch (sides[0])
                        {
                        case CubeSide.NegativeX: bounds.MinX += delta.x; break;

                        case CubeSide.PositiveX: bounds.MaxX += delta.x; break;

                        case CubeSide.NegativeY: bounds.MinY += delta.y; break;

                        case CubeSide.PositiveY: bounds.MaxY += delta.y; break;

                        case CubeSide.NegativeZ: bounds.MinZ += delta.z; break;

                        case CubeSide.PositiveZ: bounds.MaxZ += delta.z; break;
                        }

                        switch (sides[1])
                        {
                        case CubeSide.NegativeX: bounds.MinX += delta.x; break;

                        case CubeSide.PositiveX: bounds.MaxX += delta.x; break;

                        case CubeSide.NegativeY: bounds.MinY += delta.y; break;

                        case CubeSide.PositiveY: bounds.MaxY += delta.y; break;

                        case CubeSide.NegativeZ: bounds.MinZ += delta.z; break;

                        case CubeSide.PositiveZ: bounds.MaxZ += delta.z; break;
                        }
                    }
                }
            }

            Handles.matrix = origMatrix;

            if (bounds.MinX > bounds.MaxX)
            {
                float t = bounds.MinX; bounds.MinX = bounds.MaxX; bounds.MaxX = t;
            }
            if (bounds.MinY > bounds.MaxY)
            {
                float t = bounds.MinY; bounds.MinY = bounds.MaxY; bounds.MaxY = t;
            }
            if (bounds.MinZ > bounds.MaxZ)
            {
                float t = bounds.MinZ; bounds.MinZ = bounds.MaxZ; bounds.MaxZ = t;
            }
            return(bounds);
        }
        internal static void UpdateColors(AABB bounds, Quaternion worldToLocalRotation, bool showEdgePoints)
        {
            var camera = Camera.current;

            if (!camera)
            {
                return;
            }

            var localToWorldRotation = Quaternion.Inverse(worldToLocalRotation);

            BoundsUtilities.GetBoundsCornerPoints(bounds, cornerPoints);
            BoundsUtilities.GetBoundsSidePoints(bounds, sidePoints);
            BoundsUtilities.GetBoundsEdgePoints(bounds, edgePoints);


            var boundOutlinesColor = ColorSettings.MeshEdgeOutline;
            var localToWorld       = Matrix4x4.TRS(Vector3.zero, localToWorldRotation, Vector3.one);

            PaintUtility.DrawDottedLines(localToWorld, cornerPoints, BoundsUtilities.AABBLineIndices, boundOutlinesColor, 4.0f);
            PaintUtility.DrawLines(localToWorld, cornerPoints, BoundsUtilities.AABBLineIndices, ToolConstants.oldLineScale, boundOutlinesColor);


            var isOrtho = camera.orthographic;

            if (isOrtho)
            {
                var cameraDirection = worldToLocalRotation * camera.transform.forward;
                for (int i = 0; i < BoundsUtilities.AABBSideNormal.Length; i++)
                {
                    var normal = BoundsUtilities.AABBSideNormal[i];
                    sideBackfaced[i] = Mathf.Abs(Vector3.Dot(normal, cameraDirection)) > 0.9999f;
                }
            }
            else
            {
                var cameraPosition = worldToLocalRotation * camera.transform.position;
                for (int i = 0; i < BoundsUtilities.AABBSideNormal.Length; i++)
                {
                    var normal = BoundsUtilities.AABBSideNormal[i];
                    sideBackfaced[i] = Vector3.Dot(normal, (cameraPosition - sidePoints[i])) < 0;
                }
            }

            var nearestControl = HandleUtility.nearestControl;
            var hotControl     = GUIUtility.hotControl;

            for (int i = 0; i < sidePoints.Length; i++)
            {
                var id     = sideControlIDs[i];
                var state  = (hotControl == id || nearestControl == id) ? SelectState.Hovering : SelectState.None;
                var color1 = ColorSettings.MeshEdgeOutline;
                var color2 = ColorSettings.PolygonInnerStateColor[(int)state];

                bool disabled = false;
                switch (BoundsUtilities.AABBSideAxis[i])
                {
                case PrincipleAxis.X: disabled = RealtimeCSG.CSGSettings.LockAxisX; break;

                case PrincipleAxis.Y: disabled = RealtimeCSG.CSGSettings.LockAxisY; break;

                case PrincipleAxis.Z: disabled = RealtimeCSG.CSGSettings.LockAxisZ; break;
                }
                if (disabled)
                {
                    color2 = Color.red;
                }

                var handleSize      = HandleUtility.GetHandleSize(localToWorldRotation * sidePoints[i]);
                var pointHandleSize = handleSize / 20.0f;
                if (sideBackfaced[i])
                {
                    if (!isOrtho)
                    {
                        color1.a        *= ToolConstants.backfaceTransparency;
                        color2.a        *= ToolConstants.backfaceTransparency;
                        pointHandleSize *= ToolConstants.backHandleScale;
                    }
                    else
                    {
                        pointHandleSize = 0;
                    }
                }
                else
                {
                    pointHandleSize *= ToolConstants.handleScale;
                }

                sidePointSizes[i]       = pointHandleSize;
                sideSizes[i]            = handleSize;
                sideColors[(i * 2) + 0] = color1;
                sideColors[(i * 2) + 1] = color2;
            }

            if (showEdgePoints)
            {
                for (int i = 0; i < edgePoints.Length; i++)
                {
                    var id     = edgeControlIDs[i];
                    var state  = (hotControl == id || nearestControl == id) ? SelectState.Hovering : SelectState.None;
                    var color1 = ColorSettings.MeshEdgeOutline;
                    var color2 = ColorSettings.PointInnerStateColor[(int)state];

                    bool disabled1 = false;
                    switch (BoundsUtilities.AABBEdgeAxis[i][0])
                    {
                    case PrincipleAxis.X: disabled1 = RealtimeCSG.CSGSettings.LockAxisX; break;

                    case PrincipleAxis.Y: disabled1 = RealtimeCSG.CSGSettings.LockAxisY; break;

                    case PrincipleAxis.Z: disabled1 = RealtimeCSG.CSGSettings.LockAxisZ; break;
                    }
                    bool disabled2 = false;
                    switch (BoundsUtilities.AABBEdgeAxis[i][1])
                    {
                    case PrincipleAxis.X: disabled2 = RealtimeCSG.CSGSettings.LockAxisX; break;

                    case PrincipleAxis.Y: disabled2 = RealtimeCSG.CSGSettings.LockAxisY; break;

                    case PrincipleAxis.Z: disabled2 = RealtimeCSG.CSGSettings.LockAxisZ; break;
                    }
                    if (disabled1 && disabled2)
                    {
                        color2 = Color.red;
                    }

                    var handleSize      = HandleUtility.GetHandleSize(localToWorldRotation * edgePoints[i]);
                    var pointHandleSize = handleSize / 20.0f;
                    var side1           = BoundsUtilities.AABBEdgeSides[i][0];
                    var side2           = BoundsUtilities.AABBEdgeSides[i][1];
                    if (isOrtho)
                    {
                        if (sideBackfaced[side1] || sideBackfaced[side2])
                        {
                            pointHandleSize = 0;
                        }
                        else
                        {
                            pointHandleSize *= ToolConstants.handleScale;
                        }
                    }
                    else
                    {
                        if (sideBackfaced[side1] && sideBackfaced[side2])
                        {
                            color1.a        *= ToolConstants.backfaceTransparency;
                            color2.a        *= ToolConstants.backfaceTransparency;
                            pointHandleSize *= ToolConstants.backHandleScale;
                        }
                        else
                        {
                            pointHandleSize *= ToolConstants.handleScale;
                        }
                    }

                    edgePointSizes[i]       = pointHandleSize;
                    edgeSizes[i]            = handleSize;
                    edgeColors[(i * 2) + 0] = color1;
                    edgeColors[(i * 2) + 1] = color2;
                }
            }
        }
Beispiel #7
0
        public static void Flip(CSGBrush[] brushes, Matrix4x4 flipMatrix, string undoDescription = "Flip brushes")
        {
            var fail = false;

            Undo.IncrementCurrentGroup();
            Undo.RegisterCompleteObjectUndo(brushes.ToArray <UnityEngine.Object>(), undoDescription);

            var isGlobal = Tools.pivotRotation == PivotRotation.Global;

            var centerAll = BoundsUtilities.GetCenter(brushes);

            for (var t = 0; t < brushes.Length; t++)
            {
                var brush    = brushes[t];
                var shape    = brush.Shape;
                var position = brush.transform.position;

                Matrix4x4 brushFlip;
                Vector3   brushCenter;
                if (isGlobal)
                {
                    brushFlip = brush.transform.localToWorldMatrix *
                                flipMatrix *
                                brush.transform.worldToLocalMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll) - position;
                }
                else
                {
                    brushFlip   = flipMatrix;
                    brushCenter = brush.transform.InverseTransformPoint(centerAll);
                }

                for (var s = 0; s < shape.Surfaces.Length; s++)
                {
                    var plane = shape.Surfaces[s].Plane;

                    var normal   = brushFlip.MultiplyVector(plane.normal);
                    var biNormal = brushFlip.MultiplyVector(shape.Surfaces[s].BiNormal);
                    var tangent  = brushFlip.MultiplyVector(shape.Surfaces[s].Tangent);

                    var pointOnPlane = plane.pointOnPlane;
                    pointOnPlane -= brushCenter;
                    pointOnPlane  = brushFlip.MultiplyPoint(pointOnPlane);
                    pointOnPlane += brushCenter;

                    shape.Surfaces[s].Plane    = new CSGPlane(normal, pointOnPlane);
                    shape.Surfaces[s].BiNormal = biNormal;
                    shape.Surfaces[s].Tangent  = tangent;
                }

                var controlMesh = brush.ControlMesh;
                brush.Shape = shape;

                brush.ControlMesh = ControlMeshUtility.CreateFromShape(shape);
                if (brush.ControlMesh == null)
                {
                    brush.ControlMesh = controlMesh;
                    fail = true;
                    break;
                }

                ShapeUtility.CreateCutter(shape, brush.ControlMesh);
                brush.EnsureInitialized();

                brush.ControlMesh.SetDirty();
                EditorUtility.SetDirty(brush);

                InternalCSGModelManager.CheckSurfaceModifications(brush, true);

                ControlMeshUtility.RebuildShape(brush);
            }
            if (fail)
            {
                Debug.Log("Failed to perform operation");
                Undo.RevertAllInCurrentGroup();
            }
            InternalCSGModelManager.Refresh();
        }