// obtain the level 0 node that associates with the given pos. public static BlockVectorNode readNode(IntVector3 atpos, BlockVectorNode root) { // calculate the index of the child in which the split will happen. int ind = 0; BlockVectorNode cur = root; IntVector3 nodeCenterPos = IntVector3.Zero; while (cur.pos.w != 0) { nodeCenterPos.x = cur.pos.x + cur.logicalSize / 2; nodeCenterPos.y = cur.pos.y + cur.logicalSize / 2; nodeCenterPos.z = cur.pos.z + cur.logicalSize / 2; ind = ((atpos.x >= nodeCenterPos.x) ? 1 : 0) | ((atpos.y >= nodeCenterPos.y) ? 2 : 0) | ((atpos.z >= nodeCenterPos.z) ? 4 : 0); if (cur.isLeaf) { cur.Split(); } cur = cur.children[ind] as BlockVectorNode; } return(cur); }
// this function should only be used by the root node. public BlockVectorNode reroot(IntVector3 atpos) { if (covers(atpos) == false) { // make a new node that can cover atpos IntVector4 newRootPos = new IntVector4(pos.XYZ, pos.w + 1); int maskX = 0; int maskY = 0; int maskZ = 0; if (atpos.x < pos.x) { maskX = 1; } if (atpos.y < pos.y) { maskY = 1; } if (atpos.z < pos.z) { maskZ = 1; } newRootPos.x -= maskX * logicalSize; newRootPos.y -= maskY * logicalSize; newRootPos.z -= maskZ * logicalSize; BlockVectorNode newRoot = new BlockVectorNode(newRootPos, null, 0); this.parent = newRoot; newRoot.Split(); int thisOctant = maskX + (maskY << 1) + (maskZ << 2); newRoot.children[thisOctant] = null; newRoot.children[thisOctant] = this; this.octant = thisOctant; return(newRoot.reroot(atpos)); } return(this); }