static void DrawGizmoFor(CellMaker target, GizmoType gizmoType) { //測試2線段交叉 Gizmos.DrawLine(target.P0.position, target.P1.position); Gizmos.DrawLine(target.P2.position, target.P3.position); var colliderRects = target.colliderRects; if (colliderRects != null) { foreach (var rect in colliderRects) { DrawRect(rect, colliderColor); } } //outer var OuterQuadRect = target.GetOuterQuadRect(); foreach (var rect in OuterQuadRect) { DrawRect(rect, quadTreeOuter); } //innner var InnerQuadRect = target.GetInnerQuadRect(); foreach (var rect in InnerQuadRect) { DrawRect(rect, quadTreeInner); } var nodes = target.GetRawPath(); DrawPathList(nodes, target.nodeSize); var points = target.GetModifyPath(); DrawPathList(points, target.modifyNodeSize); if (target.showNodeLink) { var HorizontalLinks = QuadTreeConnectedNode.GetHorizontalLinks(); foreach (var link in HorizontalLinks) { DrawQuadTreeLink(link.from, link.to, quadTreeHorizontalLink); } var VerticaLinks = QuadTreeConnectedNode.GetVerticaLinks(); foreach (var link in VerticaLinks) { DrawQuadTreeLink(link.from, link.to, quadTreeVerticalLink); } } }
bool NodeCenterIsInColliderRects(QuadTreeConnectedNode node, IRect[] colliderRects) { for (var i = 0; i < colliderRects.Length; ++i) { var rect = colliderRects[i]; if (GeometryTool.IsContainCenterPoint(rect, node)) { return(true); } } return(false); }
bool NodeIsContainColliderRectsVertex(QuadTreeConnectedNode node, IRect[] colliderRects) { for (var i = 0; i < colliderRects.Length; ++i) { var rect = colliderRects[i]; if (node.IsContainRectVertex(rect)) { return(true); } } return(false); }
bool NodeIsIntersectWithColliderRects(QuadTreeConnectedNode node, IRect[] colliderRects) { for (var i = 0; i < colliderRects.Length; ++i) { var rect = colliderRects[i]; if (GeometryTool.IsIntersect(node, rect)) { return(true); } } return(false); }
void SetIsOuter(QuadTreeConnectedNode node, IRect[] colliderRects) { // 如果node的中心點在rect裡面 if (NodeCenterIsInColliderRects(node, colliderRects)) { node.SetIsOuter(false); } else { node.SetIsOuter(true); } }
public QuadTreeConnectedNode[] SplitTo4() { childs = new QuadTreeConnectedNode[4]; var nextLevel = level + 1; childs[0] = new QuadTreeConnectedNode(minX, centerX, minZ, centerZ, nextLevel); //左下 childs[1] = new QuadTreeConnectedNode(centerX, maxX, minZ, centerZ, nextLevel); //右下 childs[2] = new QuadTreeConnectedNode(centerX, maxX, centerZ, maxZ, nextLevel); //右上 childs[3] = new QuadTreeConnectedNode(minX, centerX, centerZ, maxZ, nextLevel); //左上 //Debug.Log(level); return(childs); }
void MakeConnectedVertical(QuadTreeConnectedNode downNode, QuadTreeConnectedNode upNode) { // 如果Pn裡的2個node都沒有child node,就為該2個node建立連結 if (!downNode.HasChild() && !upNode.HasChild()) { // https://plus.google.com/u/0/+XiangweiChiou/posts/EET3zRE8Awz if (!downNode.isOuter || !upNode.isOuter) { return; } downNode.upLink = new QuadTreeConnectedNode[1]; downNode.upLink[0] = upNode; upNode.downLink = new QuadTreeConnectedNode[1]; upNode.downLink[0] = downNode; verticalLinks.Add(new LinkInfo(downNode, upNode)); } else // 否則,向下遞迴找出邊界上子node,並相連 { var upSideNodes = new List <QuadTreeConnectedNode>(); if (!upNode.HasChild()) { upSideNodes.Add(upNode); } else { GetBorderNodes(upNode, new int[] { 0, 1 }, upSideNodes); } var downSideNodes = new List <QuadTreeConnectedNode>(); if (!downNode.HasChild()) { downSideNodes.Add(downNode); } else { GetBorderNodes(downNode, new int[] { 3, 2 }, downSideNodes); } connectTwoSide(false, downSideNodes, upSideNodes); } }
void MakeConnectedHorizontal(QuadTreeConnectedNode leftNode, QuadTreeConnectedNode rightNode) { // 如果Pn裡的2個node都沒有child node,就為該2個node建立連結 if (!leftNode.HasChild() && !rightNode.HasChild()) { // https://plus.google.com/u/0/+XiangweiChiou/posts/EET3zRE8Awz if (!leftNode.isOuter || !rightNode.isOuter) { return; } leftNode.rightLink = new QuadTreeConnectedNode[1]; leftNode.rightLink[0] = rightNode; rightNode.leftLink = new QuadTreeConnectedNode[1]; rightNode.leftLink[0] = leftNode; horizontalLinks.Add(new LinkInfo(leftNode, rightNode)); } else // 否則,向下遞迴找出邊界上子node,並相連 { var leftSideNodes = new List <QuadTreeConnectedNode>(); if (!leftNode.HasChild()) { leftSideNodes.Add(leftNode); } else { GetBorderNodes(leftNode, new int[] { 1, 2 }, leftSideNodes); } var rightSideNodes = new List <QuadTreeConnectedNode>(); if (!rightNode.HasChild()) { rightSideNodes.Add(rightNode); } else { GetBorderNodes(rightNode, new int[] { 0, 3 }, rightSideNodes); } connectTwoSide(true, leftSideNodes, rightSideNodes); } }
// 除了是四叉樹,所有葉節點彼此還會相連 public void GenerateQuadTreeConnectedNode() { var origin = GetOrigin(); var border = GetBorder(); quadTreeConnectedNode = new QuadTreeConnectedNode(origin.x, border.x, origin.z, border.z, 0); // 第1次直接split var nowTestNodes = quadTreeConnectedNode.SplitTo4(); var nextTestNodes = new List <QuadTreeConnectedNode>(); // 進行分裂 int count = maxSplitLevel - 1; for (var i = 1; i <= count; ++i) { // todo: 這裡暴力的把node和所有rect測試一次(雖然有提早return // 也許可以在每個node寫入需要測式的rect清單,做一些優化 foreach (var node in nowTestNodes) { var a = NodeIsIntersectWithColliderRects(node, colliderRects); var b = NodeIsContainColliderRectsVertex(node, colliderRects); if (a || b) // 如果有rect和node相交或是頂點在node裡面 { // 就把node分成4塊,並加入下一輪的測試清單 // 有分裂的話outer=true(預設值) nextTestNodes.AddRange(node.SplitTo4()); } else { SetIsOuter(node, colliderRects); } } nowTestNodes = nextTestNodes.ToArray(); nextTestNodes.Clear(); } // 分裂完後,還要測式1次 foreach (var node in nowTestNodes) { SetIsOuter(node, colliderRects); } }
static void GetBorderNodes(QuadTreeConnectedNode targetNode, int[] borderIndex, List <QuadTreeConnectedNode> list) { if (!targetNode.HasChild()) { return; } foreach (var index in borderIndex) { var nowChildNode = targetNode.childs[index]; if (nowChildNode.HasChild()) { GetBorderNodes(nowChildNode, borderIndex, list); } else { list.Add(nowChildNode); } } }
public void MakeConnected() { QuadTreeConnectedNode.ClearLinks(); quadTreeConnectedNode.MakeConnected(); }
public static void DrawQuadTreeLink(QuadTreeConnectedNode from, QuadTreeConnectedNode to, Color color) { Gizmos.color = color; Gizmos.DrawLine(from.GetCenter(), to.GetCenter()); }
float GetValue(QuadTreeConnectedNode node) { return(isLeftRight ? node.Width : node.Height); }
public LinkInfo(QuadTreeConnectedNode from, QuadTreeConnectedNode to) { this.from = from; this.to = to; }