Пример #1
0
        void OnGUI_Mesh()
        {
            GUILayout.Label("Mesh Baking", EditorStyles.boldLabel);
            m_Mesh         = (Mesh)EditorGUILayout.ObjectField(Contents.mesh, m_Mesh, typeof(Mesh), false);
            m_Distribution = (Distribution)EditorGUILayout.EnumPopup(Contents.distribution, m_Distribution);
            if (m_Distribution != Distribution.RandomUniformArea)
            {
                m_MeshBakeMode = (MeshBakeMode)EditorGUILayout.EnumPopup(Contents.meshBakeMode, m_MeshBakeMode);
            }

            m_ExportNormals = EditorGUILayout.Toggle("Export Normals", m_ExportNormals);
            m_ExportColors  = EditorGUILayout.Toggle("Export Colors", m_ExportColors);
            m_ExportUV      = EditorGUILayout.Toggle("Export UVs", m_ExportUV);

            m_OutputPointCount = EditorGUILayout.IntField("Point Count", m_OutputPointCount);
            if (m_Distribution != Distribution.Sequential)
            {
                m_SeedMesh = EditorGUILayout.IntField("Seed", m_SeedMesh);
            }

            m_OutputFormat = (PCache.Format)EditorGUILayout.EnumPopup("File Format", m_OutputFormat);

            if (m_Mesh != null)
            {
                if (GUILayout.Button("Save to pCache file..."))
                {
                    string fileName = EditorUtility.SaveFilePanelInProject("pCacheFile", m_Mesh.name, "pcache", "Save PCache");
                    if (fileName != null)
                    {
                        try
                        {
                            EditorUtility.DisplayProgressBar("pCache bake tool", "Capturing data...", 0.0f);
                            var file = ComputePCacheFromMesh();
                            if (file != null)
                            {
                                EditorUtility.DisplayProgressBar("pCache bake tool", "Saving pCache file", 1.0f);
                                file.SaveToFile(fileName, m_OutputFormat);
                                AssetDatabase.ImportAsset(fileName, ImportAssetOptions.ForceUpdate | ImportAssetOptions.ForceSynchronousImport);
                            }
                        }
                        catch (System.Exception e)
                        {
                            Debug.LogException(e);
                        }
                        EditorUtility.ClearProgressBar();
                    }
                }
                EditorGUILayout.Space();

                using (new GUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    EditorGUILayout.LabelField("Mesh Statistics", EditorStyles.boldLabel);
                    EditorGUI.indentLevel++;
                    EditorGUILayout.IntField("Vertices", m_Mesh.vertexCount);
                    EditorGUILayout.IntField("Triangles", m_Mesh.triangles.Length);
                    EditorGUILayout.IntField("Sub Meshes", m_Mesh.subMeshCount);
                    EditorGUI.indentLevel--;
                }
            }

            EditorGUILayout.Space();
        }
Пример #2
0
    public static PCache ComputePCacheFromMesh(Mesh mesh, int mapSize = 512, int pointCount = 4096, int seed = 0, Distribution distribution = Distribution.RandomUniformArea, MeshBakeMode meshBakeMode = MeshBakeMode.Triangle)
    {
        if (mapSize % 8 != 0)
        {
            Debug.LogError("Position map dimensions should be a multiple of 8.");
            return(null);
        }

        if (computeShader == null)
        {
            computeShader = computeShader = Resources.Load <ComputeShader>("Shaders/ComputeMeshToMap");
        }

        PCache pCache = new PCache();

        // From PointCacheBakeTool
        MeshData meshCache = ComputeDataCache(mesh);

        Picker picker = null;

        if (distribution == Distribution.Sequential)
        {
            if (meshBakeMode == MeshBakeMode.Vertex)
            {
                picker = new SequentialPickerVertex(meshCache);
            }
            else if (meshBakeMode == MeshBakeMode.Triangle)
            {
                picker = new SequentialPickerTriangle(meshCache);
            }
        }
        else if (distribution == Distribution.Random)
        {
            if (meshBakeMode == MeshBakeMode.Vertex)
            {
                picker = new RandomPickerVertex(meshCache, seed);
            }
            else if (meshBakeMode == MeshBakeMode.Triangle)
            {
                picker = new RandomPickerTriangle(meshCache, seed);
            }
        }
        else if (distribution == Distribution.RandomUniformArea)
        {
            picker = new RandomPickerUniformArea(meshCache, seed);
        }
        if (picker == null)
        {
            throw new InvalidOperationException("Unable to find picker");
        }

        pCache.mesh      = mesh;
        pCache.mapSize   = mapSize;
        pCache.positions = new List <Vector3>();
        pCache.normals   = new List <Vector3>();

        for (int i = 0; i < pointCount; ++i)
        {
            var vertex = picker.GetNext();
            pCache.positions.Add(vertex.position);
            pCache.normals.Add(vertex.normal);
        }

        // From SMRVFX
        pCache.positionMap = new RenderTexture(mapSize, mapSize, 0, RenderTextureFormat.ARGBFloat);
        pCache.positionMap.enableRandomWrite = true;
        pCache.positionMap.Create();
        pCache.normalMap = new RenderTexture(mapSize, mapSize, 0, RenderTextureFormat.ARGBFloat);
        pCache.normalMap.enableRandomWrite = true;
        pCache.normalMap.Create();

        // Transfer data
        var vcount    = pCache.positions.Count;
        var vcount_x3 = vcount * 3;

        pCache.positionBuffer = new ComputeBuffer(vcount_x3, sizeof(float));
        pCache.normalBuffer   = new ComputeBuffer(vcount_x3, sizeof(float));

        computeShader.SetInt("VertexCount", vcount);

        pCache.positionBuffer.SetData(pCache.positions);
        pCache.normalBuffer.SetData(pCache.normals);

        computeShader.SetBuffer(0, "PositionBuffer", pCache.positionBuffer);
        computeShader.SetBuffer(0, "NormalBuffer", pCache.normalBuffer);

        computeShader.SetTexture(0, "PositionMap", pCache.positionMap);
        computeShader.SetTexture(0, "NormalMap", pCache.normalMap);

        computeShader.Dispatch(0, pCache.mapSize / 8, pCache.mapSize / 8, 1);

        return(pCache);
    }