677 lines
27 KiB
C#
677 lines
27 KiB
C#
using System.Collections.Generic;
|
||
using System.IO;
|
||
using UnityEngine;
|
||
using UnityEngine.SceneManagement;
|
||
|
||
namespace Thousandto.Launcher.ExternalLibs
|
||
{
|
||
/// <summary>
|
||
/// 遮挡处理
|
||
/// </summary>
|
||
public class OcclusionCullingUtil
|
||
{
|
||
private OcMapDataScript _ocDataScript = null;
|
||
private const string _rootName = "SceneRoot";
|
||
private GameObject _sceneRoot = null;
|
||
private List<OcNode> _childs = new List<OcNode>();
|
||
private List<RegionLimit> _limitList = new List<RegionLimit>();
|
||
private List<int> _colRowList = new List<int>();
|
||
//视口List
|
||
private List<MapPortal> _portalList = new List<MapPortal>();
|
||
private Dictionary<int, List<MapCell>> _dicMapCell = new Dictionary<int, List<MapCell>>();
|
||
//ocNode字典
|
||
private Dictionary<Transform, OcNode> _dicOcNode = new Dictionary<Transform, OcNode>();
|
||
//检查高度
|
||
private List<float> _verticalSize = new List<float> { 24f,25f, 26f, 27f, 28f, 30f};
|
||
//缓存手动添加了boxCollider的节点
|
||
private List<Transform> _cacheAddBoxTransList = new List<Transform>();
|
||
//地图的最小点和最大点
|
||
private Vector3 _min = Vector3.zero;
|
||
private Vector3 _max = Vector3.zero;
|
||
|
||
//测试
|
||
public List<OcDebugLine.TestLineDate> testLineList = new List<OcDebugLine.TestLineDate>();
|
||
public List<Bounds> textboundsList = new List<Bounds>();
|
||
|
||
public List<int> ColRowList
|
||
{
|
||
get
|
||
{
|
||
return _colRowList;
|
||
}
|
||
}
|
||
public Dictionary<int, List<MapCell>> DicMapCell
|
||
{
|
||
get
|
||
{
|
||
return _dicMapCell;
|
||
}
|
||
}
|
||
public Vector3 Min
|
||
{
|
||
get
|
||
{
|
||
return _min;
|
||
}
|
||
}
|
||
public Vector3 Max
|
||
{
|
||
get
|
||
{
|
||
return _max;
|
||
}
|
||
}
|
||
|
||
public List<float> VerticalSize
|
||
{
|
||
get
|
||
{
|
||
return _verticalSize;
|
||
}
|
||
}
|
||
|
||
#region//私有函数
|
||
//初始化Root
|
||
private void Init()
|
||
{
|
||
//初始化根节点 和所有render
|
||
if (_sceneRoot == null)
|
||
{
|
||
_sceneRoot = GameObject.Find(_rootName);
|
||
var debugScript = RequireComponent<OcDebugLine>(_sceneRoot);//_sceneRoot.AddComponent<OcDebugLine>();
|
||
debugScript.ocUtile = this;
|
||
}
|
||
_childs.Clear();
|
||
Renderer[] rds = _sceneRoot.GetComponentsInChildren<Renderer>(true);
|
||
if (rds != null)
|
||
{
|
||
for (int i = 0; i < rds.Length; i++)
|
||
{
|
||
OcNode node = new OcNode();
|
||
node.trans = rds[i].transform;
|
||
if (!node.trans.gameObject.activeSelf)
|
||
continue;
|
||
node.rd = rds[i];
|
||
_childs.Add(node);
|
||
if (!_dicOcNode.ContainsKey(node.trans))
|
||
{
|
||
_dicOcNode.Add(node.trans, node);
|
||
//判断是否有boxCollider
|
||
var collider = node.trans.GetComponent<BoxCollider>();
|
||
if (collider == null)
|
||
{
|
||
//添加boxCollider并且缓存
|
||
node.trans.gameObject.AddComponent<MeshCollider>();
|
||
_cacheAddBoxTransList.Add(node.trans);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//初始化cell限制条件
|
||
RegionLimit size1 = new RegionLimit(OcDefine.OC_Big, 5, int.MaxValue);
|
||
RegionLimit size2 = new RegionLimit(OcDefine.OC_Mid, 2, 5);
|
||
RegionLimit size3 = new RegionLimit(OcDefine.OC_Small, 0, 2);
|
||
_limitList.Add(size3);
|
||
_limitList.Add(size2);
|
||
_limitList.Add(size1);
|
||
|
||
//初始化数据保存脚本
|
||
_ocDataScript = ScriptableObject.CreateInstance<OcMapDataScript>();
|
||
|
||
//初始化地图大小
|
||
Vector2 min = Vector2.zero;
|
||
Vector2 max = Vector2.zero;
|
||
SetMapMinMax(min, max);
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
Init();
|
||
//把地图按照 大中小 三个不同尺寸划分成3组 part数据
|
||
for (int i = 0; i < (int)OcDefine.Count; i++)
|
||
{
|
||
SetCell(_min, _max, (OcDefine)i);
|
||
if (_dicMapCell.ContainsKey(i))
|
||
{
|
||
List<MapCell> listCell = _dicMapCell[i];
|
||
CheckChild(listCell, (OcDefine)i);
|
||
}
|
||
}
|
||
//把场景节点按照占位格子数划分到small mid big 三个类型的cell 中
|
||
for (int i = 0; i < (int)OcDefine.Count; i++)
|
||
{
|
||
for (int m = 0; m < _childs.Count; m++)
|
||
{
|
||
DifferentNode(_childs[m], (OcDefine)i);
|
||
}
|
||
}
|
||
for (int i = 0; i < _childs.Count; i++)
|
||
{
|
||
_childs[i].SetRealRefrenceCellIds();
|
||
}
|
||
//设置视口
|
||
SetPortal(_min,_max);
|
||
CalculatePVS();
|
||
//清除缓存的collider
|
||
for (int i = 0; i < _cacheAddBoxTransList.Count; i++)
|
||
{
|
||
Object.DestroyImmediate(_cacheAddBoxTransList[i].GetComponent<MeshCollider>());
|
||
}
|
||
//设置数据脚本数据
|
||
List<OcMapDataScript.PortalVisableData> portalVisableList = new List<OcMapDataScript.PortalVisableData>();
|
||
var enumer = _ocDataScript.dicPortalVisable.GetEnumerator();
|
||
try
|
||
{
|
||
while (enumer.MoveNext())
|
||
{
|
||
OcMapDataScript.PortalVisableData data = new OcMapDataScript.PortalVisableData();
|
||
data.portalId = enumer.Current.Key;
|
||
data.pathList = enumer.Current.Value;
|
||
portalVisableList.Add(data);
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
enumer.Dispose();
|
||
}
|
||
_ocDataScript.visableArray = portalVisableList.ToArray();
|
||
_ocDataScript.colRow = _colRowList[(int)OcDefine.OC_Small];
|
||
#if UNITY_EDITOR
|
||
//保存数据脚本资源
|
||
string savePath = "GameAssets/Resources/Scene/OcclusionCulling";
|
||
string floderPath = Application.dataPath + "/" + savePath;
|
||
if (!Directory.Exists(floderPath))
|
||
Directory.CreateDirectory(floderPath);
|
||
string sceneName = SceneManager.GetActiveScene().name;
|
||
string assetName = string.Format("{0}_OcMapScript.asset", sceneName);
|
||
savePath = string.Format("Assets/{0}/{1}", savePath, assetName);
|
||
UnityEditor.AssetDatabase.CreateAsset(_ocDataScript, savePath);
|
||
UnityEditor.AssetDatabase.SaveAssets();
|
||
//保存场景
|
||
UnityEditor.SceneManagement.EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
|
||
#endif
|
||
}
|
||
|
||
private void SetMapMinMax(Vector3 min, Vector3 max)
|
||
{
|
||
bool isInitMinMax = false;
|
||
for (int i = 0; i < _childs.Count; i++)
|
||
{
|
||
if (!_childs[i].trans.gameObject.activeSelf)
|
||
continue;
|
||
Vector3 childMin = Vector3.zero;
|
||
Vector3 childMax = Vector3.zero;
|
||
var rd = _childs[i].trans.GetComponent<Renderer>();
|
||
Mesh ms = null;
|
||
if (_childs[i].rd is MeshRenderer)
|
||
{
|
||
MeshFilter mf = _childs[i].trans.GetComponent<MeshFilter>();
|
||
ms = mf.sharedMesh;
|
||
_childs[i].rdType = OcRender.OC_MeshRender;
|
||
}
|
||
else if (_childs[i].rd is SkinnedMeshRenderer)
|
||
{
|
||
SkinnedMeshRenderer skinRender = _childs[i].trans.GetComponent<SkinnedMeshRenderer>();
|
||
ms = skinRender.sharedMesh;
|
||
_childs[i].rdType = OcRender.OC_SkinRender;
|
||
}
|
||
else if (_childs[i].rd is ParticleSystemRenderer)
|
||
{
|
||
_childs[i].rdType = OcRender.OC_PsRender;
|
||
}
|
||
for (int j = 0; ms != null && j < ms.vertexCount; j++)
|
||
{
|
||
Vector3 worldVec = _childs[i].trans.TransformPoint(ms.vertices[j]);
|
||
//获取最小坐标和最大坐标
|
||
if (!isInitMinMax)
|
||
{
|
||
min.x = worldVec.x;
|
||
min.y = worldVec.z;
|
||
max.x = worldVec.x;
|
||
max.y = worldVec.z;
|
||
isInitMinMax = true;
|
||
}
|
||
else
|
||
{
|
||
min.x = worldVec.x < min.x ? worldVec.x : min.x;
|
||
min.y = worldVec.z < min.y ? worldVec.z : min.y;
|
||
max.x = worldVec.x > max.x ? worldVec.x : max.x;
|
||
max.y = worldVec.z > max.y ? worldVec.z : max.y;
|
||
}
|
||
if (j == 0)
|
||
{
|
||
childMin.x = worldVec.x;
|
||
childMin.y = worldVec.z;
|
||
childMax.x = worldVec.x;
|
||
childMax.y = worldVec.z;
|
||
}
|
||
else
|
||
{
|
||
childMin.x = worldVec.x < childMin.x ? worldVec.x : childMin.x;
|
||
childMin.y = worldVec.z < childMin.y ? worldVec.z : childMin.y;
|
||
childMax.x = worldVec.x > childMax.x ? worldVec.x : childMax.x;
|
||
childMax.y = worldVec.z > childMax.y ? worldVec.z : childMax.y;
|
||
}
|
||
}
|
||
_childs[i].Min = childMin;
|
||
_childs[i].Max = childMax;
|
||
}
|
||
_min = min;
|
||
_max = max;
|
||
}
|
||
|
||
//设置视口
|
||
private void SetPortal(Vector2 min, Vector3 max)
|
||
{
|
||
//视口大小和最小格子尺寸一样
|
||
int colRow = 0;
|
||
float celWide = 0;
|
||
float wide = max.x - min.x;
|
||
float high = max.y - min.y;
|
||
OcCellWide ocWide = OcCellWide.OC_PortalWide;
|
||
|
||
SetCol_Row(wide, wide, ocWide, ref colRow);
|
||
celWide = wide / colRow;
|
||
float celHigh = high / colRow;
|
||
int count = (int)Mathf.Pow(colRow, 2);
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
MapPortal portal = new MapPortal(i, colRow, celWide, celHigh, min);
|
||
//设置视口上的射线起点
|
||
int pointCount = (int)ocWide * 2;
|
||
portal.rayStartPointList = new List<Vector3>(pointCount);
|
||
for (int k = 0; k < pointCount; k++)
|
||
{
|
||
Vector3 point = new Vector3();
|
||
float x = UnityEngine.Random.Range(0, celWide);
|
||
float z = UnityEngine.Random.Range(0, celHigh);
|
||
|
||
point.x = portal.min.x + x;
|
||
point.z = portal.min.z + z;
|
||
portal.rayStartPointList.Add(point);
|
||
}
|
||
_portalList.Add(portal);
|
||
}
|
||
}
|
||
|
||
//设置cell
|
||
public void SetCell(Vector2 min, Vector3 max, OcDefine type)
|
||
{
|
||
int colRow = 0;
|
||
float celWide = 0;
|
||
float wide = max.x - min.x;
|
||
float high = max.y - min.y;
|
||
OcCellWide ocWide = OcCellWide.OC_SmallWide;
|
||
switch (type)
|
||
{
|
||
case OcDefine.OC_Small:
|
||
ocWide = OcCellWide.OC_SmallWide;
|
||
break;
|
||
case OcDefine.OC_Mid:
|
||
ocWide = OcCellWide.OC_MideWide;
|
||
break;
|
||
case OcDefine.OC_Big:
|
||
ocWide = OcCellWide.OC_BigWide;
|
||
break;
|
||
}
|
||
|
||
SetCol_Row(wide, wide, ocWide, ref colRow);
|
||
celWide = wide / colRow;
|
||
float celHigh = high / colRow;
|
||
int count = (int)Mathf.Pow(colRow, 2);
|
||
_colRowList.Add(colRow);
|
||
List<MapCell> celList = new List<MapCell>();
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
MapCell cell = new MapCell(i, colRow, celWide, celHigh, min, type);
|
||
//设置cell射线终点
|
||
int endPointCount = GetCellEndRayPointCount(type);
|
||
cell.rayEndPointList = new List<Vector3>(endPointCount);
|
||
for (int k = 0; k < endPointCount; k++)
|
||
{
|
||
Vector3 point = new Vector3();
|
||
float x = UnityEngine.Random.Range(0, celWide);
|
||
float z = UnityEngine.Random.Range(0, celHigh);
|
||
|
||
point.x = cell.min.x + x;
|
||
point.z = cell.min.z + z;
|
||
cell.rayEndPointList.Add(point);
|
||
}
|
||
celList.Add(cell);
|
||
}
|
||
int key = (int)type;
|
||
if (!_dicMapCell.ContainsKey(key))
|
||
{
|
||
_dicMapCell.Add(key, celList);
|
||
}
|
||
}
|
||
|
||
//计算各个视口中显示的物件
|
||
private void CalculatePVS()
|
||
{
|
||
for (int i = 0; i < _portalList.Count; i++)
|
||
{
|
||
var enumer = _dicMapCell.GetEnumerator();
|
||
try
|
||
{
|
||
while(enumer.MoveNext())
|
||
{
|
||
List<MapCell> list = enumer.Current.Value;
|
||
if (list != null)
|
||
{
|
||
for (int k = 0; k < list.Count; k++)
|
||
{
|
||
CalculateCellPVS(list[k], _portalList[i]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
finally
|
||
{
|
||
enumer.Dispose();
|
||
}
|
||
}
|
||
}
|
||
|
||
//计算视口起始点和cell终点射线碰撞
|
||
private void CalculateCellPVS(MapCell cell, MapPortal portal)
|
||
{
|
||
for (int k = 0; k < portal.rayStartPointList.Count; k++)
|
||
{
|
||
Vector3 origin = portal.rayStartPointList[k];
|
||
List<float> heightList = new List<float>();
|
||
for (int i = 0; i < cell.rayEndPointList.Count; i++)
|
||
{
|
||
for (int j = 0; j < _verticalSize.Count; j++)
|
||
{
|
||
float height = _verticalSize[j];
|
||
Vector3 start = origin + Vector3.up * height;
|
||
//-----如果是最后一层 检查和第一层之间的斜线(主要处理有凹陷的物件, 水平方向无法检测碰撞)---//
|
||
heightList.Clear();
|
||
heightList.Add(_verticalSize[j]);
|
||
if (j == _verticalSize.Count -1)
|
||
{
|
||
heightList.Add(_verticalSize[0]);
|
||
}
|
||
//-----如果是最后一层 检查和第一层之间的斜线(主要处理有凹陷的物件, 水平方向无法检测碰撞)---//
|
||
for (int m = 0; m < heightList.Count; m++)
|
||
{
|
||
float endHeight = heightList[m];
|
||
Vector3 end = cell.rayEndPointList[i] + Vector3.up * endHeight;
|
||
Vector3 direction = (end - start).normalized;
|
||
float distance = Vector3.Distance(end, start);
|
||
RaycastHit hitInfo;
|
||
if (Physics.Raycast(start, direction, out hitInfo, distance))
|
||
{
|
||
if (portal.id == 175 && cell.id == 176)
|
||
{
|
||
UnityEngine.Debug.LogError(string.Format("碰撞物件的名称是 : {0}", hitInfo.collider.transform));
|
||
OcDebugLine.TestLineDate data = new OcDebugLine.TestLineDate();
|
||
data.star = start;
|
||
data.end = end;
|
||
testLineList.Add(data);
|
||
if (textboundsList.Count < 2)
|
||
{
|
||
Vector3 center = Vector3.zero;
|
||
center.x = portal.max.x - (portal.max.x - portal.min.x) / 2;
|
||
center.z = portal.max.z - (portal.max.z - portal.min.z) / 2;
|
||
var size = new Vector3(portal.max.x - portal.min.x, 400, portal.max.z - portal.min.z);
|
||
Bounds bounds = new Bounds(center, size);
|
||
bounds.min = new Vector3(portal.min.x, -200, portal.min.z);
|
||
bounds.max = new Vector3(portal.max.x, 200, portal.max.z);
|
||
textboundsList.Add(bounds);
|
||
textboundsList.Add(cell.bounds);
|
||
}
|
||
}
|
||
if (distance > 30)
|
||
continue;
|
||
Transform trans = hitInfo.collider.transform;
|
||
if (!_dicOcNode.ContainsKey(trans))
|
||
continue;
|
||
OcNode node = _dicOcNode[trans];
|
||
if (node == null)
|
||
continue;
|
||
if (node.type != cell.type)
|
||
continue;
|
||
List<int> list = node.GetRefrenceIds(cell.type);
|
||
if (list == null)
|
||
continue;
|
||
if (!list.Contains(cell.id))
|
||
continue;
|
||
if (portal.transList.Contains(trans))
|
||
continue;
|
||
portal.transList.Add(trans);
|
||
List<string> nameList = null;
|
||
string path = string.Empty;
|
||
path = GetTransPath(trans, path);
|
||
if (_ocDataScript.dicPortalVisable.ContainsKey(portal.id))
|
||
{
|
||
nameList = _ocDataScript.dicPortalVisable[portal.id];
|
||
nameList.Add(path);
|
||
}
|
||
else
|
||
{
|
||
nameList = new List<string>();
|
||
nameList.Add(path);
|
||
_ocDataScript.dicPortalVisable.Add(portal.id, nameList);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//设置格子行列 (行列相等)
|
||
private void SetCol_Row(float celWide, float wide, OcCellWide type, ref int colRow)
|
||
{
|
||
if (celWide > (int)type)
|
||
{
|
||
colRow += 1;
|
||
celWide = wide / colRow;
|
||
SetCol_Row(celWide, wide, type, ref colRow);
|
||
}
|
||
}
|
||
|
||
private void CheckChild(List<MapCell> listCell, OcDefine type)
|
||
{
|
||
//判断child所属区块
|
||
for (int i = 0; i < _childs.Count; i++)
|
||
{
|
||
Bounds bounds = new Bounds();
|
||
switch (_childs[i].rdType)
|
||
{
|
||
case OcRender.OC_MeshRender:
|
||
{
|
||
Mesh ms = _childs[i].trans.GetComponent<MeshFilter>().sharedMesh;
|
||
Transform trans = _childs[i].trans;
|
||
if (trans == null || ms == null)
|
||
break;
|
||
bounds = GetBounds(_childs[i], ms);
|
||
SetCommpentPart(listCell, type, _childs[i], bounds);
|
||
}
|
||
break;
|
||
case OcRender.OC_SkinRender:
|
||
{
|
||
SkinnedMeshRenderer skinnedRender = _childs[i].trans.GetComponent<SkinnedMeshRenderer>();
|
||
if (_childs[i].trans == null || skinnedRender.sharedMesh == null)
|
||
break;
|
||
bounds = GetBounds(_childs[i], skinnedRender.sharedMesh);
|
||
SetCommpentPart(listCell, type, _childs[i], bounds);
|
||
}
|
||
break;
|
||
case OcRender.OC_PsRender:
|
||
{
|
||
ParticleSystemRenderer prd = _childs[i].trans.GetComponent<ParticleSystemRenderer>();
|
||
SetCommpentPart(listCell, type, _childs[i]);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
private void SetCommpentPart(List<MapCell> listCell, OcDefine type, OcNode node, Bounds bounds)
|
||
{
|
||
for (int j = 0; j < listCell.Count; j++)
|
||
{
|
||
bool isLast = j == listCell.Count - 1 ? true : false;
|
||
//判断是否相交
|
||
bool isIntersects = listCell[j].Intersects(bounds);
|
||
if (isIntersects)
|
||
{
|
||
List<int> refrenceList = new List<int>();
|
||
if (node.dicRefrenceCellIds.ContainsKey((int)type))
|
||
{
|
||
refrenceList = node.dicRefrenceCellIds[(int)type];
|
||
refrenceList.Add(j);
|
||
}
|
||
else
|
||
{
|
||
refrenceList = new List<int>();
|
||
refrenceList.Add(j);
|
||
node.dicRefrenceCellIds.Add((int)type, refrenceList);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void SetCommpentPart(List<MapCell> listCell, OcDefine type, OcNode node)
|
||
{
|
||
for (int j = 0; j < listCell.Count; j++)
|
||
{
|
||
bool isLast = j == listCell.Count - 1 ? true : false;
|
||
//判断是否相交
|
||
Bounds bounds = GetParticleBounds(node);
|
||
bool isIntersects = listCell[j].Intersects(bounds);
|
||
if (isIntersects)
|
||
{
|
||
List<int> refrenceList = new List<int>();
|
||
if (node.dicRefrenceCellIds.ContainsKey((int)type))
|
||
{
|
||
refrenceList = node.dicRefrenceCellIds[(int)type];
|
||
refrenceList.Add(j);
|
||
}
|
||
else
|
||
{
|
||
refrenceList = new List<int>();
|
||
refrenceList.Add(j);
|
||
node.dicRefrenceCellIds.Add((int)type, refrenceList);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private void DifferentNode(OcNode node, OcDefine type)
|
||
{
|
||
int min = 0;
|
||
int max = 0;
|
||
switch (type)
|
||
{
|
||
case OcDefine.OC_Small:
|
||
min = 0;
|
||
max = (int)OcCellWide.OC_SmallWide;
|
||
break;
|
||
case OcDefine.OC_Mid:
|
||
min = (int)OcCellWide.OC_SmallWide;
|
||
max = (int)OcCellWide.OC_MideWide;
|
||
break;
|
||
case OcDefine.OC_Big:
|
||
min = (int)OcCellWide.OC_MideWide;
|
||
max = (int)OcCellWide.OC_BigWide;
|
||
break;
|
||
}
|
||
float wide = (node.Max.x - node.Min.x)>= (node.Max.z - node.Min.z)? (node.Max.x - node.Min.x) : (node.Max.z - node.Min.z);
|
||
if (wide > min && wide <= max)
|
||
{
|
||
node.type = type;
|
||
node.realKey = (int)type;
|
||
}
|
||
}
|
||
|
||
private Bounds GetBounds(OcNode node, Mesh ms)
|
||
{
|
||
var center = node.trans.localToWorldMatrix.MultiplyPoint3x4(ms.bounds.center);
|
||
var extents = new Vector3(Mathf.Abs(center.x - node.Min.x), 10, Mathf.Abs(center.z - node.Min.y));
|
||
var childMin = center - extents;
|
||
var childMax = center + extents;
|
||
var bounds = new Bounds(center, extents * 2);
|
||
bounds.min = childMin;
|
||
bounds.max = childMax;
|
||
return bounds;
|
||
}
|
||
|
||
private Bounds GetParticleBounds(OcNode node)
|
||
{
|
||
Bounds bounds;
|
||
ParticleSystem ps = node.trans.GetComponent<ParticleSystem>();
|
||
var center = node.trans.position;
|
||
var extents = new Vector3(ps.shape.scale.x * node.trans.localScale.x / 2, 10, ps.shape.scale.y * node.trans.localScale.y / 2);
|
||
var childMin = center - extents;
|
||
var childMax = center + extents;
|
||
bounds = new Bounds(center, extents * 2);
|
||
bounds.min = childMin;
|
||
bounds.max = childMax;
|
||
return bounds;
|
||
}
|
||
|
||
//获取trans相对于SceneRoot的路径
|
||
private string GetTransPath(Transform trans, string path)
|
||
{
|
||
if (trans == null)
|
||
return path;
|
||
if(string.IsNullOrEmpty(path))
|
||
path = string.Format("{0}", trans.name);
|
||
else
|
||
path = string.Format("{0}/{1}", trans.name, path);
|
||
if (string.Equals(trans.name, "SceneRoot"))
|
||
return path;
|
||
return GetTransPath(trans.parent, path);
|
||
}
|
||
|
||
//获取cell上射线结束点个数
|
||
private int GetCellEndRayPointCount(OcDefine type)
|
||
{
|
||
int endPointCount = 0;
|
||
switch (type)
|
||
{
|
||
case OcDefine.OC_Small:
|
||
endPointCount = (int)OcCellWide.OC_SmallWide;
|
||
endPointCount = Random.Range(endPointCount, endPointCount * 2);
|
||
break;
|
||
case OcDefine.OC_Mid:
|
||
endPointCount = (int)OcCellWide.OC_MideWide;
|
||
endPointCount = Random.Range(endPointCount, endPointCount * 2);
|
||
break;
|
||
case OcDefine.OC_Big:
|
||
endPointCount = (int)OcCellWide.OC_BigWide;
|
||
endPointCount = Random.Range(endPointCount, endPointCount * 2);
|
||
break;
|
||
}
|
||
return endPointCount;
|
||
}
|
||
|
||
//获取或者添加脚本
|
||
private T RequireComponent<T>(GameObject go) where T : Component
|
||
{
|
||
T ret = go.GetComponent<T>();
|
||
if (ret == null)
|
||
{
|
||
ret = go.AddComponent<T>();
|
||
}
|
||
return ret;
|
||
}
|
||
#endregion
|
||
|
||
#region//公共函数
|
||
public static void StartBaker()
|
||
{
|
||
OcclusionCullingUtil oc = new OcclusionCullingUtil();
|
||
oc.Start();
|
||
}
|
||
#endregion
|
||
}
|
||
}
|
||
|
||
|