예제 #1
0
        public void BuildDecal(Decal decal)
        {
            MeshFilter filter = decal.GetComponent <MeshFilter>();

            if (filter == null)
            {
                filter = decal.gameObject.AddComponent <MeshFilter>();
            }
            if (decal.GetComponent <Renderer>() == null)
            {
                decal.gameObject.AddComponent <MeshRenderer>();
            }
            decal.Material = decal.GetComponent <Renderer>().material;

            if (decal.Material == null || decal.Sprite == null)
            {
                filter.mesh = null;
                return;
            }

            _affectedObjects = GetAffectedObjects(decal.GetBounds(), decal.AffectedLayers);
            foreach (GameObject go in _affectedObjects)
            {
                DecalBuilder.BuildDecalForObject(decal, go);
            }
            DecalBuilder.Push(decal.PushDistance);

            Mesh mesh = DecalBuilder.CreateMesh();

            if (mesh != null)
            {
                mesh.name   = "DecalMesh";
                filter.mesh = mesh;
            }
        }
예제 #2
0
        public static void BuildDecalForObject(Decal decal, GameObject affectedObject)
        {
            Mesh affectedMesh = affectedObject.GetComponent <MeshFilter>().sharedMesh;

            if (affectedMesh == null)
            {
                return;
            }

            float maxAngle = decal.MaxAngle;

            Plane right = new Plane(Vector3.right, Vector3.right / 2f);
            Plane left  = new Plane(-Vector3.right, -Vector3.right / 2f);

            Plane top    = new Plane(Vector3.up, Vector3.up / 2f);
            Plane bottom = new Plane(-Vector3.up, -Vector3.up / 2f);

            Plane front = new Plane(Vector3.forward, Vector3.forward / 2f);
            Plane back  = new Plane(-Vector3.forward, -Vector3.forward / 2f);

            Vector3[] vertices         = affectedMesh.vertices;
            int[]     triangles        = affectedMesh.triangles;
            int       startVertexCount = _bufVertices.Count;

            Matrix4x4 matrix = decal.transform.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix;

            for (int i = 0; i < triangles.Length; i += 3)
            {
                int i1 = triangles[i];
                int i2 = triangles[i + 1];
                int i3 = triangles[i + 2];

                Vector3 v1 = matrix.MultiplyPoint(vertices[i1]);
                Vector3 v2 = matrix.MultiplyPoint(vertices[i2]);
                Vector3 v3 = matrix.MultiplyPoint(vertices[i3]);

                Vector3 side1  = v2 - v1;
                Vector3 side2  = v3 - v1;
                Vector3 normal = Vector3.Cross(side1, side2).normalized;

                if (Vector3.Angle(-Vector3.forward, normal) >= maxAngle)
                {
                    continue;
                }


                DecalPolygon poly = new DecalPolygon(v1, v2, v3);

                poly = DecalPolygon.ClipPolygon(poly, right);
                if (poly == null)
                {
                    continue;
                }
                poly = DecalPolygon.ClipPolygon(poly, left);
                if (poly == null)
                {
                    continue;
                }

                poly = DecalPolygon.ClipPolygon(poly, top);
                if (poly == null)
                {
                    continue;
                }
                poly = DecalPolygon.ClipPolygon(poly, bottom);
                if (poly == null)
                {
                    continue;
                }

                poly = DecalPolygon.ClipPolygon(poly, front);
                if (poly == null)
                {
                    continue;
                }
                poly = DecalPolygon.ClipPolygon(poly, back);
                if (poly == null)
                {
                    continue;
                }

                AddPolygon(poly, normal);
            }

            if (decal.Sprite)
            {
                GenerateTexCoords(startVertexCount, decal.Sprite);
            }
            else
            {
                int       textureWidth  = decal.Material.mainTexture.width;
                int       textureHeight = decal.Material.mainTexture.height;
                Texture2D textureData   = new Texture2D(textureWidth, textureHeight);
                Sprite.Create(textureData, new Rect(0, 0, textureWidth, textureHeight), new Vector2(textureWidth / 2, textureHeight / 2));
                GenerateTexCoords(startVertexCount, decal.Sprite);
            }
        }