Exemplo n.º 1
0
        private Texture2D CreateFaceMaskAlphaMaskTexture(float width, float height, Vector2[] uv, bool makeBothEyesTransparent = true, bool makeMouthTransparent = true)
        {
            if (uv.Length != 68 && uv.Length != 73)
            {
                throw new ArgumentException("Invalid face landmark points", "uv");
            }

            Vector2[] facialContourUVPoints = new Vector2[0];
            if (uv.Length == 68)
            {
                facialContourUVPoints = new Vector2[] {
                    uv[0],
                    uv[1],
                    uv[2],
                    uv[3],
                    uv[4],
                    uv[5],
                    uv[6],
                    uv[7],
                    uv[8],
                    uv[9],
                    uv[10],
                    uv[11],
                    uv[12],
                    uv[13],
                    uv[14],
                    uv[15],
                    uv[16],
                    uv[26],
                    uv[25],
                    uv[24],
                    uv[23],
                    uv[20],
                    uv[19],
                    uv[18],
                    uv[17]
                };
            }
            else if (uv.Length == 73)   // If landmark points of forehead exists.
            {
                facialContourUVPoints = new Vector2[] {
                    uv[0],
                    uv[1],
                    uv[2],
                    uv[3],
                    uv[4],
                    uv[5],
                    uv[6],
                    uv[7],
                    uv[8],
                    uv[9],
                    uv[10],
                    uv[11],
                    uv[12],
                    uv[13],
                    uv[14],
                    uv[15],
                    uv[16],
                    uv[68],
                    uv[69],
                    uv[70],
                    uv[71],
                    uv[72]
                };
            }

            Vector2[] rightEyeContourUVPoints = new Vector2[] {
                uv[36],
                uv[37],
                uv[38],
                uv[39],
                uv[40],
                uv[41]
            };

            Vector2[] leftEyeContourUVPoints = new Vector2[] {
                uv[42],
                uv[43],
                uv[44],
                uv[45],
                uv[46],
                uv[47]
            };

            Vector2[] mouthContourUVPoints = new Vector2[] {
                uv[60],
                uv[61],
                uv[62],
                uv[63],
                uv[64],
                uv[65],
                uv[66],
                uv[67]
            };

            Vector2[][] exclusionAreas;
            if (makeBothEyesTransparent == true && makeMouthTransparent == false)
            {
                exclusionAreas = new Vector2[][] { rightEyeContourUVPoints, leftEyeContourUVPoints };
            }
            else if (makeBothEyesTransparent == false && makeMouthTransparent == true)
            {
                exclusionAreas = new Vector2[][] { mouthContourUVPoints };
            }
            else if (makeBothEyesTransparent == true && makeMouthTransparent == true)
            {
                exclusionAreas = new Vector2[][] { rightEyeContourUVPoints, leftEyeContourUVPoints, mouthContourUVPoints };
            }
            else
            {
                exclusionAreas = new Vector2[][] {};
            }

            return(AlphaMaskTextureCreater.CreateAlphaMaskTexture(width, height, facialContourUVPoints, exclusionAreas));
        }
        private static void CreateFaceMaskPrefab()
        {
            float  width    = 512f;
            float  height   = 512f;
            string basePath = "Assets/FaceMaskExample/FaceMaskPrefab/";

            GameObject newObj = new GameObject("FaceMaskTrackedMesh");

            //Add MeshFilter Component.
            MeshFilter meshFilter = newObj.AddComponent <MeshFilter>();

            // Create Mesh.
            meshFilter.mesh = new Mesh();
            Mesh mesh = meshFilter.sharedMesh;

            mesh.name = "DlibFaceLandmark68Mesh";

            // Mesh_vertices
            Vector3[] vertices = new Vector3[68] {
                new Vector3(117, 250),
                new Vector3(124, 291),
                new Vector3(131, 330),
                new Vector3(136, 369),
                new Vector3(146, 404),
                new Vector3(167, 433),
                new Vector3(192, 459),
                new Vector3(222, 480),
                new Vector3(261, 485),
                new Vector3(300, 478),

                new Vector3(328, 453),
                new Vector3(353, 425),
                new Vector3(372, 394),
                new Vector3(383, 357),
                new Vector3(387, 319),
                new Vector3(392, 281),
                new Vector3(397, 241),
                new Vector3(135, 224),
                new Vector3(151, 205),
                new Vector3(175, 196),

                new Vector3(202, 192),
                //22^23
                new Vector3(228, 205),  //new Vector3(228, 197), y+10
                new Vector3(281, 205),  //new Vector3(281, 197), y+10

                new Vector3(308, 191),
                new Vector3(334, 195),
                new Vector3(358, 205),
                new Vector3(374, 222),
                new Vector3(255, 228),
                new Vector3(256, 254),
                new Vector3(257, 279),

                new Vector3(258, 306),
                new Vector3(230, 322),
                new Vector3(243, 325),
                new Vector3(259, 329),
                new Vector3(274, 324),
                new Vector3(288, 320),
                new Vector3(168, 237),
                new Vector3(182, 229),
                new Vector3(200, 229),
                new Vector3(214, 239),

                new Vector3(199, 241),
                new Vector3(182, 242),
                new Vector3(296, 238),
                new Vector3(310, 228),
                new Vector3(327, 228),
                new Vector3(341, 235),
                new Vector3(328, 240),
                new Vector3(311, 240),
                //49
                new Vector3(198, 372),  //new Vector3(198, 367), y+5

                new Vector3(219, 360),

                new Vector3(242, 357),
                new Vector3(261, 360),
                new Vector3(280, 357),
                new Vector3(301, 357),
                //55
                new Vector3(322, 367),  //new Vector3(322, 362), y+5

                new Vector3(303, 387),
                new Vector3(282, 396),
                new Vector3(261, 398),
                new Vector3(241, 396),
                new Vector3(218, 388),
                //61^65
                new Vector3(205, 373),  //new Vector3(205, 368), y+5
                new Vector3(242, 371),  //new Vector3(242, 366), y+5
                new Vector3(261, 373),  //new Vector3(261, 368), y+5
                new Vector3(280, 370),  //new Vector3(280, 365), y+5
                new Vector3(314, 368),  //new Vector3(314, 363) y+5

                new Vector3(281, 382),
                new Vector3(261, 384),
                new Vector3(242, 383)
            };

            Vector3[] vertices2 = (Vector3[])vertices.Clone();
            for (int j = 0; j < vertices2.Length; j++)
            {
                vertices2[j].x = (vertices2[j].x - width / 2f) / width;
                vertices2[j].y = (height / 2f - vertices2[j].y) / height;
            }
            mesh.vertices = vertices2;

            // Mesh_triangles
            int[] triangles = new int[327] {
                // Around the right eye 21
                0, 36, 1,
                1, 36, 41,
                1, 41, 31,
                41, 40, 31,
                40, 29, 31,
                40, 39, 29,
                39, 28, 29,
                39, 27, 28,
                39, 21, 27,
                38, 21, 39,
                20, 21, 38,
                37, 20, 38,
                37, 19, 20,
                18, 19, 37,
                18, 37, 36,
                17, 18, 36,
                0, 17, 36,

                // (inner right eye 4)
                36, 37, 41,
                37, 40, 41,
                37, 38, 40,
                38, 39, 40,

                // Around the left eye 21
                45, 16, 15,
                46, 45, 15,
                46, 15, 35,
                47, 46, 35,
                29, 47, 35,
                42, 47, 29,
                28, 42, 29,
                27, 42, 28,
                27, 22, 42,
                22, 43, 42,
                22, 23, 43,
                23, 44, 43,
                23, 24, 44,
                24, 25, 44,
                44, 25, 45,
                25, 26, 45,
                45, 26, 16,

                // (inner left eye 4)
                44, 45, 46,
                47, 44, 46,
                43, 44, 47,
                42, 43, 47,

                // Eyebrows, nose and cheeks 13
                20, 23, 21,
                21, 23, 22,
                21, 22, 27,
                29, 30, 31,
                29, 35, 30,
                30, 32, 31,
                30, 33, 32,
                30, 34, 33,
                30, 35, 34,
                1, 31, 2,
                2, 31, 3,
                35, 15, 14,
                35, 14, 13,

                // mouth 48
                33, 51, 50,
                32, 33, 50,
                31, 32, 50,
                31, 50, 49,
                31, 49, 48,
                3, 31, 48,
                3, 48, 4,
                4, 48, 5,
                48, 59, 5,
                5, 59, 6,
                59, 58, 6,
                58, 7, 6,
                58, 57, 7,
                57, 8, 7,
                57, 9, 8,
                57, 56, 9,
                56, 10, 9,
                56, 55, 10,
                55, 11, 10,
                55, 54, 11,
                54, 12, 11,
                54, 13, 12,
                35, 13, 54,
                35, 54, 53,
                35, 53, 52,
                34, 35, 52,
                33, 34, 52,
                33, 52, 51,

                48, 49, 60,
                48, 60, 59,
                49, 50, 61,
                49, 61, 60,
                60, 67, 59,
                59, 67, 58,
                50, 51, 61,
                51, 62, 61,
                67, 66, 58,
                66, 57, 58,
                51, 52, 63,
                51, 63, 62,
                66, 65, 56,
                66, 56, 57,
                52, 53, 63,
                53, 64, 63,
                65, 64, 55,
                65, 55, 56,
                53, 54, 64,
                64, 54, 55,

                // inner mouth 6
                60, 61, 67,
                61, 62, 67,
                62, 66, 67,
                62, 63, 65,
                62, 65, 66,
                63, 64, 65
            };
            mesh.triangles = triangles;

            // Mesh_uv
            Vector2[] uv = new Vector2[68];
            for (int j = 0; j < uv.Length; j++)
            {
                uv[j].x = vertices[j].x / width;
                uv[j].y = (height - vertices[j].y) / height;
            }
            mesh.uv  = uv;
            mesh.uv2 = (Vector2[])uv.Clone();

            mesh.RecalculateNormals();

            // Add Collider Component.
            MeshCollider meshCollider = newObj.AddComponent <MeshCollider>();

            meshCollider.sharedMesh = CreatePrimitiveQuadMesh();

            // Add Renderer Component.
            MeshRenderer meshRenderer = newObj.AddComponent <MeshRenderer>();
            Material     material     = new Material(Shader.Find("Hide/FaceMaskShader"));

            // Create alpha mask texture.
            Vector2[] facialContourUVPoints = new Vector2[] {
                uv [0],
                uv [1],
                uv [2],
                uv [3],
                uv [4],
                uv [5],
                uv [6],
                uv [7],
                uv [8],
                uv [9],
                uv [10],
                uv [11],
                uv [12],
                uv [13],
                uv [14],
                uv [15],
                uv [16],
                uv [26],
                uv [25],
                uv [24],
                uv [23],
                uv [20],
                uv [19],
                uv [18],
                uv [17]
            };

            /*
             * Vector2[] rightEyeContourUVPoints = new Vector2[]{
             *  uv[36],
             *  uv[37],
             *  uv[38],
             *  uv[39],
             *  uv[40],
             *  uv[41]
             * };
             *
             * Vector2[] leftEyeContourUVPoints = new Vector2[]{
             *  uv[42],
             *  uv[43],
             *  uv[44],
             *  uv[45],
             *  uv[46],
             *  uv[47]
             * };
             */

            Vector2[] mouthContourUVPoints = new Vector2[] {
                uv [60],
                uv [61],
                uv [62],
                uv [63],
                uv [64],
                uv [65],
                uv [66],
                uv [67]
            };

            Texture2D alphaMaskTexture     = AlphaMaskTextureCreater.CreateAlphaMaskTexture(width, height, facialContourUVPoints, /*rightEyeContourUVPoints, leftEyeContourUVPoints,*/ mouthContourUVPoints);
            string    alphaMaskTexturePath = basePath + "FaceMaskAlphaMask.png";

            byte[] pngData = alphaMaskTexture.EncodeToPNG();

            if (CreateWithoutFolder(basePath))
            {
                File.WriteAllBytes(alphaMaskTexturePath, pngData);
                AssetDatabase.ImportAsset(alphaMaskTexturePath, ImportAssetOptions.ForceUpdate);
                AssetDatabase.SaveAssets();

                Debug.Log("Create asset \"" + basePath + "FaceMaskAlphaMask.png\"");
            }

            TextureImporter importer = TextureImporter.GetAtPath(alphaMaskTexturePath) as TextureImporter;

            importer.textureType    = TextureImporterType.Default;
            importer.mipmapEnabled  = false;
            importer.wrapMode       = TextureWrapMode.Clamp;
            importer.maxTextureSize = 1024;
            //importer.textureFormat = TextureImporterFormat.RGBA16;
            EditorUtility.SetDirty(importer);
            AssetDatabase.ImportAsset(alphaMaskTexturePath, ImportAssetOptions.ForceUpdate);
            AssetDatabase.SaveAssets();

            GameObject.DestroyImmediate(alphaMaskTexture);
            alphaMaskTexture = AssetDatabase.LoadAssetAtPath(alphaMaskTexturePath, typeof(Texture2D)) as Texture2D;
            material.SetTexture("_MaskTex", alphaMaskTexture);
            meshRenderer.material = material;

            // Add TracedMesh Compornent.
            newObj.AddComponent <TrackedMesh>();

            // Save FaceMask Assets.
            if (CreateWithoutFolder(basePath))
            {
                AssetDatabase.CreateAsset(material, basePath + "FaceMaskMaterial.mat");
                AssetDatabase.CreateAsset(mesh, basePath + "DlibFaceLandmark68Mesh.asset");
                AssetDatabase.SaveAssets();

                string prefab_path = basePath + "FaceMaskTrackedMesh.prefab";

#if UNITY_2018_3_OR_NEWER
                PrefabUtility.SaveAsPrefabAsset(newObj, prefab_path);
#else
                UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(prefab_path, typeof(UnityEngine.Object));
                if (prefab == null)
                {
                    PrefabUtility.CreatePrefab(prefab_path, newObj);
                }
                else
                {
                    PrefabUtility.ReplacePrefab(newObj, prefab);
                }
#endif

                AssetDatabase.SaveAssets();

                Debug.Log("Create asset \"" + basePath + "FaceMaskMaterial.mat\"");
                Debug.Log("Create asset \"" + basePath + "DlibFaceLandmark68Mesh.asset\"");
                Debug.Log("Create asset \"" + basePath + "FaceMaskTrackedMesh.prefab\"");
            }

            GameObject.DestroyImmediate(newObj);
        }