コード例 #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));
        }
コード例 #2
0
        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;
            }
        }
コード例 #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;
 }
コード例 #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 );
     //}
 }
コード例 #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());
        }
コード例 #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);
        }
コード例 #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;
        }
コード例 #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());
        }
コード例 #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
 }
コード例 #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;
            }
        }
コード例 #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);
        }
コード例 #12
0
        // Helpers
        private static bool Filter(Triangle triangle, Decal decal)
        {
            var normal = GetNormal(triangle);

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