Main/Assets/Plugins/EditorHelp/SplitTerrain/PrefabLightmapInfo.cs
2025-01-25 04:38:09 +08:00

180 lines
5.4 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using UnityEngine;
namespace Thousandto.Editor.Test
{
[Serializable]
public class RendererInfo
{
//网格索引
public int MeshIndex = -1;
public int OldLightmapIndex = -1;
//原始场景中的uv缩放偏移信息
public Vector4 OldLightmapScaleOffset;
//新生成lightmap中uv信息
public Vector4 NewLightmapScaleOffset;
public Renderer SourceRenderer;
public Vector4 UV2Bound;
public void SetRendererDataWhileAwake()
{
if(SourceRenderer != null)
{
//lightmapIndex是动态变化的
//SourceRenderer.lightmapIndex = LightmapIndex;
SourceRenderer.lightmapScaleOffset = NewLightmapScaleOffset;
}
}
}
/// <summary>
/// 场景烘焙完后保存lightmap信息
/// </summary>
[ExecuteInEditMode]
public class PrefabLightmapInfo : MonoBehaviour
{
[SerializeField]
public RendererInfo[] RendererInfos;
public bool CalcUV2Bound = false;
[SerializeField]
public int MeshIndex = -1;
private int _lastLightmapIndex = -1;
void Awake()
{
if(Application.isPlaying)
{
for (int i = 0; RendererInfos != null && i < RendererInfos.Length; ++i)
{
RendererInfos[i].SetRendererDataWhileAwake();
}
}
}
public void OnBakeFinish()
{
var Renderers = GetComponentsInChildren<MeshRenderer>();
RendererInfos = new RendererInfo[Renderers.Length];
for (int i = 0; i < Renderers.Length; ++i)
{
RendererInfo rdInfo = new RendererInfo();
rdInfo.OldLightmapScaleOffset = Renderers[i].lightmapScaleOffset;
rdInfo.OldLightmapIndex = Renderers[i].lightmapIndex;
rdInfo.SourceRenderer = Renderers[i];
RendererInfos[i] = rdInfo;
}
}
public void SetMeshIndex(int meshIndex)
{
if (RendererInfos == null)
return;
for (int i = 0; i < RendererInfos.Length; ++i)
{
RendererInfos[i].MeshIndex = meshIndex;
}
MeshIndex = meshIndex;
}
public void SetLightmapScaleOffset(Renderer rd, Vector4 lightmapScaleOffset)
{
if (RendererInfos == null)
return;
for(int i =0; i < RendererInfos.Length; ++i)
{
if(RendererInfos[i].SourceRenderer == rd)
{
RendererInfos[i].NewLightmapScaleOffset = lightmapScaleOffset;
}
}
}
void Update()
{
if(CalcUV2Bound)
{
CalcUV2Bound = false;
for (int i = 0; i < RendererInfos.Length; ++i)
{
var mesh = RendererInfos[i].SourceRenderer.gameObject.GetComponent<MeshFilter>();
if(mesh != null)
{
var uv2 = GetMeshUV2(mesh.sharedMesh);
RendererInfos[i].UV2Bound = GetBounds(uv2, RendererInfos[i].SourceRenderer);
}
}
}
int lightmapIndex = Core.Asset.TerrainPrefabManager.Instance.GetLightmapIndexByMeshIndex(MeshIndex);
if(lightmapIndex != _lastLightmapIndex)
{
_lastLightmapIndex = lightmapIndex;
for (int i = 0; RendererInfos != null && i < RendererInfos.Length; ++i)
{
RendererInfos[i].SourceRenderer.lightmapIndex = lightmapIndex;
}
}
}
//如果不存在uv2则使用uv代替
public static Vector2[] GetMeshUV2(Mesh m)
{
var uv2 = m.uv2;
if (uv2 == null || uv2.Length == 0)
uv2 = m.uv;
return uv2;
}
/// <summary>
/// 计算该renderer在lightmap贴图中的包围范围
/// </summary>
/// <param name="uv">uv2光照uv</param>
/// <param name="r"></param>
/// <returns>(minx, miny, maxX, maxY)</returns>
public static Vector4 GetBounds(Vector2[] uv, Renderer r)
{
if (uv != null)
{
var __uv = new Vector2[uv.Length];
Array.Copy(uv, __uv, uv.Length);
uv = __uv;
var minx = float.MaxValue;
var miny = float.MaxValue;
var maxx = float.MinValue;
var maxy = float.MinValue;
for (var _j = 0; _j < uv.Length; ++_j)
{
var _uv = uv[_j];
if (_uv.x < minx)
{
minx = _uv.x;
}
if (_uv.y < miny)
{
miny = _uv.y;
}
if (_uv.x > maxx)
{
maxx = _uv.x;
}
if (_uv.y > maxy)
{
maxy = _uv.y;
}
}
var bounds = new Vector4(minx, miny, maxx, maxy);
return bounds;
}
return Vector4.zero;
}
}
}