/// <summary>
        /// Generate a static preview for a ProBuilderMesh.
        /// </summary>
        /// <returns>Static preview of the given ProBuilderMesh.</returns>
        internal Texture2D GenerateProBuilderPreview()
        {
            GameObject copy = GameObject.Instantiate <GameObject>(m_Asset as GameObject);

            copy.hideFlags = HideFlags.HideAndDontSave;

            ProBuilderBridge.ToMesh(copy);
            ProBuilderBridge.Refresh(copy);

            MeshFilter mf = copy.GetComponent <MeshFilter>();

            Editor meshEditor = Editor.CreateEditor(mf.sharedMesh);

            Texture2D preview = meshEditor.RenderStaticPreview(null, null, k_PreviewSize.x, k_PreviewSize.y);

            ScriptableObject.DestroyImmediate(meshEditor);
            ScriptableObject.DestroyImmediate(copy);

            return(preview);
        }
Пример #2
0
        internal override void UndoRedoPerformed(List <GameObject> modified)
        {
            modifiedMeshes = new HashSet <PolyMesh>(modifiedMeshes.Where(x => x != null));

#if PROBUILDER_4_0_OR_NEWER
            if (ProBuilderBridge.ProBuilderExists())
            {
                // delete & undo causes cases where object is not null but the reference to it's pb_Object is
                HashSet <GameObject> remove = new HashSet <GameObject>();

                foreach (GameObject pb in modifiedPbMeshes)
                {
                    try
                    {
                        ProBuilderBridge.ToMesh(pb);
                        ProBuilderBridge.Refresh(pb);
                        ProBuilderBridge.Optimize(pb);
                    }
                    catch
                    {
                        remove.Add(pb);
                    }
                }

                if (remove.Count() > 0)
                {
                    modifiedPbMeshes.SymmetricExceptWith(remove);
                }
            }
#endif

            foreach (PolyMesh m in modifiedMeshes)
            {
                m.UpdateMeshFromData();
            }

            base.UndoRedoPerformed(modified);
        }
Пример #3
0
        /// <summary>
        /// Applies mesh changes back to the pb_Object (if necessary).  Optionally does a
        /// mesh rebuild.
        /// </summary>
        /// <param name="rebuildMesh">Only applies to ProBuilder meshes.</param>
        /// <param name="optimize">Determines if the mesh collisions are rebuilt (if that option is enabled) or if
        /// the mehs is a probuilder object, the mesh is optimized (condensed to share verts, other
        /// otpimziations etc) </param>
        internal void Apply(bool rebuildMesh, bool optimize = false)
        {
            if (m_PolybrushMesh.mode == PolybrushMesh.Mode.AdditionalVertexStream)
            {
                if (PolyEditor.instance.tool == BrushTool.RaiseLower ||
                    PolyEditor.instance.tool == BrushTool.Smooth)
                {
                    if (s_RebuildNormals.value && (modifiedChannels & MeshChannel.Position) > 0)
                    {
                        PolyMeshUtility.RecalculateNormals(editMesh);
                    }

                    if (optimize)
                    {
                        graphicsMesh.RecalculateBounds();
                        UpdateMeshCollider();
                    }
                }

                editMesh.ApplyAttributesToUnityMesh(graphicsMesh, modifiedChannels);
                graphicsMesh.UploadMeshData(false);
                EditorUtility.SetDirty(gameObjectAttached.GetComponent <Renderer>());

                if (m_PolybrushMesh.componentsCache.MeshFilter)
                {
                    Undo.RecordObject(m_PolybrushMesh.componentsCache.MeshFilter, "Assign Polymesh to MeshFilter");
                }

                if (m_PolybrushMesh)
                {
                    m_PolybrushMesh.SynchronizeWithMeshRenderer();
                }
            }


#if PROBUILDER_4_0_OR_NEWER
            // if it's a probuilder object rebuild the mesh without optimization
            if (isProBuilderObject)
            {
                ProBuilderBridge.SetPositions(gameObjectAttached, editMesh.vertices);
                ProBuilderBridge.SetTangents(gameObjectAttached, editMesh.tangents);

                if (editMesh.colors != null && editMesh.colors.Length == editMesh.vertexCount)
                {
                    Color[] colors = System.Array.ConvertAll(editMesh.colors, x => (Color)x);
                    ProBuilderBridge.SetColors(gameObjectAttached, colors);
                }

                if (rebuildMesh)
                {
                    ProBuilderBridge.ToMesh(gameObjectAttached);
                    ProBuilderBridge.Refresh(gameObjectAttached,
                                             optimize
                            ? ProBuilderBridge.RefreshMask.All
                            : (ProBuilderBridge.RefreshMask.Colors
                               | ProBuilderBridge.RefreshMask.Normals
                               | ProBuilderBridge.RefreshMask.Tangents));
                }
            }
#endif

            if (m_PolybrushMesh.mode == PolybrushMesh.Mode.AdditionalVertexStream)
            {
                modifiedChannels = MeshChannel.Null;
                return;
            }

            if (PolyEditor.instance.tool == BrushTool.RaiseLower ||
                PolyEditor.instance.tool == BrushTool.Smooth)
            {
                if (s_RebuildNormals.value)// && (modifiedChannels & MeshChannel.Position) > 0)
                {
                    PolyMeshUtility.RecalculateNormals(editMesh);
                }

                if (optimize)
                {
                    UpdateMeshCollider();
                    graphicsMesh.RecalculateBounds();
                }
            }

            editMesh.ApplyAttributesToUnityMesh(graphicsMesh, modifiedChannels);

            if (m_PolybrushMesh.componentsCache.MeshFilter)
            {
                Undo.RecordObject(m_PolybrushMesh.componentsCache.MeshFilter, "Assign Polymesh to MeshFilter");
            }

            m_PolybrushMesh.SynchronizeWithMeshRenderer();

            modifiedChannels = MeshChannel.Null;
        }
Пример #4
0
        private void Initialize(GameObject go)
        {
            CheckBackwardCompatiblity(go);

            gameObjectAttached = go;
            isProBuilderObject = false;

#if PROBUILDER_4_0_OR_NEWER
            if (ProBuilderBridge.ProBuilderExists())
            {
                isProBuilderObject = ProBuilderBridge.IsValidProBuilderMesh(gameObjectAttached);
            }
#endif
            Mesh         mesh         = null;
            MeshRenderer meshRenderer = gameObjectAttached.GetComponent <MeshRenderer>();
            meshFilter        = gameObjectAttached.GetComponent <MeshFilter>();
            _skinMeshRenderer = gameObjectAttached.GetComponent <SkinnedMeshRenderer>();

            originalMesh = go.GetMesh();

            if (originalMesh == null && _skinMeshRenderer != null)
            {
                originalMesh = _skinMeshRenderer.sharedMesh;
            }

            m_PolybrushMesh = gameObjectAttached.GetComponent <PolybrushMesh>();

            if (m_PolybrushMesh == null)
            {
                m_PolybrushMesh = Undo.AddComponent <PolybrushMesh>(gameObjectAttached);
                m_PolybrushMesh.Initialize();
                m_PolybrushMesh.mode = (s_UseAdditionalVertexStreams) ? PolybrushMesh.Mode.AdditionalVertexStream : PolybrushMesh.Mode.Mesh;
            }

            //attach the skinmesh ref to the polybrushmesh
            //it will be used when making a prefab containing a skin mesh. The limitation here is that the skin mesh must comes from an asset (which is 99.9999% of the time)
            if (_skinMeshRenderer != null)
            {
                Mesh sharedMesh = _skinMeshRenderer.sharedMesh;
                if (AssetDatabase.Contains(sharedMesh))
                {
                    m_PolybrushMesh.skinMeshRef = sharedMesh;
                }
            }

#if PROBUILDER_4_0_OR_NEWER
            // if it's a probuilder object rebuild the mesh without optimization
            if (isProBuilderObject)
            {
                if (ProBuilderBridge.IsValidProBuilderMesh(gameObjectAttached))
                {
                    ProBuilderBridge.ToMesh(gameObjectAttached);
                    ProBuilderBridge.Refresh(gameObjectAttached);
                }
            }
#endif

            if (meshRenderer != null || _skinMeshRenderer != null)
            {
                mesh = m_PolybrushMesh.storedMesh;

                if (mesh == null)
                {
                    mesh             = PolyMeshUtility.DeepCopy(originalMesh);
                    hadVertexStreams = false;
                }
                else
                {
                    //prevents leak
                    if (!MeshInstanceMatchesGameObject(mesh, gameObjectAttached))
                    {
                        mesh = PolyMeshUtility.DeepCopy(mesh);
                    }
                }

                mesh.name = k_MeshInstancePrefix + gameObjectAttached.GetInstanceID();
            }

            polybrushMesh.SetMesh(mesh);
            PrefabUtility.RecordPrefabInstancePropertyModifications(polybrushMesh);
            _graphicsMesh = m_PolybrushMesh.storedMesh;

            source = polybrushMesh.mode == PolybrushMesh.Mode.AdditionalVertexStream? ModelSource.AdditionalVertexStreams : PolyEditorUtility.GetMeshGUID(originalMesh);

            GenerateCompositeMesh();
        }