PCache ComputePCacheFromMesh()
        {
            var meshCache = ComputeDataCache(m_Mesh);

            Picker picker = null;

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

            var positions = new List <Vector3>();
            var normals   = m_ExportNormals ? new List <Vector3>() : null;
            var colors    = m_ExportColors ? new List <Vector4>() : null;
            var uvs       = m_ExportUV ? new List <Vector4>() : null;

            for (int i = 0; i < m_OutputPointCount; ++i)
            {
                if (i % 64 == 0)
                {
                    var cancel = EditorUtility.DisplayCancelableProgressBar("pCache bake tool", string.Format("Sampling data... {0}/{1}", i, m_OutputPointCount), (float)i / (float)m_OutputPointCount);
                    if (cancel)
                    {
                        return(null);
                    }
                }

                var vertex = picker.GetNext();
                positions.Add(vertex.position);
                if (m_ExportNormals)
                {
                    normals.Add(vertex.normal);
                }
                if (m_ExportColors)
                {
                    colors.Add(vertex.color);
                }
                if (m_ExportUV)
                {
                    uvs.Add(vertex.uvs.Any() ? vertex.uvs[0] : Vector4.zero);
                }
            }

            var file = new PCache();

            file.AddVector3Property("position");
            if (m_ExportNormals)
            {
                file.AddVector3Property("normal");
            }
            if (m_ExportColors)
            {
                file.AddColorProperty("color");
            }
            if (m_ExportUV)
            {
                file.AddVector4Property("uv");
            }

            EditorUtility.DisplayProgressBar("pCache bake tool", "Generating pCache...", 0.0f);
            file.SetVector3Data("position", positions);
            if (m_ExportNormals)
            {
                file.SetVector3Data("normal", normals);
            }
            if (m_ExportColors)
            {
                file.SetColorData("color", colors);
            }
            if (m_ExportUV)
            {
                file.SetVector4Data("uv", uvs);
            }

            EditorUtility.ClearProgressBar();
            return(file);
        }
        void OnGUI_Texture()
        {
            GUILayout.Label("Texture baking", EditorStyles.boldLabel);

            m_Texture = (Texture2D)EditorGUILayout.ObjectField("Texture", m_Texture, typeof(Texture2D), false);

            m_DecimationThresholdMode = (DecimationThresholdMode)EditorGUILayout.EnumPopup("Decimation Threshold", m_DecimationThresholdMode);
            if (m_DecimationThresholdMode != DecimationThresholdMode.None)
            {
                m_Threshold = EditorGUILayout.Slider("Threshold", m_Threshold, 0.0f, 1.0f);
            }

            m_RandomizePixels = EditorGUILayout.Toggle("Randomize Pixels Order", m_RandomizePixels);
            if (m_RandomizePixels)
            {
                m_SeedPixels = EditorGUILayout.IntField("Seed", m_SeedPixels);
            }
            m_ExportColors = EditorGUILayout.Toggle("Export Colors", m_ExportColors);

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

            if (m_Texture != null)
            {
                if (GUILayout.Button("Save to pCache file..."))
                {
                    string fileName = EditorUtility.SaveFilePanelInProject("pCacheFile", m_Texture.name, "pcache", "Save PCache");
                    if (fileName != null)
                    {
                        PCache file = new PCache();
                        file.AddVector3Property("position");
                        if (m_ExportColors)
                        {
                            file.AddColorProperty("color");
                        }

                        List <Vector3> positions = new List <Vector3>();
                        List <Vector4> colors    = null;

                        if (m_ExportColors)
                        {
                            colors = new List <Vector4>();
                        }

                        ComputeTextureData(positions, colors);
                        file.SetVector3Data("position", positions);
                        if (m_ExportColors)
                        {
                            file.SetColorData("color", colors);
                        }

                        file.SaveToFile(fileName, m_OutputFormat);
                    }
                }

                using (new GUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    EditorGUILayout.LabelField("Texture Statistics", EditorStyles.boldLabel);
                    EditorGUI.indentLevel++;
                    EditorGUILayout.IntField("Width", m_Texture.width);
                    EditorGUILayout.IntField("Height", m_Texture.height);
                    EditorGUILayout.IntField("Pixels count", m_Texture.width * m_Texture.height);
                    EditorGUI.indentLevel--;
                }
            }
        }