Esempio n. 1
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);
        }
        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();
            }
        }
Esempio n. 3
0
        void UpdateSurfaceSelection()
        {
            surfaceOutlines.Clear();
            var selection = ChiselSurfaceSelectionManager.Selection;
            var hovered   = ChiselSurfaceSelectionManager.Hovered;

            if (selection.Count == 0 &&
                hovered.Count == 0)
            {
                surfaceOutlines.Clear();
                surfaceOutlineRenderer.Clear();
            }
            else
            {
                var allSurfaces = new HashSet <SurfaceReference>(selection);
                allSurfaces.AddRange(hovered);
                foreach (var outline in surfaceOutlines.Keys)
                {
                    var surface = outline.surface;
                    if (!allSurfaces.Contains(surface) ||
                        !surface.TreeBrush.Valid ||
                        surface.TreeBrush.BrushMesh == BrushMeshInstance.InvalidInstance)
                    {
                        removedSurfaces.Add(outline);
                    }
                    else
                    {
                        allSurfaces.Remove(surface);
                    }
                }

                if (removedSurfaces.Count > 0)
                {
                    foreach (var outline in removedSurfaces)
                    {
                        surfaceOutlines.Remove(outline);
                    }
                }
                removedSurfaces.Clear();

                foreach (var surface in allSurfaces)
                {
                    var transform = CSGNodeHierarchyManager.FindModelTransformOfTransform(surface.node.hierarchyItem.Transform);
                    var outline   = new SurfaceOutline(transform, surface);
                    foundSurfaceOutlines.Add(outline);
                }

                foreach (var outline in foundSurfaceOutlines)
                {
                    if (!outline.surface.TreeBrush.Valid ||
                        outline.surface.TreeBrush.BrushMesh == BrushMeshInstance.InvalidInstance)
                    {
                        continue;
                    }

                    var wireframe = CSGWireframe.CreateWireframe(outline.surface.TreeBrush, outline.surface.surfaceID);
                    surfaceOutlines[outline] = wireframe;
                }
            }
            foundSurfaceOutlines.Clear();
            updateSurfaceWireframe = true;
        }
Esempio n. 4
0
        static void OnMoveTool()
        {
            var position = Tools.handlePosition;
            var rotation = Tools.handleRotation;

#if SYNC_SUPPORT // TODO: finish and fix this
            var selectedNodes = Selection.GetFiltered <CSGNode>(SelectionMode.Editable | SelectionMode.TopLevel);
            if (selectedNodes.Length == 0)
            {
                // TODO: probably need to use our own PositionHandle on non CSG objects, to be able to snap to grid
                return;
            }


            var transformation    = Matrix4x4.identity;
            var invTransformation = Matrix4x4.identity;

            // TODO: figure out how to handle this with selecting multiple variants of the same brush (synchronized brushes)
            if (selectedNodes.Length == 1)
            {
                foundTreeBrushes.Clear();
                selectedNodes[0].GetAllTreeBrushes(foundTreeBrushes, ignoreSynchronizedBrushes: true);
                if (foundTreeBrushes.Count == 1)
                {
                    var transform  = CSGNodeHierarchyManager.FindModelTransformOfTransform(selectedNodes[0].hierarchyItem.Transform);
                    var firstBrush = foundTreeBrushes.First();
                    var brush      = firstBrush;
                    if (!CSGSyncSelection.IsBrushVariantSelected(brush))
                    {
                        List <CSGTreeBrush> selectedVariants = new List <CSGTreeBrush>();
                        if (CSGSyncSelection.GetSelectedVariantsOfBrush(brush, selectedVariants))
                        {
                            brush = selectedVariants[0];
                        }
                    }
                    if (transform)
                    {
                        transformation = transform.localToWorldMatrix * brush.NodeToTreeSpaceMatrix;
                    }
                    else
                    {
                        transformation = brush.NodeToTreeSpaceMatrix;
                    }
                    rotation          = Quaternion.LookRotation(transformation.GetColumn(2), transformation.GetColumn(1));
                    invTransformation = selectedNodes[0].transform.localToWorldMatrix * transformation.inverse;
                    if (Tools.pivotRotation == PivotRotation.Global)
                    {
                        rotation = Quaternion.identity;
                    }
                    position = transformation.GetColumn(3);
                }
            }
#endif

            EditorGUI.BeginChangeCheck();
            // TODO: make this work with bounds!
            var newPosition = UnitySceneExtensions.SceneHandles.PositionHandle(position, rotation);
            if (EditorGUI.EndChangeCheck())
            {
                var delta      = newPosition - position;
                var transforms = Selection.transforms;
                if (transforms != null && transforms.Length > 0)
                {
                    MoveTransformsTo(transforms, delta);
                }
            }
        }
Esempio n. 5
0
        void UpdateBrushSelection()
        {
            brushDirectlySelected.Clear();
            var objects = Selection.objects;

            if (objects.Length > 0)
            {
                for (int i = 0; i < objects.Length; i++)
                {
                    var          obj        = objects[i];
                    ChiselNode[] nodes      = null;
                    var          gameObject = obj as GameObject;
                    if (!Equals(null, gameObject))
                    {
                        nodes = gameObject.GetComponentsInChildren <ChiselNode>();
                    }
                    else
                    {
                        var behaviour = obj as Behaviour;
                        if (!Equals(null, behaviour))
                        {
                            nodes = behaviour.GetComponents <ChiselNode>();
                        }
                    }

                    if (nodes != null &&
                        nodes.Length > 0)
                    {
                        for (int n = 0; n < nodes.Length; n++)
                        {
                            var node = nodes[n];
                            foundTreeBrushes.Clear();
                            node.GetAllTreeBrushes(foundTreeBrushes, ignoreSynchronizedBrushes: true);
                            if (foundTreeBrushes.Count > 0)
                            {
                                var directSelected = (// if component is directly select
                                    (gameObject == null) ||
                                    // or when the component is part of the selected gameObject
                                    (gameObject == node.gameObject)) &&
                                                     // if we find CSGTreeBrushes directly on this node, but this node
                                                     // can also have child nodes, then we assume the CSGTreeBrushes are generated
                                                     // and we don't want to show those as directly selected
                                                     !node.CanHaveChildNodes;
                                var transform = CSGNodeHierarchyManager.FindModelTransformOfTransform(node.hierarchyItem.Transform);
                                foreach (var treeBrush in foundTreeBrushes)
                                {
                                    if (directSelected)
                                    {
                                        brushDirectlySelected.Add(treeBrush);
                                    }
                                    var outline = new BrushOutline(transform, treeBrush);
                                    foundBrushOutlines.Add(outline);
                                }
                            }
                        }
                    }
                }
            }

            if (foundTreeBrushes.Count == 0)
            {
                brushOutlines.Clear();
                brushOutlineRenderer.Clear();
            }
            else
            {
                foreach (var outline in brushOutlines.Keys)
                {
                    if (!foundBrushOutlines.Contains(outline) ||
                        !outline.brush.Valid ||
                        outline.brush.BrushMesh == BrushMeshInstance.InvalidInstance)
                    {
                        removedBrushes.Add(outline);
                    }
                }

                if (removedBrushes.Count > 0)
                {
                    foreach (var outline in removedBrushes)
                    {
                        brushOutlines.Remove(outline);
                    }
                }
                removedBrushes.Clear();

                foreach (var outline in foundBrushOutlines)
                {
                    if (!outline.brush.Valid ||
                        outline.brush.BrushMesh == BrushMeshInstance.InvalidInstance)
                    {
                        continue;
                    }

                    var wireframe = CSGWireframe.CreateWireframe(outline.brush);
                    brushOutlines[outline] = wireframe;
                }
            }

            foundBrushOutlines.Clear();
            updateBrushWireframe = true;
        }