/// <summary> /// max /// 6 --------- 7 /// / | / | /// 2 --------- 3 | /// | | | | /// | | | | /// | 4 --------- 5 /// | / | / /// 0 --------- 1 /// min /// </summary> public static void DrawAABB(Vector3 Min, Vector3 Max, int level) { int idx = level % Colors.Length; // 6个面 // 8顶点索引和数据对应 Vector3[] vxt = new Vector3[8]; vxt[0] = new Vector3(Min[0], Min[1], Min[2]); vxt[1] = new Vector3(Max[0], Min[1], Min[2]); vxt[2] = new Vector3(Min[0], Max[1], Min[2]); vxt[3] = new Vector3(Max[0], Max[1], Min[2]); vxt[4] = new Vector3(Min[0], Min[1], Max[2]); vxt[5] = new Vector3(Max[0], Min[1], Max[2]); vxt[6] = new Vector3(Min[0], Max[1], Max[2]); vxt[7] = new Vector3(Max[0], Max[1], Max[2]); List <Vector3> polygon = new List <Vector3>(); // 近 polygon.Add(vxt[0]); polygon.Add(vxt[1]); polygon.Add(vxt[3]); polygon.Add(vxt[2]); GeoDebugDrawUtils.DrawPolygon(polygon, Colors[idx]); // 左 polygon.Clear(); polygon.Add(vxt[0]); polygon.Add(vxt[4]); polygon.Add(vxt[6]); polygon.Add(vxt[2]); GeoDebugDrawUtils.DrawPolygon(polygon, Colors[idx]); // 底 polygon.Clear(); polygon.Add(vxt[0]); polygon.Add(vxt[1]); polygon.Add(vxt[5]); polygon.Add(vxt[4]); GeoDebugDrawUtils.DrawPolygon(polygon, Colors[idx]); // 右 polygon.Clear(); polygon.Add(vxt[1]); polygon.Add(vxt[5]); polygon.Add(vxt[7]); polygon.Add(vxt[3]); GeoDebugDrawUtils.DrawPolygon(polygon, Colors[idx]); // 远 polygon.Clear(); polygon.Add(vxt[4]); polygon.Add(vxt[5]); polygon.Add(vxt[7]); polygon.Add(vxt[6]); GeoDebugDrawUtils.DrawPolygon(polygon, Colors[idx]); // 上 polygon.Clear(); polygon.Add(vxt[2]); polygon.Add(vxt[3]); polygon.Add(vxt[7]); polygon.Add(vxt[6]); GeoDebugDrawUtils.DrawPolygon(polygon, Colors[idx]); }
/// <summary> /// 根据相机位置,获得所在区域,然后获取Box可见面构造的轮廓 /// max /// 6 --------- 7 /// / | / | /// 2 --------- 3 | /// | | | | /// | | | | /// | 4 --------- 5 /// | / | / /// 0 --------- 1 /// min /// </summary> /// <param name="box">查询Box的可见性</param> /// <returns></returns> private int QueryBox(ref OOBox box) { Vector3 min = box.Min; Vector3 max = box.Max; // 8顶点索引和数据对应 Vector4[] vxt = new Vector4[8]; vxt[0] = new Vector4(min[0], min[1], min[2], 1); vxt[1] = new Vector4(max[0], min[1], min[2], 1); vxt[2] = new Vector4(min[0], max[1], min[2], 1); vxt[3] = new Vector4(max[0], max[1], min[2], 1); vxt[4] = new Vector4(min[0], min[1], max[2], 1); vxt[5] = new Vector4(max[0], min[1], max[2], 1); vxt[6] = new Vector4(min[0], max[1], max[2], 1); vxt[7] = new Vector4(max[0], max[1], max[2], 1); // 区域码计算 int cd = 0; if (mPosition[0] < min[0]) { // 左面之左 cd |= 1; } if (mPosition[0] > max[0]) { // 右面之右 cd |= 2; } if (mPosition[1] < min[1]) { // 下面之下 cd |= 4; } if (mPosition[1] > max[1]) { // 上面之上 cd |= 8; } if (mPosition[2] < min[2]) { // 进面之近 cd |= 16; } if (mPosition[2] > max[2]) { // 远面之远 cd |= 32; } // 到这一步,已经过了截头体测试.物体均在相机视角内 // 索引相机能见到的顶点 int[] stt = STAB[cd]; // 数组0索引表示能见到的顶点数量,后面的数组索引记录Box的顶点索引 int vp = stt[0]; #if TEST_DRAW List <Vector3> polygon = new List <Vector3>(); List <Vector3> clipPolygon = new List <Vector3>(); #endif // 遍历顶点 for (int i = 0; i < vp; i++) { // 获得顶点索引 int j = stt[i + 1]; // 将顶点变换到裁剪空间 mClip.mClipSpaceVertices[i] = mPV * vxt[j]; #if TEST_DRAW polygon.Add(vxt[j]); // 裁剪前 clipPolygon.Add(mClip.mClipSpaceVertices[i] * (1 / mClip.mClipSpaceVertices[i][3])); #endif } #if TEST_DRAW // 绘制可见多边形 GeoDebugDrawUtils.DrawPolygon(polygon, Color.red); GeoDebugDrawUtils.DrawPolygon(clipPolygon, Color.red); DrawNDCBox(); #endif // 对Box的轮廓进行裁剪计算,返回裁剪后的顶点数 vp = mClip.ClipAndProject(vp); #if TEST_DRAW clipPolygon.Clear(); // z 方向上 偏移 0.01 Vector4 offset = new Vector4(0, 0, 0.01f, 0); for (int i = 0; i < vp; ++i) { clipPolygon.Add(offset + mClip.mClipSpaceVertices[i]); } // 裁剪后 GeoDebugDrawUtils.DrawPolygon(clipPolygon, Color.blue); #endif if (vp < 3) { return(0); } int res = Map.QueryPolygon(mClip.mScreenSpaceVertices, vp); return(res); }
public void DrawAABB() { GeoDebugDrawUtils.DrawAABB(Box.Min, Box.Max, Level); }