180 lines
5.4 KiB
C#
180 lines
5.4 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|