Desc:
用于减少场景中物体的数量
原理
将地图分为存在上限的树,树每个非根节点可以最大存在四个子节点,物体如果存在两个及以上区域的时候,挂载在上一层节点上
实现
接口
INode.cs:
Bounds bound{get;set;}
// 初始化节点
void InsertNodeData(NodeData data);
// 在视角内,检查当前节点是否在摄像机裁剪区域内,不在则调用 Outside 回收
void Inside(Camera camera);
// 不在视角
void Outside(Camera camera);
// 编辑器模式下进行绘制
void DrawBound();
类
Node.cs:
实现INode接口,定义深度和子节点
Tree.cs:
定义最大层数
NodeData.cs:
存储每个节点的数据,通过编辑器初始化
NodeManager.cs:
持有当前场景中所有节点的引用,控制节点的加载和释放
QuadTreeManager.cs:
在Update中,调用tree的Inside
方法:
拓展 Bounds
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public static bool CheckBoundIsInCamera(this Bounds bound, Camera camera, float viewRatio = 1) { System.Func<Vector4, int> ComputeOutCode = (projectionPos) => { int _code = 0; if (projectionPos.x < -projectionPos.w) _code |= 1; if (projectionPos.x > projectionPos.w) _code |= 2; if (projectionPos.y < -projectionPos.w) _code |= 4; if (projectionPos.y > projectionPos.w) _code |= 8; if (projectionPos.z < -projectionPos.w) _code |= 16; if (projectionPos.z > projectionPos.w) _code |= 32; return _code; };
Vector4 worldPos = Vector4.one; int code = 63; for (int i = -1; i <= 1; i += 2) { for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { worldPos.x = bound.center.x + i * bound.extents.x; worldPos.y = bound.center.y + j * bound.extents.y; worldPos.z = bound.center.z + k * bound.extents.z;
code &= ComputeOutCode(camera.projectionMatrix * camera.worldToCameraMatrix * worldPos * viewRatio); } } } return code == 0 ? true : false; }
|
参考
github