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)); }
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(); } }
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(); } }
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); }
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); } } }
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)); }
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)); }
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(); }
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); }