public IEnumerator CreateAndDestroyOperationComponent_Undo_OperationExists()
        {
            var scene               = TestUtility.defaultScene;
            var operation           = TestUtility.CreateGameObjectWithUndoableOperationComponent();
            var operationGameObject = operation.gameObject;

            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Undo.FlushUndoRecordObjects();
            Undo.IncrementCurrentGroup();
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeBranchCount, "Expected 1 TreeBranch to Exist");
            Assert.AreEqual(2, CSGManager.TreeNodeCount, "Expected 2 TreeNodes to Exist");

            Undo.DestroyObjectImmediate(operation);
            yield return(null);

            Assert.True(operationGameObject);
            Assert.False(operation);
            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Assert.AreEqual(0, CSGNodeHierarchyManager.RootCount(scene));

            Undo.PerformUndo();
            operation = operationGameObject.GetComponent <ChiselOperation>();
            yield return(null);

            Assert.True(operationGameObject);
            Assert.True(operation);
            Assert.AreEqual(1, CSGManager.TreeBranchCount, "Expected 1 TreeBranch to Exist");
            Assert.AreEqual(2, CSGManager.TreeNodeCount, "Expected 2 TreeNodes to Exist");
            Assert.AreEqual(1, CSGNodeHierarchyManager.RootCount(scene));
        }
Beispiel #2
0
        public IEnumerator CreateBrushWithBrushContainerAssetWithBrushMaterial_ModifyBrushMaterial_BrushIsDirty()
        {
            using (var newBrushMaterial = ChiselBrushMaterial.CreateInstance())
            {
                newBrushMaterial.LayerUsage = LayerUsageFlags.None;
                var newBrushContainerAsset = CreateBox(Vector3.one, newBrushMaterial);
                var brushGameObject        = EditorUtility.CreateGameObjectWithHideFlags("Brush", HideFlags.None);
                var brush = brushGameObject.AddComponent <ChiselBrush>();
                brush.BrushContainerAsset = newBrushContainerAsset;

                yield return(null);

                ChiselBrushContainerAssetManager.Update();
                CSGNodeHierarchyManager.Update();

                newBrushMaterial.LayerUsage = LayerUsageFlags.Renderable;
                ChiselBrushContainerAssetManager.Update();

                Assert.IsTrue(brush.Dirty);
                yield return(null);

                UnityEngine.Object.DestroyImmediate(brushGameObject);
                UnityEngine.Object.DestroyImmediate(newBrushContainerAsset);
            }
        }
        public static void SelectBrushVariant(CSGTreeBrush brush, bool uniqueSelection = false)
        {
            Undo.RecordObject(CSGSyncSelection.Instance, "Selected brush variant");
            var node = CSGNodeHierarchyManager.FindCSGNodeByTreeNode(brush);

            if (node)
            {
                node.hierarchyItem.SetBoundsDirty();
            }
            var selectedBrushesLookup = Instance.selectedBrushesLookup;
            var modified = false;/*
                                  * if (uniqueSelection)
                                  * {
                                  * foreach (var variant in brush.AllSynchronizedVariants)
                                  * {
                                  * if (variant != brush)
                                  * modified = selectedBrushesLookup.Remove(variant) || modified;
                                  * }
                                  * }*/

            modified = selectedBrushesLookup.Add(brush);
            if (modified)
            {
                CSGOutlineRenderer.Instance.OnSelectionChanged();
            }
        }
Beispiel #4
0
        public static bool GetNodesInFrustum(Frustum frustum, int visibleLayers, ref HashSet <CSGTreeNode> rectFoundNodes)
        {
            var     planes = new Plane[6];
            Vector4 srcVector;
            var     allTrees = CSGManager.AllTrees;

            for (var t = 0; t < allTrees.Length; t++)
            {
                var tree  = allTrees[t];
                var model = CSGNodeHierarchyManager.FindCSGNodeByTreeNode(tree) as ChiselModel;
                if (!model || !model.isActiveAndEnabled)
                {
                    continue;
                }

                if (((1 << model.gameObject.layer) & visibleLayers) == 0)
                {
                    continue;
                }

                var query = CSGMeshQueryManager.GetMeshQuery(model);

                // We only accept RayCasts into this model if it's visible
                if (!CSGMeshQueryManager.IsVisible(query))
                {
                    continue;
                }

                // Transform the frustum into the space of the tree
                var transform = model.transform;
                var worldToLocalMatrixInversed           = transform.localToWorldMatrix;                 // localToWorldMatrix == worldToLocalMatrix.inverse
                var worldToLocalMatrixInversedTransposed = worldToLocalMatrixInversed.transpose;
                for (int p = 0; p < 6; p++)
                {
                    var srcPlane = frustum.Planes[p];
                    srcVector.x = srcPlane.normal.x;
                    srcVector.y = srcPlane.normal.y;
                    srcVector.z = srcPlane.normal.z;
                    srcVector.w = srcPlane.distance;

                    srcVector = worldToLocalMatrixInversedTransposed * srcVector;

                    planes[p].normal   = srcVector;
                    planes[p].distance = srcVector.w;
                }

                var treeNodesInFrustum = tree.GetNodesInFrustum(planes);
                if (treeNodesInFrustum == null)
                {
                    continue;
                }

                for (int n = 0; n < treeNodesInFrustum.Length; n++)
                {
                    var treeNode = treeNodesInFrustum[n];
                    rectFoundNodes.Add(treeNode);
                }
            }
            return(rectFoundNodes.Count > 0);
        }
        internal override void UpdateTransformation()
        {
            // TODO: recalculate transformation based on hierarchy up to (but not including) model
            var transform = hierarchyItem.Transform;

            if (!transform)
            {
                return;
            }

            var localToWorldMatrix = transform.localToWorldMatrix;
            var modelTransform     = CSGNodeHierarchyManager.FindModelTransformOfTransform(transform);

            if (modelTransform)
            {
                localTransformation = modelTransform.worldToLocalMatrix * localToWorldMatrix;
            }
            else
            {
                localTransformation = localToWorldMatrix;
            }

            if (ValidNodes)
            {
                UpdateInternalTransformation();
            }
        }
Beispiel #6
0
        public IEnumerator CreateBrushWithBrushMeshAssetWithSurfaceAsset_ModifySurfaceAsset_BrushIsDirty()
        {
            using (var newSurfaceAsset = CSGSurfaceAsset.CreateInstance())
            {
                newSurfaceAsset.LayerUsage = LayerUsageFlags.None;
                var newBrushMeshAsset = BrushMeshAssetFactory.CreateBoxAsset(Vector3.one, newSurfaceAsset);
                var brushGameObject   = EditorUtility.CreateGameObjectWithHideFlags("Brush", HideFlags.None);
                var brush             = brushGameObject.AddComponent <CSGBrush>();
                brush.BrushMeshAsset = newBrushMeshAsset;

                yield return(null);

                CSGBrushMeshAssetManager.Update();
                CSGNodeHierarchyManager.Update();

                newSurfaceAsset.LayerUsage = LayerUsageFlags.Renderable;
                CSGBrushMeshAssetManager.Update();

                Assert.IsTrue(brush.Dirty);
                yield return(null);

                UnityEngine.Object.DestroyImmediate(brushGameObject);
                UnityEngine.Object.DestroyImmediate(newBrushMeshAsset);
            }
        }
        public IEnumerator CreateAndDestroyBrushGameObject_Undo_BrushExists()
        {
            var scene           = TestUtility.defaultScene;
            var brush           = TestUtility.CreateUndoableGameObjectWithBrush();
            var brushGameObject = brush.gameObject;

            Assert.AreEqual(0, CSGManager.TreeBrushCount, "Expected 0 TreeBrushes to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Undo.FlushUndoRecordObjects();
            Undo.IncrementCurrentGroup();
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeBrushCount, "Expected 1 TreeBrush to Exist");
            Assert.AreEqual(2, CSGManager.TreeNodeCount, "Expected 2 TreeNodes to Exist");

            Undo.DestroyObjectImmediate(brushGameObject);
            yield return(null);

            Assert.False(brushGameObject);
            Assert.False(brush);
            Assert.AreEqual(0, CSGManager.TreeBrushCount, "Expected 0 TreeBrushes to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Assert.AreEqual(0, CSGNodeHierarchyManager.RootCount(scene));

            Undo.PerformUndo();
            brush           = Object.FindObjectsOfType <ChiselBrush>()[0];
            brushGameObject = brush.gameObject;
            yield return(null);

            Assert.True(brushGameObject);
            Assert.True(brush);
            Assert.AreEqual(1, CSGManager.TreeBrushCount, "Expected 1 TreeBrush to Exist");
            Assert.AreEqual(2, CSGManager.TreeNodeCount, "Expected 2 TreeNodes to Exist");
            Assert.AreEqual(1, CSGNodeHierarchyManager.RootCount(scene));
        }
        public static SurfaceIntersection FindSurfaceIntersection(Vector2 position)
        {
            try
            {
                CSGTreeBrushIntersection brushIntersection;
                if (!PickFirstGameObject(position, out brushIntersection))
                {
                    return(null);
                }

                var brush = brushIntersection.brush;

                var node = CSGNodeHierarchyManager.FindCSGNodeByInstanceID(brush.UserID);
                if (!node)
                {
                    return(null);
                }

                var surface = node.FindSurfaceReference(brush, brushIntersection.surfaceID);
                if (surface == null)
                {
                    return(null);
                }
                return(new SurfaceIntersection {
                    surface = surface, intersection = brushIntersection.surfaceIntersection
                });
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
                return(null);
            }
        }
        public IEnumerator CreateBrush_DeactivateBrushGameObject_BrushDoesNotExist()
        {
            var scene           = TestUtility.defaultScene;
            var brush           = TestUtility.CreateUndoableGameObjectWithBrush();
            var brushGameObject = brush.gameObject;

            Assert.AreEqual(0, CSGManager.TreeBrushCount, "Expected 0 TreeBrushes to Exist");
            Assert.AreEqual(0, CSGManager.TreeCount, "Expected 0 Trees to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeBrushCount, "Expected 1 TreeBrush to Exist");
            Assert.AreEqual(1, CSGManager.TreeCount, "Expected 1 Tree to Exist");       // default model
            Assert.AreEqual(2, CSGManager.TreeNodeCount, "Expected 2 TreeNodes to Exist");

            brushGameObject.SetActive(false);
            yield return(null);

            Assert.True(brushGameObject);
            Assert.True(brush);
            Assert.AreEqual(0, CSGManager.TreeBrushCount, "Expected 0 TreeBrushes to Exist");
            Assert.AreEqual(0, CSGManager.TreeCount, "Expected 0 Trees to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Assert.AreEqual(0, CSGNodeHierarchyManager.RootCount(scene));
        }
        public IEnumerator CreateAndDestroyModelGameObject_Undo_ModelExist()
        {
            var scene           = TestUtility.defaultScene;
            var model           = TestUtility.CreateUndoableGameObjectWithModel();
            var modelGameObject = model.gameObject;

            Assert.AreEqual(0, CSGManager.TreeCount, "Expected 0 Trees to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Undo.FlushUndoRecordObjects();
            Undo.IncrementCurrentGroup();
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeCount, "Expected 1 Tree to Exist");
            Assert.AreEqual(1, CSGManager.TreeNodeCount, "Expected 1 TreeNode to Exist");

            Undo.DestroyObjectImmediate(modelGameObject);
            yield return(null);

            Assert.False(modelGameObject);
            Assert.False(model);
            Assert.AreEqual(0, CSGManager.TreeCount, "Expected 0 Trees to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");

            Undo.PerformUndo();
            yield return(null);

            model = modelGameObject.GetComponent <ChiselModel>();
            yield return(null);

            Assert.True(modelGameObject);
            Assert.True(model);
            Assert.AreEqual(1, CSGManager.TreeCount, "Expected 1 Tree to Exist");
            Assert.AreEqual(1, CSGManager.TreeNodeCount, "Expected 1 TreeNode to Exist");
            Assert.AreEqual(1, CSGNodeHierarchyManager.RootCount(scene));
        }
        public IEnumerator ModelInScene1_MoveToScene2_ModelOnlyExistsInScene2()
        {
            var scene2 = TestUtility.defaultScene;

            EditorSceneManager.SaveScene(scene2, TestUtility.tempFilename);
            var scene1 = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive);

            EditorSceneManager.SetActiveScene(scene1);

            var model           = TestUtility.CreateUndoableGameObjectWithModel();
            var modelGameObject = model.gameObject;

            Assert.AreEqual(0, CSGManager.TreeCount, "Expected 0 Trees to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeCount, "Expected 1 Tree to Exist");
            Assert.AreEqual(1, CSGManager.TreeNodeCount, "Expected 1 TreeNode to Exist");
            Assert.AreEqual(scene1, model.hierarchyItem.Scene);

            Undo.MoveGameObjectToScene(modelGameObject, scene2, "Move gameObject to different scene");
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeCount, "Expected 1 Tree to Exist");
            Assert.AreEqual(1, CSGManager.TreeNodeCount, "Expected 1 TreeNode to Exist");

            Assert.AreEqual(scene2, model.gameObject.scene, "Model is not part of expected scene");
            Assert.AreEqual(scene2, model.hierarchyItem.Scene, "Model is not registered to expected scene");

            Assert.AreEqual(0, CSGNodeHierarchyManager.RootCount(scene1));
            Assert.AreEqual(1, CSGNodeHierarchyManager.RootCount(scene2));

            // make sure test runner doesn't puke on its own bugs
            EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
        }
Beispiel #12
0
        private static bool StartToolDragging()
        {
            jumpedMousePosition += Event.current.delta;
            Event.current.Use();
            if (ToolIsDragging)
            {
                UpdateDragVector();
                return(false);
            }

            // We set ToolIsDragging to true to be able to tell the difference between dragging and clicking
            ToolIsDragging = true;

            // Find the intersecting surfaces
            startSurfaceReference = hoverSurfaceReference;
            var currentIntersection = hoverIntersection.Value.surfaceIntersection;

            selectedSurfaceReferences = ChiselSurfaceSelectionManager.Selection.ToArray();

            // We need all the brushContainerAssets for all the surfaces we're moving, so that we can record them for an undo
            selectedBrushContainerAsset = ChiselSurfaceSelectionManager.SelectedBrushMeshes.ToArray();

            // We copy all the original surface uvMatrices, so we always apply rotations and transformations relatively to the original
            // This makes it easier to recover from edge cases and makes it more accurate, floating point wise.
            selectedUVMatrices = new UVMatrix[selectedSurfaceReferences.Length];
            for (int i = 0; i < selectedSurfaceReferences.Length; i++)
            {
                if (selectedSurfaceReferences[i].Polygon.surface == null)
                {
                    selectedUVMatrices[i] = UVMatrix.identity;
                }
                else
                {
                    selectedUVMatrices[i] = selectedSurfaceReferences[i].Polygon.surface.surfaceDescription.UV0;
                }
            }

            // Find the intersection point/plane in model space
            var nodeTransform  = startSurfaceReference.node.hierarchyItem.Transform;
            var modelTransform = CSGNodeHierarchyManager.FindModelTransformOfTransform(nodeTransform);

            worldStartPosition   = modelTransform.localToWorldMatrix.MultiplyPoint(hoverIntersection.Value.surfaceIntersection.worldIntersection);
            worldProjectionPlane = modelTransform.localToWorldMatrix.TransformPlane(hoverIntersection.Value.surfaceIntersection.worldPlane);
            worldIntersection    = worldStartPosition;

            // TODO: we want to be able to determine delta movement over a plane. Ideally it would match the position of the cursor perfectly.
            //		 unfortunately when moving the cursor towards the horizon of the plane, relative to the camera, the delta movement
            //		 becomes too large or even infinity. Ideally we'd switch to a camera facing plane for these cases and determine movement in
            //		 a less perfect way that would still allow the user to move or rotate things in a reasonable way.

            // more accurate for small movements
            worldDragPlane = worldProjectionPlane;

            // TODO: (unfinished) prevents drag-plane from intersecting near plane (makes movement slow down to a singularity when further away from click position)
            //worldDragPlane	= new Plane(Camera.current.transform.forward, worldStartPosition);

            // TODO: ideally we'd interpolate the behavior of the worldPlane between near and far behavior
            UpdateDragVector();
            return(true);
        }
 public static void ClearScene()
 {
     defaultScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
     CSGManager.Clear();
     CSGNodeHierarchyManager.Reset();
     CSGNodeHierarchyManager.Update();
 }
        public void OnSceneGUI()
        {
            if (!target || !ChiselEditModeManager.EditMode.EnableComponentEditors)
            {
                return;
            }

            using (new UnityEditor.Handles.DrawingScope(UnityEditor.Handles.yAxisColor))
            {
                var generator = target as T;
                if (!generator.isActiveAndEnabled)
                {
                    return;
                }

                var modelMatrix = CSGNodeHierarchyManager.FindModelTransformMatrixOfTransform(generator.hierarchyItem.Transform);
                var brush       = generator.TopNode;
                //foreach (var brush in CSGSyncSelection.GetSelectedVariantsOfBrushOrSelf((CSGTreeBrush)generator.TopNode))
                //foreach (var brush in generator.Node.AllSynchronizedVariants) // <-- this fails when brushes have failed to be created
                {
                    //var directSelect = CSGSyncSelection.IsBrushVariantSelected(brush);
                    //if (!directSelect)
                    //	continue;

                    UnityEditor.Handles.matrix = modelMatrix * brush.NodeToTreeSpaceMatrix;
                    UnityEditor.Handles.color  = UnityEditor.Handles.yAxisColor;

                    OnScene(generator);
                }
            }
        }
Beispiel #15
0
        public IEnumerator DisabledOperationWithPassThroughEnabled_EnableOperationComponent_OperationDoesNotExist()
        {
            var scene               = TestUtility.defaultScene;
            var operation           = TestUtility.CreateUndoableGameObjectWithOperation();
            var operationGameObject = operation.gameObject;

            operation.enabled     = false;
            operation.PassThrough = true;

            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            yield return(null);

            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");

            operation.enabled = true;
            yield return(null);

            Assert.True(operationGameObject);
            Assert.True(operation);
            Assert.AreEqual(operation.Node, (CSGTreeBranch)CSGTreeNode.InvalidNode);
            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Assert.AreEqual(0, CSGNodeHierarchyManager.RootCount(scene));
        }
Beispiel #16
0
        public IEnumerator OperationWithPassThroughEnabled_DestroyOperationComponent_OperationDoesNotExist()
        {
            var scene               = TestUtility.defaultScene;
            var operation           = TestUtility.CreateUndoableGameObjectWithOperation();
            var operationGameObject = operation.gameObject;

            operation.PassThrough = true;

            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            yield return(null);

            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Assert.True(operationGameObject);
            Assert.True(operation);

            Undo.DestroyObjectImmediate(operation);
            yield return(null);

            Assert.True(operationGameObject);
            Assert.False(operation);
            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            Assert.AreEqual(0, CSGNodeHierarchyManager.RootCount(scene));
        }
Beispiel #17
0
        protected override void OnScene(ChiselBrush generator)
        {
            var targetBrushContainerAsset = generator.BrushContainerAsset;

            if (!targetBrushContainerAsset)
            {
                return;
            }

            var brushMeshes = targetBrushContainerAsset.BrushMeshes;

            if (brushMeshes == null)
            {
                return;
            }

            for (int m = 0; m < brushMeshes.Length; m++)
            {
                var brushMesh = brushMeshes[m];
                if (brushMesh == null)
                {
                    continue;
                }

                EditorGUI.BeginChangeCheck();

                var modelMatrix = CSGNodeHierarchyManager.FindModelTransformMatrixOfTransform(generator.hierarchyItem.Transform);

                var vertices  = brushMesh.vertices;
                var halfEdges = brushMesh.halfEdges;

                //HashSet<CSGTreeBrush> foundBrushes = new HashSet<CSGTreeBrush>();
                //targetBrush.GetAllTreeBrushes(foundBrushes, false)
                //foreach (var brush in CSGSyncSelection.GetSelectedVariantsOfBrushOrSelf((CSGTreeBrush)generator.TopNode))
                {
                    var brush          = (CSGTreeBrush)generator.TopNode;
                    var transformation = modelMatrix * brush.NodeToTreeSpaceMatrix;
                    for (int e = 0; e < halfEdges.Length; e++)
                    {
                        var vertexIndex1 = halfEdges[e].vertexIndex;
                        var vertexIndex2 = halfEdges[halfEdges[e].twinIndex].vertexIndex;

                        var from = vertices[vertexIndex1];
                        var to   = vertices[vertexIndex2];
                        ChiselOutlineRenderer.DrawLine(transformation, from, to, UnityEditor.Handles.yAxisColor, thickness: 1.0f);
                    }
                }

                //var newBounds = CSGHandles.BoundsHandle(originalBounds, Quaternion.identity, CSGHandles.DotHandleCap);

                if (EditorGUI.EndChangeCheck())
                {
                    //Undo.RecordObject(target, "Changed shape of Brush");
                    //brush.Bounds = newBounds;
                }
            }
        }
        public void OnSceneGUI(SceneView sceneView)
        {
            if (selectedNode.Count > 0)
            {
                for (int i = 0; i < selectedNode.Count; i++)
                {
                    if (!selectedNode[i].transform)
                    {
                        UpdateSelection();
                        break;
                    }
                }
                modifiedNodes.Clear();
                for (int i = 0; i < selectedNode.Count; i++)
                {
                    var transform             = selectedNode[i].transform;
                    var node                  = selectedNode[i].node;
                    var curLocalToWorldMatrix = transform.localToWorldMatrix;
                    var oldLocalToWorldMatrix = node.hierarchyItem.LocalToWorldMatrix;
                    if (curLocalToWorldMatrix.m00 != oldLocalToWorldMatrix.m00 ||
                        curLocalToWorldMatrix.m01 != oldLocalToWorldMatrix.m01 ||
                        curLocalToWorldMatrix.m02 != oldLocalToWorldMatrix.m02 ||
                        curLocalToWorldMatrix.m03 != oldLocalToWorldMatrix.m03 ||

                        curLocalToWorldMatrix.m10 != oldLocalToWorldMatrix.m10 ||
                        curLocalToWorldMatrix.m11 != oldLocalToWorldMatrix.m11 ||
                        curLocalToWorldMatrix.m12 != oldLocalToWorldMatrix.m12 ||
                        curLocalToWorldMatrix.m13 != oldLocalToWorldMatrix.m13 ||

                        curLocalToWorldMatrix.m20 != oldLocalToWorldMatrix.m20 ||
                        curLocalToWorldMatrix.m21 != oldLocalToWorldMatrix.m21 ||
                        curLocalToWorldMatrix.m22 != oldLocalToWorldMatrix.m22 ||
                        curLocalToWorldMatrix.m23 != oldLocalToWorldMatrix.m23 //||

                        //curLocalToWorldMatrix.m30 != oldLocalToWorldMatrix.m30 ||
                        //curLocalToWorldMatrix.m31 != oldLocalToWorldMatrix.m31 ||
                        //curLocalToWorldMatrix.m32 != oldLocalToWorldMatrix.m32 ||
                        //curLocalToWorldMatrix.m33 != oldLocalToWorldMatrix.m33
                        )
                    {
                        node.hierarchyItem.LocalToWorldMatrix = curLocalToWorldMatrix;
                        node.hierarchyItem.WorldToLocalMatrix = transform.worldToLocalMatrix;
                        modifiedNodes.Add(node);
                    }
                }
                if (modifiedNodes.Count > 0)
                {
                    CSGNodeHierarchyManager.NotifyTransformationChanged(modifiedNodes);
                }
            }

            // Handle selection clicks / marquee selection
            ChiselRectSelectionManager.Update(sceneView);
        }
        public static bool FindBrushMaterials(Vector2 position, out ChiselBrushMaterial[] brushMaterials, out ChiselBrushContainerAsset[] brushContainerAssets, bool selectAllSurfaces)
        {
            brushMaterials       = null;
            brushContainerAssets = null;
            try
            {
                CSGTreeBrushIntersection intersection;
                if (!PickFirstGameObject(Event.current.mousePosition, out intersection))
                {
                    return(false);
                }

                var brush = intersection.brush;

                var node = CSGNodeHierarchyManager.FindCSGNodeByInstanceID(brush.UserID);
                if (!node)
                {
                    return(false);
                }

                if (selectAllSurfaces)
                {
                    brushContainerAssets = node.GetUsedGeneratedBrushes();
                    if (brushContainerAssets == null)
                    {
                        return(false);
                    }
                    brushMaterials = node.GetAllBrushMaterials(brush);
                    return(true);
                }
                else
                {
                    var surface = node.FindBrushMaterial(brush, intersection.surfaceID);
                    if (surface == null)
                    {
                        return(false);
                    }
                    brushContainerAssets = node.GetUsedGeneratedBrushes();
                    if (brushContainerAssets == null)
                    {
                        return(false);
                    }
                    brushMaterials = new ChiselBrushMaterial[] { surface };
                    return(true);
                }
            }
            catch (Exception ex)
            {
                Debug.LogException(ex);
                return(false);
            }
        }
        private static void OnEditorApplicationUpdate()
        {
            // TODO: remove this once we've moved to managed implementation of CSG algorithm
            if (!loggingMethodsRegistered)
            {
                Editors.NativeLogging.RegisterUnityMethods();
                loggingMethodsRegistered = true;
            }

            //Grid.HoverGrid = null;
            CSGNodeHierarchyManager.Update();
            ChiselGeneratedModelMeshManager.UpdateModels();
        }
Beispiel #21
0
        public IEnumerator OperationWithChildInScene1_MoveToScene2_OperationWithChildOnlyExistsInScene2()
        {
            var scene2 = TestUtility.defaultScene;

            EditorSceneManager.SaveScene(scene2, TestUtility.tempFilename);
            var scene1 = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive);

            EditorSceneManager.SetActiveScene(scene1);

            var operation           = TestUtility.CreateUndoableGameObjectWithOperation();
            var operationGameObject = operation.gameObject;

            var brush           = TestUtility.CreateUndoableGameObjectWithBrush();
            var brushGameObject = brush.gameObject;

            brush.transform.parent = operation.transform;

            Assert.AreEqual(0, CSGManager.TreeBranchCount, "Expected 0 TreeBranches to Exist");
            Assert.AreEqual(0, CSGManager.TreeBrushCount, "Expected 0 TreeBrushes to Exist");
            Assert.AreEqual(0, CSGManager.TreeNodeCount, "Expected 0 TreeNodes to Exist");
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeBranchCount, "Expected 1 TreeBranch to Exist");
            Assert.AreEqual(1, CSGManager.TreeBrushCount, "Expected 1 TreeBrush to Exist");
            Assert.AreEqual(3, CSGManager.TreeNodeCount, "Expected 3 TreeNodes to Exist");
            Assert.AreEqual(scene1, operation.gameObject.scene);
            Assert.AreEqual(scene1, operation.hierarchyItem.Scene);

            Undo.MoveGameObjectToScene(operationGameObject, scene2, "Move gameObject to different scene");
            yield return(null);

            Assert.AreEqual(1, CSGManager.TreeBranchCount, "Expected 1 TreeBranch to Exist");
            Assert.AreEqual(1, CSGManager.TreeBrushCount, "Expected 1 TreeBrush to Exist");
            Assert.AreEqual(3, CSGManager.TreeNodeCount, "Expected 3 TreeNodes to Exist");

            Assert.AreEqual(operation.hierarchyItem, brush.hierarchyItem.Parent);
            Assert.AreEqual(operation.NodeID, brush.hierarchyItem.Parent.Component.NodeID);
            Assert.AreEqual(operation.NodeID, brush.TopNode.Parent.NodeID);

            Assert.AreEqual(scene2, operation.gameObject.scene, "Operation is not part of expected scene");
            Assert.AreEqual(scene2, operation.hierarchyItem.Scene, "Operation is not registered to expected scene");

            Assert.AreEqual(scene2, brush.gameObject.scene, "Brush is not part of expected scene");
            Assert.AreEqual(scene2, brush.hierarchyItem.Scene, "Brush is not registered to expected scene");

            Assert.AreEqual(0, CSGNodeHierarchyManager.RootCount(scene1));
            Assert.AreEqual(1, CSGNodeHierarchyManager.RootCount(scene2));

            // make sure test runner doesn't puke on its own bugs
            EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
        }
 public static void ForceUpdateNodeContents(SerializedObject serializedObject)
 {
     serializedObject.ApplyModifiedProperties();
     foreach (var target in serializedObject.targetObjects)
     {
         var node = target as ChiselNode;
         if (!node)
         {
             continue;
         }
         CSGNodeHierarchyManager.NotifyContentsModified(node);
         node.SetDirty();
     }
 }
        public static void CheckForTransformationChanges(SerializedObject serializedObject)
        {
            if (Event.current.type == EventType.Layout)
            {
                modifiedNodes.Clear();
                foreach (var target in serializedObject.targetObjects)
                {
                    var node = target as ChiselNode;
                    if (!node)
                    {
                        continue;
                    }
                    var transform = node.transform;

                    // TODO: probably not a good idea to use matrices for this, since it calculates this all the way up the transformation tree
                    var curLocalToWorldMatrix = transform.localToWorldMatrix;
                    var oldLocalToWorldMatrix = node.hierarchyItem.LocalToWorldMatrix;
                    if (curLocalToWorldMatrix.m00 != oldLocalToWorldMatrix.m00 ||
                        curLocalToWorldMatrix.m01 != oldLocalToWorldMatrix.m01 ||
                        curLocalToWorldMatrix.m02 != oldLocalToWorldMatrix.m02 ||
                        curLocalToWorldMatrix.m03 != oldLocalToWorldMatrix.m03 ||

                        curLocalToWorldMatrix.m10 != oldLocalToWorldMatrix.m10 ||
                        curLocalToWorldMatrix.m11 != oldLocalToWorldMatrix.m11 ||
                        curLocalToWorldMatrix.m12 != oldLocalToWorldMatrix.m12 ||
                        curLocalToWorldMatrix.m13 != oldLocalToWorldMatrix.m13 ||

                        curLocalToWorldMatrix.m20 != oldLocalToWorldMatrix.m20 ||
                        curLocalToWorldMatrix.m21 != oldLocalToWorldMatrix.m21 ||
                        curLocalToWorldMatrix.m22 != oldLocalToWorldMatrix.m22 ||
                        curLocalToWorldMatrix.m23 != oldLocalToWorldMatrix.m23 //||

                        //curLocalToWorldMatrix.m30 != oldLocalToWorldMatrix.m30 ||
                        //curLocalToWorldMatrix.m31 != oldLocalToWorldMatrix.m31 ||
                        //curLocalToWorldMatrix.m32 != oldLocalToWorldMatrix.m32 ||
                        //curLocalToWorldMatrix.m33 != oldLocalToWorldMatrix.m33
                        )
                    {
                        node.hierarchyItem.LocalToWorldMatrix = curLocalToWorldMatrix;
                        node.hierarchyItem.WorldToLocalMatrix = transform.worldToLocalMatrix;
                        modifiedNodes.Add(node);
                    }
                }
                if (modifiedNodes.Count > 0)
                {
                    CSGNodeHierarchyManager.NotifyTransformationChanged(modifiedNodes);
                }
            }
        }
        //**//

        protected override void OnValidateInternal()
        {
            HandleDuplication();

            if (!ValidNodes)
            {
                return;
            }

            UpdateGenerator();
            UpdateBrushMeshInstances();

            CSGNodeHierarchyManager.NotifyContentsModified(this);
            base.OnValidateInternal();
        }
        private static UnityEditor.UndoPropertyModification[] OnPostprocessModifications(UnityEditor.UndoPropertyModification[] modifications)
        {
            // Note: this is not always properly called
            //			- when? can't remember? maybe prefab related?
            modifiedNodes.Clear();
            processedTransforms.Clear();
            for (int i = 0; i < modifications.Length; i++)
            {
                var currentValue = modifications[i].currentValue;
                var transform    = currentValue.target as Transform;
                if (object.Equals(null, transform))
                {
                    continue;
                }

                if (processedTransforms.Contains(transform))
                {
                    continue;
                }

                var propertyPath = currentValue.propertyPath;
                if (!propertyPath.StartsWith("m_Local"))
                {
                    continue;
                }

                processedTransforms.Add(transform);

                var nodes = transform.GetComponentsInChildren <ChiselNode>();
                if (nodes.Length == 0)
                {
                    continue;
                }
                if (nodes[0] is ChiselModel)
                {
                    continue;
                }
                for (int n = 0; n < nodes.Length; n++)
                {
                    modifiedNodes.Add(nodes[n]);
                }
            }
            if (modifiedNodes.Count > 0)
            {
                CSGNodeHierarchyManager.NotifyTransformationChanged(modifiedNodes);
            }
            return(modifications);
        }
        public static void ClearBrushVariants(CSGTreeBrush brush)
        {
            Undo.RecordObject(CSGSyncSelection.Instance, "ClearBrushVariants variant");
            var node = CSGNodeHierarchyManager.FindCSGNodeByTreeNode(brush);

            if (node)
            {
                node.hierarchyItem.SetBoundsDirty();
            }
            var modified = false;

            if (modified)
            {
                CSGOutlineRenderer.Instance.OnSelectionChanged();
            }
        }
        public void OnSceneGUI()
        {
            if (!target || !ChiselEditModeManager.EditMode.EnableComponentEditors)
            {
                return;
            }

            var generator = target as T;

            if (GUIUtility.hotControl == 0)
            {
                if (!OnGeneratorValidate(generator))
                {
                    if (validTargets.Contains(generator))
                    {
                        OnGeneratorDeselected(generator);
                        validTargets.Remove(generator);
                    }
                    return;
                }
                if (!validTargets.Contains(generator))
                {
                    OnGeneratorSelected(generator);
                    validTargets.Add(generator);
                }
            }

            var sceneView = SceneView.currentDrawingSceneView;

            var modelMatrix = CSGNodeHierarchyManager.FindModelTransformMatrixOfTransform(generator.hierarchyItem.Transform);
            var brush       = generator.TopNode;

            // NOTE: could loop over multiple instances from here, once we support that
            {
                using (new UnityEditor.Handles.DrawingScope(UnityEditor.Handles.yAxisColor, modelMatrix * brush.NodeToTreeSpaceMatrix))
                {
                    EditorGUI.BeginChangeCheck();
                    {
                        OnScene(sceneView, generator);
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        OnTargetModifiedInScene();
                    }
                }
            }
        }
        public static void DeselectBrushVariant(CSGTreeBrush brush)
        {
            Undo.RecordObject(CSGSyncSelection.Instance, "Deselected brush variant");
            var node = CSGNodeHierarchyManager.FindCSGNodeByTreeNode(brush);

            if (node)
            {
                node.hierarchyItem.SetBoundsDirty();
            }
            var selectedBrushesLookup = Instance.selectedBrushesLookup;
            var modified = selectedBrushesLookup.Remove(brush);

            if (modified)
            {
                CSGOutlineRenderer.Instance.OnSelectionChanged();
            }
        }
        void OnGUI()
        {
            CSGNodeHierarchyManager.Update();
            if (styles == null)
            {
                UpdateStyles();
            }

            var selectedTransforms = new HashSet <Transform>();

            foreach (var transform in Selection.transforms)
            {
                selectedTransforms.Add(transform);
            }

            var totalCount = GetVisibleItems(CSGNodeHierarchyManager.sceneHierarchies);

            var itemArea = position;

            itemArea.x = 0;
            itemArea.y = 0;

            var totalRect = position;

            totalRect.x      = 0;
            totalRect.y      = 0;
            totalRect.width  = position.width - kScrollWidth;
            totalRect.height = (totalCount * kItemHeight) + (2 * kPadding);

            var itemRect = position;

            itemRect.x      = 0;
            itemRect.y      = kPadding;
            itemRect.height = kItemHeight;

            m_ScrollPos = GUI.BeginScrollView(itemArea, m_ScrollPos, totalRect);
            {
                Rect visibleArea = itemArea;
                visibleArea.x += m_ScrollPos.x;
                visibleArea.y += m_ScrollPos.y;

                AddFoldOuts(ref itemRect, ref visibleArea, selectedTransforms, CSGNodeHierarchyManager.sceneHierarchies);
            }
            GUI.EndScrollView();
        }
        public static PlaneIntersection GetPlaneIntersection(Vector2 mousePosition)
        {
            CSGTreeBrushIntersection brushIntersection;
            var intersectionObject = ChiselClickSelectionManager.PickClosestGameObject(mousePosition, out brushIntersection);

            if (intersectionObject &&
                intersectionObject.activeInHierarchy)
            {
                if (brushIntersection.brushUserID != -1)
                {
                    var brush = CSGNodeHierarchyManager.FindCSGNodeByInstanceID(brushIntersection.brush.UserID);
                    var model = CSGNodeHierarchyManager.FindCSGNodeByInstanceID(brushIntersection.tree.UserID) as ChiselModel;
                    return(new PlaneIntersection(brushIntersection, brush, model));
                }

                var meshFilter = intersectionObject.GetComponent <MeshFilter>();
                if (meshFilter)
                {
                    var        mesh     = meshFilter.sharedMesh;
                    var        mouseRay = UnityEditor.HandleUtility.GUIPointToWorldRay(mousePosition);
                    RaycastHit hit;
                    if (ChiselClickSelectionManager.IntersectRayMesh(mouseRay, mesh, intersectionObject.transform.localToWorldMatrix, out hit))
                    {
                        var meshRenderer = intersectionObject.GetComponent <MeshRenderer>();
                        if (meshRenderer.enabled)
                        {
                            return(new PlaneIntersection(hit.point, hit.normal));
                        }
                    }
                }
            }
            else
            {
                var gridPlane = UnitySceneExtensions.Grid.ActiveGrid.PlaneXZ;
                var mouseRay  = UnityEditor.HandleUtility.GUIPointToWorldRay(mousePosition);
                var dist      = 0.0f;
                if (gridPlane.UnsignedRaycast(mouseRay, out dist))
                {
                    return(new PlaneIntersection(mouseRay.GetPoint(dist), gridPlane));
                }
            }
            return(null);
        }