Beispiel #1
0
    public static IEnumerator ExtrudeOrthogonally_OneElementManyTimes_NoYOffsetAccumulates()
    {
        // Generate single face plane
        var pb = ShapeGenerator.GeneratePlane(PivotLocation.Center, 1f, 1f, 0, 0, Axis.Up);

        try
        {
            pb.transform.position = Vector3.zero;
            pb.transform.rotation = Quaternion.identity;

            ProBuilderEditor.MenuOpenWindow();
            EditorApplication.ExecuteMenuItem("Window/General/Scene");

            var sceneView = UnityEngine.Resources.FindObjectsOfTypeAll <UnityEditor.SceneView>()[0];
            sceneView.orthographic = true;
            sceneView.drawGizmos   = false;
            sceneView.pivot        = new Vector3(0, 0, 0);
            sceneView.rotation     = Quaternion.AngleAxis(90f, Vector3.right);
            sceneView.size         = 2.0f;
            sceneView.Focus();

            var e = new Event();
            e.type = EventType.MouseEnterWindow;
            sceneView.SendEvent(e);

            Assume.That(pb.facesInternal.Length, Is.EqualTo(1));
            var face = pb.facesInternal[0];

            // Select face
            var selectedFaces = new List <Face>();
            selectedFaces.Add(face);
            Tools.current = Tool.Move;
            ProBuilderEditor.toolManager.SetSelectMode(SelectMode.Face);
            pb.SetSelectedFaces(selectedFaces);
            MeshSelection.SetSelection(pb.gameObject);

            // Center mouse position
            var bounds   = SceneView.focusedWindow.rootVisualElement.worldBound;
            var mousePos = (bounds.size * 0.5f + bounds.position) + new Vector2Int(1, 1);

            e = new UnityEngine.Event()
            {
                type          = EventType.MouseDown,
                mousePosition = mousePos,
                modifiers     = EventModifiers.None,
                clickCount    = 1,
                delta         = Vector2.zero,
            };
            sceneView.SendEvent(e);

            e = new UnityEngine.Event()
            {
                type          = EventType.MouseUp,
                mousePosition = mousePos,
                modifiers     = EventModifiers.None,
                clickCount    = 0,
                delta         = Vector2.zero,
            };
            sceneView.SendEvent(e);

            yield return(null);

            const int k_ExtrudeCount = 100;
            for (int i = 0; i < k_ExtrudeCount; i++)
            {
                // Press down at the center of the face
                e = new UnityEngine.Event()
                {
                    type          = EventType.MouseDown,
                    mousePosition = mousePos,
                    modifiers     = EventModifiers.None,
                    clickCount    = 1,
                    delta         = Vector2.zero,
                };
                sceneView.SendEvent(e);

                // Do lateral 1px drag and release
                var mouseDelta = new Vector2(i % 2 == 0 ? 1f : -1f, 0f);
                mousePos += mouseDelta;

                e.type          = EventType.MouseDrag;
                e.mousePosition = mousePos;
                e.modifiers     = EventModifiers.Shift;
                e.clickCount    = 0;
                e.delta         = mouseDelta;
                sceneView.SendEvent(e);

                e.type          = EventType.MouseUp;
                e.mousePosition = mousePos;
                e.delta         = Vector2.zero;
                sceneView.SendEvent(e);

                yield return(null);
            }

            // Check that our face count is correct after all extrusions
            Assume.That(pb.facesInternal.Length, Is.EqualTo(k_ExtrudeCount * 4 + 1));

            // We should have the last extruded face in selection
            var postExtrudeSelectedFaces = pb.GetSelectedFaces();
            Assume.That(postExtrudeSelectedFaces.Length, Is.EqualTo(1));
            var lastExtrudedFace = postExtrudeSelectedFaces[0];
            var faceVertices     = pb.GetVertices(lastExtrudedFace.indexes);

            // After many orthogonal extrusions, the last face should still be at y=0 coordinate
            for (int i = 0; i < faceVertices.Length; i++)
            {
                Assert.That(faceVertices[i].position.y, Is.EqualTo(0f));
            }
        }
        finally
        {
            UObject.DestroyImmediate(pb.gameObject);
        }
    }
        public override ActionResult DoAction()
        {
            if (MeshSelection.selectedObjectCount < 1)
            {
                return(ActionResult.NoSelection);
            }

            UndoUtility.RecordSelection("Offset Elements(s)");

            var handleRotation = MeshSelection.GetHandleRotation();

            foreach (var group in MeshSelection.elementSelection)
            {
                var mesh      = group.mesh;
                var positions = mesh.positionsInternal;
                var offset    = s_Translation.value;

                switch (s_CoordinateSpace.value)
                {
                case CoordinateSpace.World:
                case CoordinateSpace.Handle:
                {
                    var pre  = mesh.transform.localToWorldMatrix;
                    var post = mesh.transform.worldToLocalMatrix;

                    if (s_CoordinateSpace.value == CoordinateSpace.Handle)
                    {
                        offset = handleRotation * offset;
                    }

                    foreach (var index in mesh.selectedCoincidentVertices)
                    {
                        var p = pre.MultiplyPoint3x4(positions[index]);
                        p += offset;
                        positions[index] = post.MultiplyPoint3x4(p);
                    }
                    break;
                }

                case CoordinateSpace.Local:
                {
                    foreach (var index in mesh.selectedCoincidentVertices)
                    {
                        positions[index] += offset;
                    }
                    break;
                }

                case CoordinateSpace.Element:
                {
                    foreach (var elements in group.elementGroups)
                    {
                        var rotation = Quaternion.Inverse(mesh.transform.rotation) * elements.rotation;
                        var o        = rotation * offset;
                        foreach (var index in elements.indices)
                        {
                            positions[index] += o;
                        }
                    }
                    break;
                }
                }

                mesh.Rebuild();
                mesh.Optimize();
                ProBuilderEditor.Refresh();
            }

            if (ProBuilderEditor.selectMode.ContainsFlag(SelectMode.Edge | SelectMode.TextureEdge))
            {
                return(new ActionResult(ActionResult.Status.Success, "Move " + MeshSelection.selectedEdgeCount + (MeshSelection.selectedEdgeCount > 1 ? " Edges" : " Edge")));
            }
            if (ProBuilderEditor.selectMode.ContainsFlag(SelectMode.Face | SelectMode.TextureFace))
            {
                return(new ActionResult(ActionResult.Status.Success, "Move " + MeshSelection.selectedFaceCount + (MeshSelection.selectedFaceCount > 1 ? " Faces" : " Face")));
            }
            return(new ActionResult(ActionResult.Status.Success, "Move " + MeshSelection.selectedVertexCount + (MeshSelection.selectedVertexCount > 1 ? " Vertices" : " Vertex")));
        }
Beispiel #3
0
        static ActionResult DuplicateFacesToObject()
        {
            int duplicatedFaceCount      = 0;
            List <GameObject> duplicated = new List <GameObject>();

            foreach (ProBuilderMesh mesh in MeshSelection.topInternal)
            {
                if (mesh.selectedFaceCount < 1)
                {
                    continue;
                }

                var primary = mesh.selectedFaceIndexes;
                duplicatedFaceCount += primary.Count;

                List <int> inverse = new List <int>();

                for (int i = 0; i < mesh.facesInternal.Length; i++)
                {
                    if (!primary.Contains(i))
                    {
                        inverse.Add(i);
                    }
                }

                ProBuilderMesh copy = Object.Instantiate(mesh.gameObject, mesh.transform.parent).GetComponent <ProBuilderMesh>();
                EditorUtility.SynchronizeWithMeshFilter(copy);

                if (copy.transform.childCount > 0)
                {
                    for (int i = copy.transform.childCount - 1; i > -1; i--)
                    {
                        Object.DestroyImmediate(copy.transform.GetChild(i).gameObject);
                    }

                    foreach (var child in mesh.transform.GetComponentsInChildren <ProBuilderMesh>())
                    {
                        EditorUtility.SynchronizeWithMeshFilter(child);
                    }
                }

                Undo.RegisterCreatedObjectUndo(copy.gameObject, "Duplicate Selection");

                copy.DeleteFaces(inverse);
                copy.Rebuild();
                copy.Optimize();
                mesh.ClearSelection();
                copy.ClearSelection();
                copy.SetSelectedFaces(copy.faces);

                copy.gameObject.name = GameObjectUtility.GetUniqueNameForSibling(mesh.transform.parent, mesh.gameObject.name);
                duplicated.Add(copy.gameObject);
            }

            MeshSelection.SetSelection(duplicated);
            ProBuilderEditor.Refresh();

            if (duplicatedFaceCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Duplicate " + duplicatedFaceCount + " faces to new Object"));
            }

            return(new ActionResult(ActionResult.Status.Failure, "No Faces Selected"));
        }
Beispiel #4
0
        /// <summary>
        /// Return a pb_ActionResult indicating the success/failure of action.
        /// </summary>
        /// <returns></returns>
        protected override ActionResult PerformActionImplementation()
        {
            var selection = MeshSelection.top.ToArray();

            Undo.RecordObjects(selection, "Removing Edges");

            List <Face> edgeFaces = new List <Face>();

            Dictionary <Face, int> faceToMergeGroup = new Dictionary <Face, int>();
            HashSet <int>          mergeGroupIDs    = new HashSet <int>();
            List <List <Face> >    mergeGroups      = new List <List <Face> >();

            foreach (ProBuilderMesh pbMesh in selection)
            {
                if (pbMesh.selectedEdgeCount > 0)
                {
                    var selectedEdges = pbMesh.selectedEdges;
                    faceToMergeGroup.Clear();

                    foreach (var edge in selectedEdges)
                    {
                        edgeFaces.Clear();
                        mergeGroupIDs.Clear();

                        //Retrieving impacted faces from edge
                        ElementSelection.GetNeighborFaces(pbMesh, edge, edgeFaces);

                        //Chacking all edges status
                        foreach (var face in edgeFaces)
                        {
                            if (faceToMergeGroup.ContainsKey(face))
                            {
                                mergeGroupIDs.Add(faceToMergeGroup[face]);
                            }
                            else
                            {
                                faceToMergeGroup.Add(face, -1);
                            }
                        }

                        //These faces haven't been seen before
                        if (mergeGroupIDs.Count == 0)
                        {
                            foreach (var face in edgeFaces)
                            {
                                faceToMergeGroup[face] = mergeGroups.Count;
                            }
                            mergeGroups.Add(new List <Face>(edgeFaces));
                        }
                        //If only a face should already be merge, add other faces to the same merge group
                        else if (mergeGroupIDs.Count == 1)
                        {
                            foreach (var face in edgeFaces)
                            {
                                if (faceToMergeGroup[face] == -1)
                                {
                                    int index = mergeGroupIDs.First();
                                    faceToMergeGroup[face] = index;
                                    mergeGroups[index].Add(face);
                                }
                            }
                        }
                        //If more than a face already belongs to a merge group, merge these groups together
                        else
                        {
                            //Group the different mergeGroups together
                            List <Face> facesToMerge = new List <Face>();
                            foreach (var groupID in mergeGroupIDs)
                            {
                                facesToMerge.AddRange(mergeGroups[groupID]);
                                mergeGroups[groupID] = null;
                            }

                            foreach (var face in edgeFaces)
                            {
                                if (!facesToMerge.Contains(face))
                                {
                                    facesToMerge.Add(face);
                                }
                            }

                            //Remove unnecessary groups
                            mergeGroups.RemoveAll(group => group == null);
                            //Add newly created one
                            mergeGroups.Add(facesToMerge);

                            //Update groups references
                            for (int i = 0; i < mergeGroups.Count; i++)
                            {
                                foreach (var face in mergeGroups[i])
                                {
                                    faceToMergeGroup[face] = i;
                                }
                            }
                        }
                    }

                    foreach (var mergeGroup in mergeGroups)
                    {
                        MergeElements.Merge(pbMesh, mergeGroup);
                    }

                    pbMesh.ToMesh();
                    pbMesh.Refresh();
                    pbMesh.Optimize();
                }
            }

            MeshSelection.ClearElementSelection();

            // Rebuild the pb_Editor caches
            ProBuilderEditor.Refresh();

            return(new ActionResult(ActionResult.Status.Success, "Edges Removed"));
        }
        void OnSceneGUI(SceneView view)
        {
            s_Points.Clear();

            var coord          = OffsetElements.s_CoordinateSpace.value;
            var offset         = OffsetElements.s_Translation.value;
            var handleRotation = MeshSelection.GetHandleRotation();
            var camera         = view.camera.transform.forward * -.01f;

            foreach (var selection in MeshSelection.elementSelection)
            {
                var mesh = selection.mesh;

                if (coord == OffsetElements.CoordinateSpace.Element)
                {
                    foreach (var elements in selection.elementGroups)
                    {
                        s_Points.Add(elements.position + camera);
                        s_Points.Add(elements.rotation * offset);
                    }
                }
                else
                {
                    var preview = offset;

                    if (coord == OffsetElements.CoordinateSpace.Handle)
                    {
                        preview = handleRotation * offset;
                    }
                    else if (coord == OffsetElements.CoordinateSpace.Local)
                    {
                        preview = mesh.transform.TransformDirection(offset);
                    }

                    foreach (var elements in selection.elementGroups)
                    {
                        s_Points.Add(elements.position + camera);
                        s_Points.Add(preview);
                    }
                }
            }

            using (var lines = new EditorHandleDrawing.LineDrawingScope(ColorUtility.GetColor(offset)))
            {
                for (int i = 0; i < s_Points.Count; i += 2)
                {
                    lines.DrawLine(s_Points[i], s_Points[i] + s_Points[i + 1]);
                }
            }

            using (var points = new EditorHandleDrawing.PointDrawingScope(Color.gray))
            {
                for (int i = 0; i < s_Points.Count; i += 2)
                {
                    points.Draw(s_Points[i]);
                }
            }

            using (var points = new EditorHandleDrawing.PointDrawingScope(ColorUtility.GetColor(offset)))
            {
                for (int i = 0; i < s_Points.Count; i += 2)
                {
                    points.Draw(s_Points[i] + s_Points[i + 1]);
                }
            }
        }
        /// <summary>
        /// Adds pb_Object component without duplicating the objcet. Is undo-able.
        /// </summary>
        /// <param name="selected"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        public static ActionResult DoProBuilderize(
            IEnumerable <MeshFilter> selected,
            MeshImportSettings settings)
        {
            int   i     = 0;
            float count = selected.Count();

            foreach (var mf in selected)
            {
                if (mf.sharedMesh == null)
                {
                    continue;
                }

                GameObject go           = mf.gameObject;
                Mesh       originalMesh = mf.sharedMesh;

                try
                {
                    ProBuilderMesh pb = Undo.AddComponent <ProBuilderMesh>(go);

                    MeshImporter meshImporter = new MeshImporter(pb);
                    meshImporter.Import(go, settings);

                    // if this was previously a pb_Object, or similarly any other instance asset, destroy it.
                    // if it is backed by saved asset, leave the mesh asset alone but assign a new mesh to the
                    // renderer so that we don't modify the asset.
                    if (string.IsNullOrEmpty(AssetDatabase.GetAssetPath(originalMesh)))
                    {
                        Undo.DestroyObjectImmediate(originalMesh);
                    }
                    else
                    {
                        go.GetComponent <MeshFilter>().sharedMesh = new Mesh();
                    }

                    pb.ToMesh();
                    pb.Refresh();
                    pb.Optimize();

                    i++;
                }
                catch (System.Exception e)
                {
                    Debug.LogWarning("Failed ProBuilderizing: " + go.name + "\n" + e.ToString());
                }

                UnityEditor.EditorUtility.DisplayProgressBar("ProBuilderizing", mf.gameObject.name, i / count);
            }

            UnityEditor.EditorUtility.ClearProgressBar();
            MeshSelection.OnObjectSelectionChanged();
            ProBuilderEditor.Refresh();

            if (i < 1)
            {
                return(new ActionResult(ActionResult.Status.Canceled, "Nothing Selected"));
            }
            else
            {
                return(new ActionResult(ActionResult.Status.Success, "ProBuilderize " + i + (i > 1 ? " Objects" : " Object").ToString()));
            }
        }
Beispiel #7
0
        private void CreateUVRenderers()
        {
            HashSet <PBMesh> selectedMeshes = new HashSet <PBMesh>();
            IMeshEditor      meshEditor     = m_tool.GetEditor();

            if (meshEditor != null)
            {
                MeshSelection selection = meshEditor.GetSelection();
                if (selection != null)
                {
                    selectedMeshes = new HashSet <PBMesh>(selection.GetSelectedMeshes());
                }
            }

            int delta = selectedMeshes.Count() - m_uvRenderers.Count;

            if (delta > 0)
            {
                m_uvRenderersRoot.SetActive(false);
                for (int i = 0; i < delta; ++i)
                {
                    ManualUVRenderer renderer = m_uvRenderersRoot.AddComponent <ManualUVRenderer>();
                    renderer.Window = Window;
                    m_uvRenderers.Add(renderer);
                }
                m_uvRenderersRoot.SetActive(true);
            }
            else
            {
                delta = -delta;
                for (int i = 0; i < delta; ++i)
                {
                    Destroy(m_uvRenderers[m_uvRenderers.Count - 1]);
                    m_uvRenderers.RemoveAt(m_uvRenderers.Count - 1);
                }
            }

            foreach (PBMesh mesh in m_meshToRenderer.Keys.ToArray())
            {
                if (!selectedMeshes.Contains(mesh))
                {
                    m_meshToRenderer.Remove(mesh);
                }
            }

            int index = 0;

            foreach (PBMesh mesh in selectedMeshes)
            {
                ManualUVRenderer uvRenderer = m_uvRenderers[index];
                switch (m_tool.Mode)
                {
                case ProBuilderToolMode.Vertex:
                    uvRenderer.Mode = ManualUVRenderer.RenderMode.Vertex;
                    break;

                case ProBuilderToolMode.Edge:
                    uvRenderer.Mode = ManualUVRenderer.RenderMode.Edge;
                    break;

                case ProBuilderToolMode.Face:
                    uvRenderer.Mode = ManualUVRenderer.RenderMode.Face;
                    break;
                }

                index++;

                m_meshToRenderer[mesh] = uvRenderer;
            }
        }
        private void UpdateTexturesDrowDown()
        {
            HashSet <PBMesh>  selectedMeshes = new HashSet <PBMesh>();
            IMeshEditor       meshEditor     = m_tool.GetEditor();
            HashSet <Texture> textures       = new HashSet <Texture>();

            if (meshEditor != null)
            {
                MeshSelection selection = meshEditor.GetSelection();
                if (selection != null)
                {
                    foreach (PBMesh mesh in selection.GetSelectedMeshes())
                    {
                        Renderer renderer = mesh.GetComponent <Renderer>();
                        if (renderer != null)
                        {
                            foreach (Material material in renderer.sharedMaterials)
                            {
                                if (material != null && material.MainTexture() != null && !textures.Contains(material.MainTexture()))
                                {
                                    textures.Add(material.MainTexture());
                                }
                            }
                        }
                    }
                }
            }

            m_textures = textures.ToArray();
            m_texturesDropDown.ClearOptions();

            if (m_textures.Length == 0)
            {
                m_texturesDropDown.gameObject.SetActive(false);
                m_texturePreview.material.MainTexture(null);
                return;
            }

            m_texturesDropDown.gameObject.SetActive(true);

            List <string> options       = new List <string>();
            int           selectedIndex = -1;

            for (int i = 0; i < m_textures.Length; ++i)
            {
                Texture texture = m_textures[i];
                if (texture == m_lastSelectedTexture)
                {
                    selectedIndex = i;
                }

                options.Add(i + ". " + (string.IsNullOrEmpty(texture.name) ? "Texture" : texture.name));
            }
            m_texturesDropDown.AddOptions(options);

            if (selectedIndex == -1)
            {
                selectedIndex = 0;
            }

            m_texturePreview.material.MainTexture(m_textures[selectedIndex]);
            m_texturesDropDown.SetValueWithoutNotify(selectedIndex);
        }
Beispiel #9
0
        private void LateUpdate()
        {
            if (m_rte.ActiveWindow == null)
            {
                return;
            }

            if (m_rte.ActiveWindow.WindowType != RuntimeWindowType.Scene)
            {
                return;
            }

            if (!m_rte.ActiveWindow.Camera)
            {
                return;
            }

            IMeshEditor meshEditor = GetEditor();

            if (meshEditor == null)
            {
                return;
            }

            if (m_rte.Tools.ActiveTool != null)
            {
                if (UVEditingMode)
                {
                    if (m_selectionComponent.PositionHandle != null && m_selectionComponent.PositionHandle.IsDragging)
                    {
                        Vector2 uv = (Quaternion.Inverse(m_pivot.rotation) * (m_pivot.position - meshEditor.Position));
                        uv.x      = -uv.x;
                        UV.offset = m_initialUVOffset + uv;
                    }
                    else if (m_selectionComponent.RotationHandle != null && m_selectionComponent.RotationHandle.IsDragging)
                    {
                        UV.rotation = m_initialUVRotation - Vector3.SignedAngle(m_initialRight, m_pivot.right, m_pivot.forward);
                    }
                    else if (m_selectionComponent.ScaleHandle != null && m_selectionComponent.ScaleHandle.IsDragging)
                    {
                        Vector2 scale = (Vector2)m_pivot.localScale;
                        if (Mathf.Approximately(scale.x, 0))
                        {
                            scale.x = Mathf.Epsilon;
                        }
                        if (Mathf.Approximately(scale.y, 0))
                        {
                            scale.y = Mathf.Epsilon;
                        }

                        UV.scale = Vector2.Scale(new Vector2(1 / scale.x, 1 / scale.y), m_initialUVScale);
                    }
                }
                else
                {
                    if (m_selectionComponent.PositionHandle != null && m_selectionComponent.PositionHandle.IsDragging)
                    {
                        meshEditor.Position = m_pivot.position;
                    }
                    else if (m_selectionComponent.RotationHandle != null && m_selectionComponent.RotationHandle.IsDragging)
                    {
                        meshEditor.Rotate(m_pivot.rotation);
                    }
                    else if (m_selectionComponent.ScaleHandle != null && m_selectionComponent.ScaleHandle.IsDragging)
                    {
                        Vector3 localScale = m_pivot.localScale;
                        if (Mathf.Approximately(localScale.x, 0))
                        {
                            localScale.x = 0.00001f;
                        }
                        if (Mathf.Approximately(localScale.y, 0))
                        {
                            localScale.y = 0.000001f;
                        }
                        if (Mathf.Approximately(localScale.z, 0))
                        {
                            localScale.z = 0.000001f;
                        }
                        m_pivot.localScale = localScale;
                        meshEditor.Scale(m_pivot.localScale, m_pivot.rotation);
                    }
                }
            }
            else
            {
                if (!m_rte.ActiveWindow.IsPointerOver)
                {
                    return;
                }

                RuntimeWindow window = m_rte.ActiveWindow;
                meshEditor.Hover(window.Camera, m_rte.Input.GetPointerXY(0));

                if (m_rte.Input.GetPointerDown(0))
                {
                    bool          shift     = m_rte.Input.GetKey(KeyCode.LeftShift);
                    MeshSelection selection = meshEditor.Select(window.Camera, m_rte.Input.GetPointerXY(0), shift);
                    m_rte.Undo.BeginRecord();

                    if (selection != null)
                    {
                        RecordSelection(meshEditor, selection);
                    }

                    m_pivot.position = meshEditor.Position;
                    m_pivot.rotation = GetPivotRotation(meshEditor);
                    TrySelectPivot(meshEditor);

                    m_rte.Undo.EndRecord();
                }
                else if (m_rte.Input.GetKeyDown(KeyCode.Delete))
                {
                    DeleteFaces();
                }
                else if (m_rte.Input.GetKeyDown(KeyCode.H))
                {
                    FillHoles();
                }
            }
        }
Beispiel #10
0
        private void OnCurrentModeChanged(ProBuilderToolMode oldMode)
        {
            IMeshEditor disabledEditor = m_meshEditors[(int)oldMode];
            IMeshEditor enabledEditor  = m_meshEditors[(int)m_mode];

            GameObject target = null;

            if (disabledEditor != null)
            {
                target = disabledEditor.Target;

                MeshSelection disabledSelection = disabledEditor.ClearSelection();
                MeshSelection selection         = null;
                if (disabledSelection != null)
                {
                    selection = new MeshSelection(disabledSelection);
                }

                if (selection != null)
                {
                    if (oldMode == ProBuilderToolMode.Face)
                    {
                        if (m_mode == ProBuilderToolMode.Vertex)
                        {
                            selection.FacesToVertices(true);
                            enabledEditor.ApplySelection(selection);
                        }
                        else if (m_mode == ProBuilderToolMode.Edge)
                        {
                            selection.FacesToEdges(true);
                            enabledEditor.ApplySelection(selection);
                        }
                    }
                    else if (oldMode == ProBuilderToolMode.Edge)
                    {
                        if (m_mode == ProBuilderToolMode.Vertex)
                        {
                            selection.EdgesToVertices(true);
                            enabledEditor.ApplySelection(selection);
                        }
                        else if (m_mode == ProBuilderToolMode.Face)
                        {
                            selection.EdgesToFaces(true);
                            enabledEditor.ApplySelection(selection);

                            if (!selection.HasFaces)
                            {
                                m_rte.Selection.activeObject = target;
                            }
                        }
                    }
                    else if (oldMode == ProBuilderToolMode.Vertex)
                    {
                        if (m_mode == ProBuilderToolMode.Face)
                        {
                            selection.VerticesToFaces(true);
                            enabledEditor.ApplySelection(selection);
                            if (!selection.HasFaces)
                            {
                                m_rte.Selection.activeObject = target;
                            }
                        }
                        else if (m_mode == ProBuilderToolMode.Edge)
                        {
                            selection.VerticesToEdges(true);
                            enabledEditor.ApplySelection(selection);

                            if (!selection.HasEdges)
                            {
                                m_rte.Selection.activeObject = target;
                            }
                        }
                    }

                    if (enabledEditor != null && m_rte.Selection.activeObject != m_pivot)
                    {
                        GameObject[] gameObjects = m_rte.Selection.gameObjects;
                        if (gameObjects != null)
                        {
                            enabledEditor.ApplySelection(new MeshSelection(gameObjects));
                        }
                    }
                }
                else
                {
                    m_rte.Selection.activeObject = target;
                }

                if (selection != null)
                {
                    UndoRedoCallback redo = record =>
                    {
                        if (enabledEditor != null)
                        {
                            enabledEditor.ApplySelection(selection);
                            m_pivot.position = enabledEditor.Position;
                            m_pivot.rotation = GetPivotRotation(enabledEditor);
                            OnSelectionChanged();
                        }

                        return(true);
                    };

                    UndoRedoCallback undo = record =>
                    {
                        if (disabledEditor != null)
                        {
                            disabledEditor.RollbackSelection(disabledSelection);
                            m_pivot.position = disabledEditor.Position;
                            m_pivot.rotation = GetPivotRotation(disabledEditor);
                            OnSelectionChanged();
                        }

                        return(true);
                    };
                    m_rte.Undo.CreateRecord(redo, undo);
                }
            }
            else
            {
                if (enabledEditor != null)
                {
                    GameObject[] gameObjects = m_rte.Selection.gameObjects;
                    if (gameObjects != null)
                    {
                        enabledEditor.ApplySelection(new MeshSelection(gameObjects));
                        OnSelectionChanged();
                    }
                }
            }

            if (oldMode == ProBuilderToolMode.Object)
            {
                SetCanSelect(false);
                if (disabledEditor != null)
                {
                    if (disabledEditor.HasSelection)
                    {
                        m_rte.Selection.activeObject = m_pivot.gameObject;
                    }

                    disabledEditor.CenterMode = m_rte.Tools.PivotMode == RuntimePivotMode.Center;
                }
            }
            else if (Mode == ProBuilderToolMode.Object)
            {
                SetCanSelect(true);
                if (m_rte.Selection.activeGameObject == m_pivot.gameObject)
                {
                    if (disabledEditor != null)
                    {
                        m_rte.Selection.activeObject = target;
                    }
                    else
                    {
                        m_rte.Selection.activeObject = null;
                    }
                }
            }

            if (enabledEditor != null)
            {
                m_pivot.position = enabledEditor.Position;
                m_pivot.rotation = GetPivotRotation(enabledEditor);
            }
        }
        static ActionResult DetachFacesToObject()
        {
            int detachedFaceCount      = 0;
            List <GameObject> detached = new List <GameObject>();

            foreach (ProBuilderMesh mesh in MeshSelection.topInternal)
            {
                if (mesh.selectedFaceCount < 1 || mesh.selectedFaceCount == mesh.facesInternal.Length)
                {
                    continue;
                }

                var primary = mesh.selectedFaceIndexes;
                detachedFaceCount += primary.Count;

                List <int> inverse = new List <int>();

                for (int i = 0; i < mesh.facesInternal.Length; i++)
                {
                    if (!primary.Contains(i))
                    {
                        inverse.Add(i);
                    }
                }

                ProBuilderMesh copy = Object.Instantiate(mesh.gameObject, mesh.transform.parent).GetComponent <ProBuilderMesh>();
                EditorUtility.SynchronizeWithMeshFilter(copy);

#if !UNITY_2018_3_OR_NEWER
                // if is prefab, break connection and destroy children
                if (EditorUtility.IsPrefabInstance(copy.gameObject) || EditorUtility.IsPrefabAsset(copy.gameObject))
                {
                    PrefabUtility.DisconnectPrefabInstance(copy.gameObject);
                }
#endif

                if (copy.transform.childCount > 0)
                {
                    for (int i = copy.transform.childCount - 1; i > -1; i--)
                    {
                        Object.DestroyImmediate(copy.transform.GetChild(i).gameObject);
                    }

                    foreach (var child in mesh.transform.GetComponentsInChildren <ProBuilderMesh>())
                    {
                        EditorUtility.SynchronizeWithMeshFilter(child);
                    }
                }

                Undo.RegisterCreatedObjectUndo(copy.gameObject, "Detach Selection");

                mesh.DeleteFaces(primary);
                copy.DeleteFaces(inverse);

                mesh.Rebuild();
                copy.Rebuild();

                mesh.Optimize();
                copy.Optimize();

                mesh.ClearSelection();
                copy.ClearSelection();

                copy.SetSelectedFaces(copy.faces);

                copy.gameObject.name = GameObjectUtility.GetUniqueNameForSibling(mesh.transform.parent, mesh.gameObject.name);;
                detached.Add(copy.gameObject);
            }

            MeshSelection.SetSelection(detached);
            ProBuilderEditor.Refresh();

            if (detachedFaceCount > 0)
            {
                return(new ActionResult(ActionResult.Status.Success, "Detach " + detachedFaceCount + " faces to new Object"));
            }

            return(new ActionResult(ActionResult.Status.Failure, "No Faces Selected"));
        }
Beispiel #12
0
        protected override void LoadContent()
        {
            arial            = Content.Load <SpriteFont>(Fnames.Arial14);
            obj              = Content.Load <SpriteFont>(Fnames.obj);
            arialB           = Content.Load <SpriteFont>(Fnames.MSReferenceSansSerif14B);
            World.Flag.Image = new Sprite(Content);
            World.Flag.Image.LoadTexture(Fnames.Flag);
            World.Flag.Visible = false;

            Vector2 ScaleFactor = new Vector2(210 * ((float)Window.ClientBounds.Width / 1280), 200 * ((float)Window.ClientBounds.Height / 1024));

            panel = new Panel(Game, arial, arialB, Window.ClientBounds);
            panel.UIPanelClick    += new EventHandler <UIPanelEventArgs>(panel_UIPanelClick);
            panel.ObjectIconClick += new EventHandler <ObjectIconsEventArgs>(panel_ObjectIconClick);
            ground         = new Ground(World.Field, cfg.Ground);
            mesh           = new MeshSelection(Game, Fnames.Mesh);
            minimap        = new Minimap(Game, World.Field, new Rectangle(Right - (int)(Right / 5.2), Bottom - (int)(Bottom / 4.55), (int)ScaleFactor.X, (int)ScaleFactor.Y), ground.Tiles);
            minimap.Click += new EventHandler <MinimapMouseEventArgs>(minimap_Click);
            World.Panel    = panel;
            scene          = new Scene(World.Field, panel);

            #region Game.Components

            Game.Components.Clear();
            Game.Components.Add(panel);
            Game.Components.Add(mesh);
            Game.Components.Add(minimap);
            Game.Components.Add(new FPS(Game, Fnames.Arial14, new Vector2(Window.ClientBounds.Width / 2f, 0)));
            Game.Components.Add(new GameCursor(Game, Fnames.Cursor));

            #endregion

            #region Music

            Song fearNotThisNight = Content.Load <Song>(Fnames.FearNotThisNight);
            Song windGuideYou     = Content.Load <Song>(Fnames.WindGuideYou);
            Song heritageOfKings  = Content.Load <Song>(Fnames.HeritageOfKings);
            Song stronghold       = Content.Load <Song>(Fnames.Stronghold);
            Song elfish1          = Content.Load <Song>(Fnames.Elfish1);
            Song elfish2          = Content.Load <Song>(Fnames.Elfish2);
            Song elfish3          = Content.Load <Song>(Fnames.Elfish3);

            player.Add(windGuideYou);
            player.Add(fearNotThisNight);
            player.Add(heritageOfKings);
            player.Add(stronghold);
            player.Add(elfish1);
            player.Add(elfish2);
            player.Add(elfish3);

            #endregion

            if (!cfg.MusicIsMuted)
            {
                player.Shuffle();
                if (random.Next(100) == 1)
                {
                    MakeBonus();
                }
                player.Start();
            }

#if true
            for (int i = 0; i < 1000; i++)
            {
                new TStone(random.Next(World.Field.Width), random.Next(World.Field.Height), random.Next(500), MultiSprite.CreateSprite(Content, spriteBatch, Fnames.Stone,
                                                                                                                                       new Vector2(random.Next(World.Field.Width), random.Next(World.Field.Height)), new Vector2(60, 60), new Vector2(1, 2), World.FPS));
                string name = (random.Next(0, 2) == 0) ? Fnames.BigTree : Fnames.SmallTree;
                new TTree(random.Next(World.Field.Width), random.Next(World.Field.Height), i + 50, MultiSprite.CreateSprite(Content, spriteBatch, name,
                                                                                                                            new Vector2(random.Next(World.Field.Width), random.Next(World.Field.Height)), new Vector2(60, 60), new Vector2(3, 1), World.FPS));
            }
            for (int i = 0; i < 1000; i++)
            {
                new TCSwordman(random.Next(World.Field.Width - 36), random.Next(World.Field.Height - 36), 100, 10, 3, Vector2.Zero, MultiSprite.CreateSprite(Content, spriteBatch, Fnames.Swordman,
                                                                                                                                                             new Vector2(random.Next(World.Field.Width - 36), random.Next(World.Field.Height - 36)), new Vector2(72, 72), new Vector2(5, 24), World.FPS));
            }

#if false
            for (int i = 0; i < 1000; i++)
            {
                new TEnemy(random.Next(World.Field.Width), random.Next(World.Field.Height), 100, 10, 3, Vector2.Zero, MultiSprite.CreateSprite(Content, spriteBatch, Fnames.Enemy,
                                                                                                                                               new Vector2(random.Next(World.Field.Width), random.Next(World.Field.Height)), new Vector2(30, 30), new Vector2(6, 2), World.FPS));
            }
#endif
#endif

            BuildingRectangleSprite = new Sprite(Content);
            BuildingRectangleSprite.LoadTexture(Fnames.Mesh, Vector2.Zero, Vector2.One);
            BuildingRectangleSprite.Visible = false;
            BuildingRectangle = new BuildingRectangle(BuildingRectangleSprite);
        }