From d19e008027370039d4b32fc5012f850daea8a35a Mon Sep 17 00:00:00 2001 From: z3y <33181641+z3y@users.noreply.github.com> Date: Thu, 16 Mar 2023 07:37:28 -0700 Subject: [PATCH] Update and rename PackLightmapGroupUV.cs to XatlasLightmapPacker.cs --- PackLightmapGroupUV.cs | 180 ------------------------------ XatlasLightmapPacker.cs | 235 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 180 deletions(-) delete mode 100644 PackLightmapGroupUV.cs create mode 100644 XatlasLightmapPacker.cs diff --git a/PackLightmapGroupUV.cs b/PackLightmapGroupUV.cs deleted file mode 100644 index bc255e9..0000000 --- a/PackLightmapGroupUV.cs +++ /dev/null @@ -1,180 +0,0 @@ -#if UNITY_EDITOR -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEditor; -using UnityEngine; - - -[ExecuteInEditMode] -public class PackLightmapGroupUV : MonoBehaviour -{ - public GameObject[] rootObjects; - public bool forceUpdate = false; - public bool clearStream = true; - - public int lightmapSize = 1024; - public int padding = 2; - - [SerializeField] public List meshCache = new List(); - - - - private void OnValidate() - { - if (!forceUpdate) - { - return; - } - - - var meshes = new List(); - GetActiveTransformsWithRenderers(rootObjects, out List renderers, out List filters, out List objects); - - if (meshCache.Count == 0 || meshCache.Count != objects.Count) - { - - - - for (int i = 0; i < objects.Count; i++) - { - var m_Renderer = renderers[i]; - - var mf = filters[i]; - var stream = m_Renderer.additionalVertexStreams; - var sm = mf.sharedMesh; - - - if (clearStream) - { - m_Renderer.additionalVertexStreams = null; - continue; - } - - Vector2[] lightmapUV; - var scale = m_Renderer.scaleInLightmap; - - var area = CalculateArea(sm); - scale *= Mathf.Sqrt(area); - - lightmapUV = new Vector2[sm.uv2.Length]; - - for (int j = 0; j < lightmapUV.Length; j++) - { - lightmapUV[j] = sm.uv2[j] * scale; - } - - - stream = new Mesh - { - vertices = sm.vertices, - normals = sm.normals, - uv = sm.uv, - uv2 = lightmapUV, - triangles = sm.triangles, - tangents = sm.tangents - }; - - var originalData = new Mesh - { - vertices = sm.vertices, - uv = sm.uv, - uv2 = sm.uv2 - }; - - - meshes.Add(stream); - - } - - if (clearStream) - { - return; - } - - - z3y.xatlas.PackLightmap(meshes.ToArray(), padding, lightmapSize); - - meshCache = new List(meshes.Count); - meshCache.AddRange(meshes); - } - - - for (int i = 0; i < meshCache.Count; i++) - { - var m_Renderer = renderers[i]; - var mf = filters[i]; - meshCache[i].UploadMeshData(false); - if (meshCache[i].vertices.Length != mf.sharedMesh.vertices.Length) - { - Debug.LogError("Vertex count not the same + " + mf.sharedMesh.name + " " + meshes[i].vertices.Length + " original: " + mf.sharedMesh.vertices.Length); - } - m_Renderer.additionalVertexStreams = meshCache[i]; - } - - } - - private void GetActiveTransformsWithRenderers(GameObject[] rootObjs, out List renderers, out List filters, out List obs) - { - - var roots = new List(); - - for (int i = 0; i < rootObjs.Length; i++) - { - var o = rootObjs[i]; - roots.AddRange(o.GetComponentsInChildren(false)); - } - roots.Distinct(); - - renderers = new List(); - filters = new List(); - obs = new List(); - - foreach (var root in roots) - { - var o = root.gameObject; - if (!o.activeInHierarchy || !o.isStatic) - { - continue; - } - - var r = root.GetComponent(); - var f = root.GetComponent(); - - if (!f || !r) - { - continue; - } - - obs.Add(o); - renderers.Add(r); - filters.Add(f); - } - } - - private float CalculateArea(Mesh mesh) - { - var verts = mesh.vertices; - float area = 0; - - for (int k = 0; k < mesh.subMeshCount; k++) - { - var indices = mesh.GetIndices(k); - for (int j = 0; j < indices.Length; j += 3) - { - var indexA = indices[j]; - var indexB = indices[j + 1]; - var indexC = indices[j + 2]; - - var v1 = verts[indexA]; // should be transformed position - var v2 = verts[indexB]; - var v3 = verts[indexC]; - area += Vector3.Cross(v2 - v1, v3 - v1).magnitude; - } - } - - return area; - } -} -#endif diff --git a/XatlasLightmapPacker.cs b/XatlasLightmapPacker.cs new file mode 100644 index 0000000..bc77f96 --- /dev/null +++ b/XatlasLightmapPacker.cs @@ -0,0 +1,235 @@ +#if UNITY_EDITOR +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; +using UnityEngine; +using UnityEngine.SceneManagement; +using Object = UnityEngine.Object; + +namespace z3y +{ + [ExecuteInEditMode] + public class XatlasLightmapPacker : MonoBehaviour + { + public GameObject[] rootObjects; + public bool forceUpdate = false; + public bool clearStream = true; + + public int lightmapSize = 1024; + public int padding = 2; + + [SerializeField] public LightmapMeshData[] meshCache; + + [Serializable] + public struct LightmapMeshData + { + public LightmapMeshData(Vector2[] uv) + { + lightmapUV = uv; + } + public Vector2[] lightmapUV; + } + + public static List instances = new List(); + + public void OnValidate() + { + if (!instances.Contains(gameObject)) + { + instances.Add(gameObject); + } + + if (!forceUpdate) + { + return; + } + + var meshes = new List(); + GetActiveTransformsWithRenderers(rootObjects, out List renderers, out List filters, out List objects); + + if (meshCache == null || meshCache.Length == 0 || meshCache.Length != objects.Count) + { + + + + for (int i = 0; i < objects.Count; i++) + { + var m_Renderer = renderers[i]; + + var mf = filters[i]; + var stream = m_Renderer.additionalVertexStreams; + var sm = mf.sharedMesh; + + + if (clearStream) + { + m_Renderer.additionalVertexStreams = null; + continue; + } + + Vector2[] lightmapUV; + var scale = m_Renderer.scaleInLightmap; + + var area = CalculateArea(sm); + scale *= Mathf.Sqrt(area); + + lightmapUV = new Vector2[sm.uv2.Length]; + + for (int j = 0; j < lightmapUV.Length; j++) + { + lightmapUV[j] = sm.uv2[j] * scale; + } + + + stream = new Mesh + { + vertices = sm.vertices, + normals = sm.normals, + uv = sm.uv, + uv2 = lightmapUV, + triangles = sm.triangles, + tangents = sm.tangents + }; + + meshes.Add(stream); + + } + + if (clearStream) + { + return; + } + + + z3y.xatlas.PackLightmap(meshes.ToArray(), padding, lightmapSize); + + meshCache = new LightmapMeshData[meshes.Count]; + for (int k = 0; k < meshCache.Length; k++) + { + var m = meshes[k]; + m.UploadMeshData(true); + meshCache[k] = new LightmapMeshData(m.uv2); + DestroyImmediate(m); + } + } + + + for (int i = 0; i < meshCache.Length; i++) + { + var m_Renderer = renderers[i]; + var mf = filters[i]; + if (meshCache[i].lightmapUV.Length != mf.sharedMesh.vertices.Length) + { + Debug.LogError("Vertex count not the same + " + mf.sharedMesh.name + " " + meshCache[i].lightmapUV.Length + " original: " + mf.sharedMesh.vertices.Length); + } + + var avs = m_Renderer.additionalVertexStreams; + var sm = mf.sharedMesh; + + if (avs == null) + { + avs = new Mesh + { + vertices = mf.sharedMesh.vertices, + uv2 = meshCache[i].lightmapUV + }; + } + else + { + if (avs.vertices == null || avs.vertices.Length != sm.vertices.Length) + { + avs.vertices = mf.sharedMesh.vertices; + } + avs.uv2 = meshCache[i].lightmapUV; + } + + m_Renderer.additionalVertexStreams = avs; + avs.UploadMeshData(false); + } + } + + private void GetActiveTransformsWithRenderers(GameObject[] rootObjs, out List renderers, out List filters, out List obs) + { + + var roots = new List(); + + for (int i = 0; i < rootObjs.Length; i++) + { + var o = rootObjs[i]; + roots.AddRange(o.GetComponentsInChildren(false)); + } + + roots.Distinct(); + + renderers = new List(); + filters = new List(); + obs = new List(); + + foreach (var root in roots) + { + var o = root.gameObject; + if (!o.activeInHierarchy || !o.isStatic) + { + continue; + } + + var r = root.GetComponent(); + var f = root.GetComponent(); + + if (!f || !r) + { + continue; + } + + obs.Add(o); + renderers.Add(r); + filters.Add(f); + } + } + + private float CalculateArea(Mesh mesh) + { + var verts = mesh.vertices; + float area = 0; + + for (int k = 0; k < mesh.subMeshCount; k++) + { + var indices = mesh.GetIndices(k); + for (int j = 0; j < indices.Length; j += 3) + { + var indexA = indices[j]; + var indexB = indices[j + 1]; + var indexC = indices[j + 2]; + + var v1 = verts[indexA]; // should be transformed position + var v2 = verts[indexB]; + var v3 = verts[indexC]; + area += Vector3.Cross(v2 - v1, v3 - v1).magnitude; + } + } + + return area; + } + } + + public class RemoveObjectOnBuild : IProcessSceneWithReport + { + public int callbackOrder => 0; + + public void OnProcessScene(Scene scene, BuildReport report) + { + var instances = XatlasLightmapPacker.instances; + + for (int i = 0; i < instances.Count; i++) + { + Object.DestroyImmediate(instances[i]); + } + } + } +} +#endif