Example #1
0
        public static Bounds GetBounds(Decal decal)
        {
            var transform = decal.transform;
            var size      = transform.lossyScale;
            var min       = -size / 2f;
            var max       = size / 2f;

            var vts = new Vector3[] {
                new Vector3(min.x, min.y, min.z),
                new Vector3(max.x, min.y, min.z),
                new Vector3(min.x, max.y, min.z),
                new Vector3(max.x, max.y, min.z),

                new Vector3(min.x, min.y, max.z),
                new Vector3(max.x, min.y, max.z),
                new Vector3(min.x, max.y, max.z),
                new Vector3(max.x, max.y, max.z),
            };

            vts = vts.Select(transform.TransformDirection).ToArray();
            min = vts.Aggregate(Vector3.Min);
            max = vts.Aggregate(Vector3.Max);

            return(new Bounds(transform.position, max - min));
        }
        internal static 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.GetComponent<Renderer>().material = decal.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)
            {
                filter.mesh = mesh;
            }
        }
Example #3
0
 public static void SetDirty(Decal decal)  /*
                                            * if (decal.gameObject.scene.IsValid()) {
                                            * if (!EditorApplication.isPlaying) EditorSceneManager.MarkSceneDirty( decal.gameObject.scene );return;
                                            * } else {
                                            * EditorUtility.SetDirty( decal.gameObject );
                                            * }*/
 {
     return;
 }
Example #4
0
 public static void SetDirty(Decal decal)
 {
     //if (decal.gameObject.scene.IsValid())
     //{
     //    if (!EditorApplication.isPlaying) EditorSceneManager.MarkSceneDirty( decal.gameObject.scene );
     //} else {
     //    EditorUtility.SetDirty( decal.gameObject );
     //}
 }
Example #5
0
        public static Terrain[] GetAffectedTerrains(Decal decal)
        {
            var bounds       = GetBounds(decal);
            var isOnlyStatic = decal.gameObject.isStatic;

            return(Terrain.activeTerrains
                   .Where(i => i.gameObject.isStatic || !isOnlyStatic)
                   .Where(i => HasLayer(decal.LayerMask, i.gameObject.layer))
                   .Where(i => bounds.Intersects(i.GetBounds()))
                   .ToArray());
        }
Example #6
0
        private static void Build_(MeshBuilder builder, Decal decal)
        {
            var objects            = DecalUtils.GetAffectedObjects(decal);
            var terrains           = DecalUtils.GetAffectedTerrains(decal);
            var bounds             = DecalUtils.GetBounds(decal);
            var worldToDecalMatrix = decal.transform.worldToLocalMatrix;

            var triangles1 = MeshUtils.GetTriangles(objects, worldToDecalMatrix).Where(i => Filter(i, decal));
            var triangles2 = TerrainUtils.GetTriangles(terrains, bounds, worldToDecalMatrix).Where(i => Filter(i, decal));

            AddTriangles(builder, triangles1);
            AddTriangles(builder, triangles2);
        }
Example #7
0
        public static void FixRatio(Decal decal, ref Vector3 oldScale)
        {
            var transform = decal.transform;
            var rect      = decal.Sprite.rect;
            var ratio     = rect.width / rect.height;

            var scale = transform.localScale;

            FixRatio(ref scale, ref oldScale, ratio);

            var hasChanged = transform.hasChanged;

            transform.localScale = scale;
            transform.hasChanged = hasChanged;
        }
Example #8
0
        public static MeshFilter[] GetAffectedObjects(Decal decal)
        {
            var bounds       = GetBounds(decal);
            var isOnlyStatic = decal.gameObject.isStatic;

            return(GameObject.FindObjectsOfType <MeshRenderer>()
                   .Where(i => i.GetComponent <Decal>() == null) // ignore another decals
                   .Where(i => i.gameObject.isStatic || !isOnlyStatic)
                   .Where(i => HasLayer(decal.LayerMask, i.gameObject.layer))
                   .Where(i => bounds.Intersects(i.bounds))

                   .Select(i => i.GetComponent <MeshFilter>())
                   .Where(i => i)
                   .Where(i => i.sharedMesh)
                   .ToArray());
        }
Example #9
0
 public static void SetDirty(Decal decal)
 {
     //edited by Alexy
     #if UNITY_EDITOR
     if (decal.gameObject.scene.IsValid())
     {
         if (!EditorApplication.isPlaying)
         {
             EditorSceneManager.MarkSceneDirty(decal.gameObject.scene);
         }
     }
     else
     {
         EditorUtility.SetDirty(decal.gameObject);
     }
     #endif
 }
Example #10
0
        private static void Build(MeshBuilder builder, Decal decal)
        {
            var filter   = decal.MeshFilter;
            var renderer = decal.MeshRenderer;

            if (decal.Material && decal.Sprite)
            {
                builder.Clear();
                Build_(builder, decal);
                filter.sharedMesh       = builder.ToMesh(filter.sharedMesh, GetUVRect(decal.Sprite), decal.Offset);
                renderer.sharedMaterial = decal.Material;
            }
            else
            {
                Object.DestroyImmediate(filter.sharedMesh);
                filter.sharedMesh       = null;
                renderer.sharedMaterial = null;
            }
        }
Example #11
0
        internal static void BuildDecalForObject(Decal decal, GameObject affectedObject)
        {
            var skinnedMeshRenderer = affectedObject.GetComponent<SkinnedMeshRenderer>();
            var meshFilter = affectedObject.GetComponent<MeshFilter>();

            Mesh affectedMesh = skinnedMeshRenderer == null ? meshFilter.sharedMesh : skinnedMeshRenderer.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);
            }

            GenerateTexCoords(startVertexCount, decal.sprite);
        }
Example #12
0
        // Helpers
        private static bool Filter(Triangle triangle, Decal decal)
        {
            var normal = GetNormal(triangle);

            return(Vector3.Angle(Vector3.back, normal) <= decal.MaxAngle);
        }
Example #13
0
 public static void Build(Decal decal)
 {
     Build(Builder, decal);
 }