private TValue SetValueInternal(OcNode node, int x, int y, int z, TValue value, bool isRemoving) { var existing = node[x & MASK, y & MASK, z & MASK]; if (existing == null) { if (!isRemoving) { node[x & MASK, y & MASK, z & MASK] = new OcSingle(x, y, z, value); } return(default(TValue)); } var child = existing as OcNode; if (child != null) { var ret = SetValueInternal(child, x >> SHIFT, y >> SHIFT, z >> SHIFT, value, isRemoving); if (child.IsEmpty) { node[x & MASK, y & MASK, z & MASK] = null; } return(ret); } var single = (OcSingle)existing; if (Equals(single.value, value)) { return(single.value); } if (single.x != x || single.y != y || single.z != z) { if (isRemoving) { return(default(TValue)); } var split = SplitSingle(node, single); return(SetValueInternal(split, x >> SHIFT, y >> SHIFT, z >> SHIFT, value, false)); } if (isRemoving) { node[x & MASK, y & MASK, z & MASK] = null; return(single.value); } var vv = single.value; single.value = value; return(vv); }
private OcNode SplitSingle(OcNode node, OcSingle single) { var child = new OcNode(); var sx = single.x; var sy = single.y; var sz = single.z; int x = sx >> SHIFT; int y = sy >> SHIFT; int z = sz >> SHIFT; child[x & MASK, y & MASK, z & MASK] = new OcSingle(x, y, z, single.value); node[sx & MASK, sy & MASK, sz & MASK] = child; return(child); }