Exemplo n.º 1
0
    public void End()
    {
        m_Mesh.Clear();

        m_Mesh.SetVertices(m_Vertices);
        m_Mesh.SetColors(m_Color);
        m_Mesh.SetUVs(0, m_UV);
        m_Mesh.subMeshCount = 2;
        InternalMeshUtil.SetIndices(m_Mesh, m_Lines, MeshTopology.Lines, 0, false);
        InternalMeshUtil.SetIndices(m_Mesh, m_Quads, MeshTopology.Quads, 1, false);
        m_Mesh.RecalculateBounds();
    }
Exemplo n.º 2
0
    public void End()
    {
        m_Mesh.Clear();

        m_Mesh.SetVertices(m_Vertices);
        m_Mesh.SetColors(m_Color);
        m_Mesh.SetUVs(0, m_UV);
        m_Mesh.subMeshCount = 2;
#if UNITY_2019_2 || UNITY_2019_1 || UNITY_2018 || UNITY_2017 || UNITY_5
        InternalMeshUtil.SetIndices(m_Mesh, m_Lines, MeshTopology.Lines, 0, false);
        InternalMeshUtil.SetIndices(m_Mesh, m_Quads, MeshTopology.Quads, 1, false);
#else
        m_Mesh.SetIndices(m_Lines, MeshTopology.Lines, 0, false);
        m_Mesh.SetIndices(m_Quads, MeshTopology.Quads, 1, false);
#endif
        m_Mesh.RecalculateBounds();
    }
Exemplo n.º 3
0
        protected void OnGUI()
        {
            if (m_Settings == null)
            {
                m_Settings      = CreateInstance <SdfBakerSettings>();
                m_Settings.name = "None";
            }
            bool needsUpdate = false;

            Undo.RecordObject(this, "Settings Asset change");
            Undo.RecordObject(m_Settings, "SDF Baker Parameter change");
            GUILayout.BeginHorizontal();


            EditorGUI.BeginChangeCheck();
            var newSettings = (SdfBakerSettings)EditorGUILayout.ObjectField(Contents.settingsAsset, m_Settings, typeof(SdfBakerSettings), true, GUILayout.MinWidth(20),
                                                                            GUILayout.MaxWidth(400), GUILayout.ExpandWidth(true));

            if (EditorGUI.EndChangeCheck())
            {
                if (newSettings != null)
                {
                    LoadSettings(newSettings);
                }
                else
                {
                    CreateNewSession();
                }
            }
            GUILayout.Space(5);


            GUI.enabled = EditorUtility.IsDirty(m_Settings);
            if (GUILayout.Button(Contents.saveSettings, GUILayout.MinWidth(20), GUILayout.ExpandWidth(true)))
            {
                SaveSettings();
            }
            GUI.enabled = true;
            DrawContextIcon();
            GUILayout.EndHorizontal();
            GUILayout.Space(5);

            EditorGUI.BeginChangeCheck();
            maxResolution = Mathf.Clamp(EditorGUILayout.IntField(Contents.maxResolution, maxResolution), 8, 1024);
            bool maxResChanged = EditorGUI.EndChangeCheck();

            needsUpdate |= maxResChanged;
            if (maxResolution > 255)
            {
                EditorGUILayout.HelpBox(
                    "Higher resolutions are more expensive to calculate and can make Unity unstable.",
                    MessageType.Warning);
            }

            EditorGUI.BeginChangeCheck();
            var prevWideMode = EditorGUIUtility.wideMode;

            EditorGUIUtility.wideMode = true;
            boxCenter    = EditorGUILayout.Vector3Field("Box Center", boxCenter);
            needsUpdate |= EditorGUI.EndChangeCheck();

            EditorGUI.BeginChangeCheck();
            boxSizeReference = EditorGUILayout.Vector3Field(Contents.boxSizeReference, boxSizeReference);
            bool boxSizeChanged = EditorGUI.EndChangeCheck();

            needsUpdate |= boxSizeChanged;

            if (boxSizeChanged || maxResChanged)
            {
                m_ActualBoxSize = SnapBoxToVoxels();
            }

            using (new EditorGUI.DisabledScope(true))
            {
                SerializedObject selfSO = new SerializedObject(this);
                EditorGUILayout.PropertyField(selfSO.FindProperty("m_ActualBoxSize"), Contents.actualBoxSize);
            }


            if (boxSizeReference.x * boxSizeReference.y * boxSizeReference.z <= Single.Epsilon)
            {
                EditorGUILayout.HelpBox("The volume of your bounding box is zero.", MessageType.Warning);
            }

            int estimatedGridSize = EstimateGridSize();

            if (estimatedGridSize > 1 << 21 || selectedMesh == null)
            {
                GUI.enabled  = false;
                m_LiveUpdate = false;
            }

            EditorGUI.BeginChangeCheck();
            m_LiveUpdate = EditorGUILayout.Toggle(Contents.liveUpdate, m_LiveUpdate);
            needsUpdate |= (EditorGUI.EndChangeCheck() & m_LiveUpdate);

            GUI.enabled = true;
            if (m_LiveUpdate)
            {
                EditorGUILayout.HelpBox(
                    "Baking the mesh in real-time might cause slowdowns or instabilities when the resolution and/or the sign passes count is high ",
                    MessageType.Warning);
            }

            bool fitPaddingChanged = false;

            if (m_ShowAdvanced)
            {
                m_FoldOutParameters = EditorGUILayout.BeginFoldoutHeaderGroup(m_FoldOutParameters, Contents.bakingParameters);
                EditorGUI.BeginChangeCheck();
                if (m_FoldOutParameters)
                {
                    EditorGUI.indentLevel++;
                    signPassesCount = Mathf.Clamp(EditorGUILayout.IntField(Contents.signPass, signPassesCount), 0,
                                                  20);
                    inOutThreshold = EditorGUILayout.Slider(Contents.inOutParam, inOutThreshold, 0.0f, 1.0f);
                    surfaceOffset  = EditorGUILayout.Slider(Contents.sdfOffset, surfaceOffset, -0.5f, 0.5f);
                    EditorGUI.indentLevel--;
                }
                EditorGUILayout.EndFoldoutHeaderGroup();
                needsUpdate |= EditorGUI.EndChangeCheck();

                EditorGUI.BeginChangeCheck();
                m_Settings.m_FitPaddingVoxel = EditorGUILayout.Vector3IntField(Contents.fitPadding, m_Settings.m_FitPaddingVoxel);
                fitPaddingChanged            = EditorGUI.EndChangeCheck();
            }
            EditorGUIUtility.wideMode = prevWideMode;

            if (selectedMesh != null)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUI.BeginChangeCheck();
                if (GUILayout.Button(Contents.fitBoxToMesh))
                {
                    FitBoxToMesh();
                }
                needsUpdate |= EditorGUI.EndChangeCheck();

                EditorGUI.BeginChangeCheck();
                if (GUILayout.Button(Contents.fitCubeToMesh))
                {
                    FitCubeToMesh();
                }
                needsUpdate |= EditorGUI.EndChangeCheck();


                EditorGUILayout.EndHorizontal();
            }

            EditorGUI.BeginChangeCheck();
            modelSource = (ModelSource)EditorGUILayout.EnumPopup(Contents.bakeSource, modelSource);
            bool changedSource = EditorGUI.EndChangeCheck();

            needsUpdate |= changedSource;

            switch (modelSource)
            {
            case ModelSource.Mesh:
                EditorGUI.BeginChangeCheck();
                selectedMesh =
                    (Mesh)EditorGUILayout.ObjectField(Contents.mesh, selectedMesh, typeof(Mesh), false);
                bool meshFieldHasChanged = EditorGUI.EndChangeCheck();
                needsUpdate |= meshFieldHasChanged;

                m_RefreshMeshPreview |= meshFieldHasChanged | changedSource;
                if (m_RefreshMeshPreview)
                {
                    m_Settings.ApplySelectedMesh();
                }

                break;

            case ModelSource.MeshPrefab:
                EditorGUI.BeginChangeCheck();
                meshPrefab =
                    (GameObject)EditorGUILayout.ObjectField(Contents.meshPrefab, meshPrefab, typeof(GameObject),
                                                            false);

                meshFieldHasChanged = EditorGUI.EndChangeCheck() || m_PrefabChanged;
                m_PrefabChanged     = false;
                needsUpdate        |= meshFieldHasChanged;

                m_RefreshMeshPreview |= meshFieldHasChanged | changedSource || (mesh == null);
                bool rebuildMesh = m_RefreshMeshPreview;
                if (rebuildMesh)
                {
                    m_Settings.BuildMeshFromPrefab();
                    rebuildMesh = false;
                }

                break;
            }

            if (mesh == null)
            {
                m_LiveUpdate = false;
            }

            if (m_RefreshMeshPreview && mesh != null)
            {
                FitBoxToMesh();
                m_MeshPreview?.Dispose();
                m_MeshPreview        = new SdfBakerPreview(mesh);
                m_RefreshMeshPreview = false;
            }

            if (mesh == null || (estimatedGridSize > UnityEngine.VFX.SDF.MeshToSDFBaker.kMaxGridSize) || InternalMeshUtil.GetPrimitiveCount(mesh) == 0)
            {
                GUI.enabled = false;
            }

            if (GUILayout.Button("Bake mesh") || m_LiveUpdate && needsUpdate)
            {
                if (m_Baker == null)
                {
                    m_Baker = new MeshToSDFBaker(boxSizeReference, boxCenter, maxResolution, mesh, signPassesCount,
                                                 inOutThreshold, surfaceOffset);
                }
                else
                {
                    m_Baker.Reinit(boxSizeReference, boxCenter, maxResolution, mesh, signPassesCount,
                                   inOutThreshold, surfaceOffset);
                }

                m_Baker.BakeSDF();
                m_BakedSDF = m_Baker.SdfTexture;
            }

            GUI.enabled = true;


            bool canSave = true;

            if ((m_BakedSDF == null) || (m_Baker == null))
            {
                canSave     = false;
                GUI.enabled = false;
            }

            if (GUILayout.Button(canSave ? Contents.saveSDF : Contents.saveSDFBlocked))
            {
                m_Baker.SaveToAsset();
            }

            GUI.enabled = true;

            previewObject = (PreviewChoice)EditorGUILayout.EnumPopup(Contents.previewChoice, previewObject);
            if ((previewObject & PreviewChoice.Mesh) != 0)
            {
                UpdateMeshPreview();
            }

            if ((previewObject & PreviewChoice.Texture) != 0)
            {
                UpdateTexture3dPreview();
            }

            if (needsUpdate)
            {
                EditorUtility.SetDirty(m_Settings);
            }
        }
Exemplo n.º 4
0
    public void Update()
    {
        if (!m_Mesh)
        {
            return;
        }
        if (!(m_MeshReadable = m_Mesh.isReadable))
        {
            return;
        }
        {
            m_MeshBounds       = m_Mesh.bounds;
            m_MeshSubmeshCount = m_Mesh.subMeshCount;
        }
        {
            Set(ref m_Verts, m_Mesh.vertices);
            Set(ref m_Colors, m_Mesh.colors);
            Set(ref m_BoneWeights, m_Mesh.boneWeights);
            Resize(ref m_UVs, 4);
            for (int i = 0; i < m_MeshSubmeshCount; i++)
            {
                m_Mesh.GetUVs(i, m_UVs[i]);
            }
            m_VertCount = m_Verts.Count;
        }
        {
            Resize(ref m_Normals, 3);
            Set(ref m_Normals[0], m_Mesh.normals);
            Reset(ref m_NormalFlips);
            var tan = m_Mesh.tangents;
            for (int i = 0; i < m_Normals[0].Count; i++)
            {
                m_Normals[1].Add(tan[i]);
                m_NormalFlips.Add(tan[i].w);
                m_Normals[2].Add(Vector3.Cross(m_Normals[0][i], m_Normals[1][i]) * m_NormalFlips[i]);
            }
        }
        {
            m_IndiceAreaMax     = 0;
            m_IndiceAreaTotal   = 0;
            m_IndiceInvalidArea = 0;
            Resize(ref m_Indices, m_MeshSubmeshCount);
            Resize(ref m_IndiceAreas, m_MeshSubmeshCount);
            Resize(ref m_IndiceMedians, m_MeshSubmeshCount);
            Resize(ref m_IndiceNormals, m_MeshSubmeshCount);
            Array.Resize(ref m_IndiceOffsets, m_MeshSubmeshCount);
            Array.Resize(ref m_IndiceTypes, m_MeshSubmeshCount);
            int iter = 0, iterNormaled = 0;
            for (int i = 0; i < m_MeshSubmeshCount; i++)
            {
                Set(ref m_Indices[i], m_Mesh.GetIndices(i));
                m_IndiceTypes[i]   = m_Mesh.GetTopology(i);
                m_IndiceOffsets[i] = iter;
                var steps  = m_TopologyDivision[m_IndiceTypes[i]];
                var indice = m_Indices[i];
                var normal = m_Normals[0];
                iter         += indice.Count;
                iterNormaled += indice.Count / steps;
                for (int m = 0; m < indice.Count; m += steps)
                {
                    int a, b, c, d;
                    switch (steps)
                    {
                    case 1:
                        a = indice[m];
                        m_IndiceMedians[i].Add(m_Verts[a]);
                        m_IndiceNormals[i].Add(normal[a]);
                        m_IndiceAreas[i].Add(0); break;

                    case 2:
                        a = indice[m]; b = indice[m + 1];
                        m_IndiceMedians[i].Add((m_Verts[a] + m_Verts[b]) / 2);
                        m_IndiceNormals[i].Add((normal[a] + normal[b]).normalized);
                        m_IndiceAreas[i].Add((m_Verts[a] + m_Verts[b]).magnitude); break;

                    case 3:
                        a = indice[m]; b = indice[m + 1]; c = indice[m + 2];
                        m_IndiceMedians[i].Add((m_Verts[a] + m_Verts[b] + m_Verts[c]) / 3);
                        m_IndiceNormals[i].Add((normal[a] + normal[b] + normal[c]).normalized);
                        m_IndiceAreas[i].Add(GetTriArea(m_Verts[a], m_Verts[b], m_Verts[c])); break;

                    case 4:
                        a = indice[m]; b = indice[m + 1]; c = indice[m + 2]; d = indice[m + 3];
                        m_IndiceMedians[i].Add((m_Verts[a] + m_Verts[b] + m_Verts[c] + m_Verts[d]) / 4);
                        m_IndiceNormals[i].Add((normal[a] + normal[b] + normal[c] + normal[d]).normalized);
                        m_IndiceAreas[i].Add(GetTriArea(m_Verts[a], m_Verts[b], m_Verts[c]) +
                                             GetTriArea(m_Verts[d], m_Verts[b], m_Verts[c])); break;
                    }
                    var area = m_IndiceAreas[i][m_IndiceAreas[i].Count - 1];
                    m_IndiceAreaMax    = Mathf.Max(m_IndiceAreaMax, area);
                    m_IndiceAreaTotal += area;
                    if (area < 0e-10f)
                    {
                        m_IndiceInvalidArea++;
                    }
                }
            }
            m_IndiceCount           = iter;
            m_IndiceCountNormalized = iterNormaled;
        }
        {
            m_VertSimilarsMax  = 0;
            m_VertUsedCountMax = 0;
            m_VertDuplicates   = 0;
            m_VertOrphan       = m_Verts.Count;
            Resize(ref m_VertUsedCounts, m_Verts.Count);
            Resize(ref m_VertToIndicesDir, m_Verts.Count);
            Reset(ref m_VertSimilars);
            for (int i = 0; i < m_Verts.Count; i++)
            {
                var v = m_Verts[i];
                if (m_VertSimilars.ContainsKey(v))
                {
                    m_VertSimilars[v]++;
                    m_VertDuplicates++;
                }
                else
                {
                    m_VertSimilars[v] = 1;
                }
                m_VertSimilarsMax = Mathf.Max(m_VertSimilarsMax, m_VertSimilars[v]);
            }
            for (int i = 0; i < m_Indices.Length; i++)
            {
                var indice = m_Indices[i];
                for (int j = 0; j < indice.Count; j++)
                {
                    var idx = indice[j];
                    m_VertToIndicesDir[idx] = (m_IndiceMedians[i][j / m_TopologyDivision[m_IndiceTypes[i]]] - m_Verts[idx]);
                    if (m_VertUsedCounts[idx] == 0)
                    {
                        m_VertOrphan--;
                    }
                    m_VertUsedCountMax = Mathf.Max(m_VertUsedCountMax, ++m_VertUsedCounts[idx]);
                }
            }
        }
        {
            m_Features =
                "Vertices: " + m_VertCount + " total, " + (m_VertOrphan > 0 ? m_VertOrphan + " orphan, " : "") + (m_VertDuplicates > 0 ? m_VertDuplicates + " duplicates, " : "") +
                "\nIndices: " + m_IndiceCountNormalized + " total, " + m_IndiceCount + " buffer capacity, " + m_IndiceAreaTotal.ToString("0.##") + " unit surface area, " +
                (m_MeshSubmeshCount > 1 ? m_MeshSubmeshCount + " submeshes, " : "") + (m_IndiceInvalidArea > 0 ? m_IndiceInvalidArea + " invalid, " : "") +
                "\nChannels: " + InternalMeshUtil.GetVertexFormat(m_Mesh) +
                "\nSize: " + m_MeshBounds.size.ToString("0.00");
        }
        m_lastMeshId = m_Mesh.GetInstanceID();
    }