// set a neighbor to this node public void SetNeighbor(en_NeighborDirection direction, CQuadtree pToNode, en_NeighborDirection directionFromThere) { if (pToNode.m_HasChildren) { // the other node has children, which means this node was in coarse resolution, // so find correct child to link to... // need to find which two of the 4 children // of the other node that links to the parent of this node or to this node itself // then, decide which of the two children is closer to this node // and update the correct (nearest) child to link to this node CQuadtree pCorrectNode = null; float dist = 0; byte neighDirection = 0; // for each child of that node... for (byte i=0; i<4; i++) { CQuadtree pChild = pToNode.m_Children[i]; // for each direction of that child of that node... for (byte j=0; j<4; j++) { // check if that child links from that direction to our parent if (pChild.m_Neighbors[j].node.Equals(m_Parent)) { if (pCorrectNode == null) { // as there is no best correct child yet, // temporarily selects that child as the correct pCorrectNode = pChild; neighDirection = j; dist = CMath.QuickDistance(pChild.m_Center, m_Center); break; } else { // check if this child is closer than // the currently selected as the closer child if (CMath.QuickDistance(pChild.m_Center, m_Center) < dist) { pCorrectNode = pChild; neighDirection = j; // as we can have only two childs // pointing to our own parent, and the other child has been scanned already, // we can safely bail out of the outer loop and stop searching i = 4; break; } } } else if (pChild.m_Neighbors[j].node == this) { // that child relinked to this node first // which means both nodes are at same level // so just get it and bail out pCorrectNode = pChild; neighDirection = j; // link back to that node m_Neighbors[(int)direction].node = pCorrectNode; m_Neighbors[(int)direction].directionThere = (en_NeighborDirection)neighDirection; // update edges of this node m_NeedsReedge = true; // bail out return; } } } if (pCorrectNode != null) { // link to that node m_Neighbors[(int)direction].node = pCorrectNode; m_Neighbors[(int)direction].directionThere = (en_NeighborDirection)neighDirection; // link that node back to this node pCorrectNode.m_Neighbors[neighDirection].node = this; pCorrectNode.m_Neighbors[neighDirection].directionThere = direction; // update edges and gaps m_NeedsReedge = true; pCorrectNode.m_NeedsReedge = true; // the other node was discarding resolution // because this node was at coarse level // now that both are at same level, // lets force the other node to use full mesh at the edge that links to this node pCorrectNode.m_GapFixMask |= (byte)(1 << neighDirection); pCorrectNode.m_Neighbors[neighDirection].isFixed = false; } } else { // the other node has no children... // so, the other node is at a coarse level // OR at same level (a brother node); // link directly to that node m_Neighbors[(int)direction].node = pToNode; m_Neighbors[(int)direction].directionThere = directionFromThere; m_Neighbors[(int)direction].node.m_NeedsReedge = true; // only this node needs to update edges and fix gaps m_NeedsReedge = true; m_GapFixMask |= (byte)(1 << (int)direction); m_Neighbors[(int)direction].isFixed = false; // the other node stays linked to the node it is already linked to. } }
// get a neighbor to this node public TNeighbor GetNeighbor(en_NeighborDirection direction) { return m_Neighbors[(int)direction]; }