public virtual Coords GetCoords() { AssertNotDeleted(); if (parent == null) { return(new Coords()); } var coords = new List <OctreeChildCoords> { OctreeChildCoords.FromIndex(indexInParent) }; var currentParent = parent; while (currentParent != null) { if (currentParent.parent != null) { coords.Add(OctreeChildCoords.FromIndex(currentParent.indexInParent)); } currentParent = currentParent.parent; } var coordsArray = new OctreeChildCoords[coords.Count]; for (var i = 0; i < coordsArray.Length; ++i) { coordsArray[i] = coords[coords.Count - 1 - i]; } return(new Coords(coordsArray)); }
private void AddRandomList() { var coordsList = new List <OctreeChildCoords>(); for (var i = 0; i < wantedDepth; ++i) { coordsList.Add(OctreeChildCoords.FromIndex((OctreeNode.ChildIndex)Random.Range(0, 8))); } var coords = new Coords(coordsList.ToArray()); var wantedTree = voxelTree; var dirtyTrees = new HashSet <VoxelTree>(); for (var i = 0; i < numAdd; ++i) { var result = wantedTree.GetNeighbourCoordsInfinite(coords, (NeighbourSide)Random.Range(0, 6)); if (result == null) { Debug.Log("wut"); break; } var neighbourCoordsResult = result.Value; wantedTree = (VoxelTree)neighbourCoordsResult.tree; coords = neighbourCoordsResult.coordsResult; wantedTree.GetRoot() .AddRecursive(coords) .SetItem(wantedTree.GetMaterialIndex(Random.Range(0, 3))); dirtyTrees.Add(wantedTree); } foreach (var dirtyTree in dirtyTrees) { dirtyTree.Render(); } }
private void ReplaceChild(ChildIndex childIndex, Node newChild) { Assert.AreEqual(newChild.bounds.extents * 2, bounds.extents); var childCoords = new Coords(new[] { OctreeChildCoords.FromIndex(childIndex) }); var childBounds = GetChildBounds(childCoords); Assert.AreEqual(newChild.bounds.center, childBounds.center); if (children == null) { children = new Node[8]; } else if (children[(int)childIndex] != null) { RemoveChild(childIndex); } childCount++; SetChild(childIndex, newChild); }
private void ProcSubtree(float tx0, float ty0, float tz0, float tx1, float ty1, float tz1, INode node, bool insideSolidNode, int currentDepth, int? wantedDepth, Coords nodeCoords) { if (!_intersectMultiple && results.Count > 0) { return; } if (tx1 < 0.0 || ty1 < 0.0 || tz1 < 0.0) { return; } if (_debug) { var entryDistance = Mathf.Max(tx0, ty0, tz0); Debug.DrawLine(_ray.origin, _ray.GetPoint(entryDistance), Color.red, 0, false); } if (wantedDepth == null) { if (node == null) { return; } if (node.IsSolid()) { ProcessTerminal(node, tx0, ty0, tz0); if (results.Count > 0) { return; } } } else { if (!insideSolidNode) { //didn't manage to get into a solid node if (node == null) { return; } insideSolidNode = node.IsSolid(); } if (insideSolidNode && currentDepth >= wantedDepth) { if (currentDepth == wantedDepth) { ProcessTerminal(nodeCoords, tx0, ty0, tz0); } else { //oops, went too deep!!! //trace back to wanted depth var newCoords = new OctreeChildCoords[wantedDepth.Value]; for (var i = 0; i < newCoords.Length; ++i) { newCoords[i] = nodeCoords.GetCoord(i); } ProcessTerminal(new Coords(newCoords), tx0, ty0, tz0); } if (results.Count > 0) { return; } } } if (_debug) { if (node != null) { var bounds = node.GetBounds(); DrawBounds(bounds, Color.white); } else { //inside solid node and still going strong baby! var bounds = _rootNode.GetChildBounds(nodeCoords); DrawBounds(bounds, Color.cyan); } } var txm = 0.5f * (tx0 + tx1); var tym = 0.5f * (ty0 + ty1); var tzm = 0.5f * (tz0 + tz1); var currNode = FirstNode(tx0, ty0, tz0, txm, tym, tzm); while (currNode < 8) { var childIndex = (OctreeNode.ChildIndex) (currNode ^ _dimensionFlipFlags); if (!_intersectMultiple && results.Count > 0) { return; } var nextDepth = currentDepth + 1; var childCoords = new Coords(nodeCoords, OctreeChildCoords.FromIndex(childIndex)); INode childNode; if (insideSolidNode) { childNode = null; } else { childNode = node.GetChild(childIndex); } switch (currNode) { //0= none //1 = only x //2 = only y //3 = 2 + 1 = y and x //4 = only z //5 = 4 + 1 = z and x //6 = 4 + 2 = z and y //7 = 4 + 2 + 1 = z and y and x //z sets 4, y set 2, x sets 1 //except if the bit is already set, then it can't set it again so 8 case 0: //0= none ProcSubtree(tx0, ty0, tz0, txm, tym, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 1, tym, 2, tzm, 4); break; case 1: //1 = only x ProcSubtree(txm, ty0, tz0, tx1, tym, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(tx1, 8, tym, 3, tzm, 5); break; case 2: //2 = only y ProcSubtree(tx0, tym, tz0, txm, ty1, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 3, ty1, 8, tzm, 6); break; case 3: //3 = 2 + 1 = y and x ProcSubtree(txm, tym, tz0, tx1, ty1, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(tx1, 8, ty1, 8, tzm, 7); break; case 4: //4 = only z ProcSubtree(tx0, ty0, tzm, txm, tym, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 5, tym, 6, tz1, 8); break; case 5: //5 = 4 + 1 = z and x ProcSubtree(txm, ty0, tzm, tx1, tym, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(tx1, 8, tym, 7, tz1, 8); break; case 6: //6 = 4 + 2 = z and y ProcSubtree(tx0, tym, tzm, txm, ty1, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 7, ty1, 8, tz1, 8); break; case 7: //7 = 4 + 2 + 1 = z and y and x ProcSubtree(txm, tym, tzm, tx1, ty1, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = 8; break; } } }
protected static NeighbourCoordsResult?GetNeighbourCoordsInfinite(TTree tree, Coords coords, NeighbourSide side, Func <NeighbourSide, bool, TTree> getOrCreateNeighbour, bool readOnly = false) { var coordsLength = coords.Length; if (coordsLength == 0) { var neighbourTree = getOrCreateNeighbour(side, readOnly); if (neighbourTree == null) { return(null); } // get the neighbour tree? return(new NeighbourCoordsResult(false, coords, neighbourTree)); } var newCoords = new OctreeChildCoords[coordsLength]; var hasLastCoords = false; var lastCoordX = 0; var lastCoordY = 0; var lastCoordZ = 0; for (var i = coordsLength - 1; i >= 0; --i) { var coord = coords.GetCoord(i); var currentX = coord.x; var currentY = coord.y; var currentZ = coord.z; if (hasLastCoords) { //let's check the lower _coords, if it's out of that bounds then we need to modify ourselves! var lastCoordUpdated = UpdateLastCoord( ref lastCoordX, ref currentX, ref lastCoordY, ref currentY, ref lastCoordZ, ref currentZ); if (lastCoordUpdated) { newCoords[i + 1] = new OctreeChildCoords(lastCoordX, lastCoordY, lastCoordZ); } } else { //final _coords! //update _coords from the side switch (side) { case NeighbourSide.Above: currentY += 1; break; case NeighbourSide.Below: currentY -= 1; break; case NeighbourSide.Right: currentX += 1; break; case NeighbourSide.Left: currentX -= 1; break; case NeighbourSide.Back: currentZ -= 1; break; case NeighbourSide.Forward: currentZ += 1; break; default: throw new ArgumentOutOfRangeException("side", side, null); } } var newCoord = new OctreeChildCoords(currentX, currentY, currentZ); newCoords[i] = newCoord; lastCoordX = currentX; lastCoordY = currentY; lastCoordZ = currentZ; hasLastCoords = true; } // we're at the end now if (hasLastCoords && (lastCoordX < 0 || lastCoordX > 1 || lastCoordY < 0 || lastCoordY > 1 || lastCoordZ < 0 || lastCoordZ > 1)) { //invalid _coords, out of bounds, pick neighbour voxelTree var neighbourTree = getOrCreateNeighbour(side, readOnly); if (neighbourTree == null) { return(null); } var currentX = lastCoordX; var currentY = lastCoordY; var currentZ = lastCoordZ; UpdateLastCoord(ref lastCoordX, ref currentX, ref lastCoordY, ref currentY, ref lastCoordZ, ref currentZ); newCoords[0] = new OctreeChildCoords(lastCoordX, lastCoordY, lastCoordZ); return(new NeighbourCoordsResult(false, new Coords(newCoords), neighbourTree)); } return(new NeighbourCoordsResult(true, new Coords(newCoords), tree)); }
public static Coords?GetNeighbourCoords(Coords coords, NeighbourSide side) { // var voxelTree = GetTree(); var coordsLength = coords.Length; if (coordsLength <= 0) { // get the neighbour tree? return(null); } var newCoords = new OctreeChildCoords[coordsLength]; var hasLastCoords = false; var lastCoordX = 0; var lastCoordY = 0; var lastCoordZ = 0; for (var i = coordsLength - 1; i >= 0; --i) { var coord = coords.GetCoord(i); var currentX = coord.x; var currentY = coord.y; var currentZ = coord.z; if (hasLastCoords) { //let's check the lower _coords, if it's out of that bounds then we need to modify ourselves! var lastCoordUpdated = UpdateLastCoord( ref lastCoordX, ref currentX, ref lastCoordY, ref currentY, ref lastCoordZ, ref currentZ); if (lastCoordUpdated) { newCoords[i + 1] = new OctreeChildCoords(lastCoordX, lastCoordY, lastCoordZ); } } else { //final _coords! //update _coords from the side switch (side) { case NeighbourSide.Above: currentY += 1; break; case NeighbourSide.Below: currentY -= 1; break; case NeighbourSide.Right: currentX += 1; break; case NeighbourSide.Left: currentX -= 1; break; case NeighbourSide.Back: currentZ -= 1; break; case NeighbourSide.Forward: currentZ += 1; break; default: throw new ArgumentOutOfRangeException("side", side, null); } } var newCoord = new OctreeChildCoords(currentX, currentY, currentZ); newCoords[i] = newCoord; lastCoordX = currentX; lastCoordY = currentY; lastCoordZ = currentZ; hasLastCoords = true; } // we're at the end now if (hasLastCoords && (lastCoordX < 0 || lastCoordX > 1 || lastCoordY < 0 || lastCoordY > 1 || lastCoordZ < 0 || lastCoordZ > 1)) { return(null); } return(new Coords(newCoords)); }
public void Bounds() { var testOctree = new TestOctree <int>(new Bounds(Vector3.zero, Vector3.one * 5)); var root = testOctree.GetRoot(); root.SubDivide(); var rootBounds = root.GetBounds(); Assert.AreEqual(Vector3.zero, rootBounds.center); var rootSize = rootBounds.size; Assert.AreEqual(Vector3.one * 5, rootSize); Assert.AreNotEqual(Vector3.one * 4, rootSize); // just to confirm vector equality var leftAboveBackIndex = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.LeftAboveBack); var childBounds = root.GetChildBounds(new Coords( new[] { leftAboveBackIndex })); Assert.AreEqual(rootBounds.center + Vector3.Scale(rootBounds.extents, new Vector3(-0.5f, 0.5f, -0.5f)), childBounds.center); var childNode = root.GetChild(OctreeNode.ChildIndex.LeftAboveBack); var actualChildBounds = childNode.GetBounds(); Assert.AreEqual(childBounds.center, actualChildBounds.center); Assert.AreEqual(childBounds.extents, actualChildBounds.extents); Assert.AreEqual(rootSize * 0.5f, childBounds.size ); var oldBounds = childBounds; childBounds = root.GetChildBounds(new Coords( new[] { leftAboveBackIndex, leftAboveBackIndex })); Assert.AreEqual(oldBounds.center + Vector3.Scale(oldBounds.extents, new Vector3(-0.5f, 0.5f, -0.5f)), childBounds.center); Assert.AreEqual(childBounds.center, Vector3.up * (rootSize.y * 0.25f) + Vector3.left * (rootSize.x * 0.25f) + Vector3.back * (rootSize.z * 0.25f) + Vector3.up * (rootSize.y * 0.125f) + Vector3.left * (rootSize.x * 0.125f) + Vector3.back * (rootSize.z * 0.125f) ); var parentChildBounds = childNode.GetChildBounds(new Coords(new[] { leftAboveBackIndex })); Assert.AreEqual(childBounds.center, parentChildBounds.center); Assert.AreEqual(childBounds.extents, parentChildBounds.extents); Assert.AreEqual(childBounds.size, rootSize * 0.25f ); var rightAboveBackIndex = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.RightAboveBack); oldBounds = childBounds; childBounds = root.GetChildBounds(new Coords( new[] { leftAboveBackIndex, leftAboveBackIndex, rightAboveBackIndex })); Assert.AreEqual(oldBounds.center + Vector3.Scale(oldBounds.extents, new Vector3(0.5f, 0.5f, -0.5f)), childBounds.center); Assert.AreEqual(childBounds.center, Vector3.left * (rootSize.x * 0.25f) + Vector3.up * (rootSize.y * 0.25f) + Vector3.back * (rootSize.z * 0.25f) + Vector3.left * (rootSize.x * 0.125f) + Vector3.up * (rootSize.y * 0.125f) + Vector3.back * (rootSize.z * 0.125f) + Vector3.right * (rootSize.x * 0.0625f) + Vector3.up * (rootSize.y * 0.0625f) + Vector3.back * (rootSize.z * 0.0625f) ); Assert.AreEqual(childBounds.size, rootSize * 0.125f ); //var belowForwardLeft = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.LeftBelowForward); //childBounds = root.GetChildBounds(new Coords( // new[] { // leftAboveBack, // leftAboveBack, // aboveBackRight, // belowForwardLeft // })); //count++; //up = up * 2 - 1; //right = right * 2 - 1; //forward = forward * 2 + 1; //Assert.AreEqual(13, up); //Assert.AreEqual(-11, right); //Assert.AreEqual(-13, forward); //Assert.AreEqual(childBounds.center, // (Vector3.up * (rootSize.y * up) + // Vector3.right * (rootSize.x * right) + // Vector3.forward * (rootSize.z * forward)) / Mathf.Pow(2, count) // ); //Assert.AreEqual(childBounds.center, // Vector3.up * (rootSize.y * 0.25f) + // Vector3.up * (rootSize.y * 0.125f) + // Vector3.up * (rootSize.y * 0.0625f) + // Vector3.up * (-rootSize.y * 0.03125f) + // Vector3.left * (rootSize.x * 0.25f) + // Vector3.left * (rootSize.x * 0.125f) + // Vector3.left * (-rootSize.x * 0.0625f) + // Vector3.left * (rootSize.x * 0.03125f) + // Vector3.back * (rootSize.z * 0.25f) + // Vector3.back * (rootSize.z * 0.125f) + // Vector3.back * (rootSize.z * 0.0625f) + // Vector3.back * (-rootSize.z * 0.03125f) // ); //Assert.AreEqual(childBounds.size, // rootSize * 0.0625f // ); }
private void ProcSubtree(float tx0, float ty0, float tz0, float tx1, float ty1, float tz1, INode node, bool insideSolidNode, int currentDepth, int?wantedDepth, Coords nodeCoords) { if (!_intersectMultiple && results.Count > 0) { return; } if (tx1 < 0.0 || ty1 < 0.0 || tz1 < 0.0) { return; } if (_debug) { var entryDistance = Mathf.Max(tx0, ty0, tz0); Debug.DrawLine(_ray.origin, _ray.GetPoint(entryDistance), Color.red, 0, false); } if (wantedDepth == null) { if (node == null) { return; } if (node.IsSolid()) { ProcessTerminal(node, tx0, ty0, tz0); if (results.Count > 0) { return; } } } else { if (!insideSolidNode) { //didn't manage to get into a solid node if (node == null) { return; } insideSolidNode = node.IsSolid(); } if (insideSolidNode && currentDepth >= wantedDepth) { if (currentDepth == wantedDepth) { ProcessTerminal(nodeCoords, tx0, ty0, tz0); } else { //oops, went too deep!!! //trace back to wanted depth var newCoords = new OctreeChildCoords[wantedDepth.Value]; for (var i = 0; i < newCoords.Length; ++i) { newCoords[i] = nodeCoords.GetCoord(i); } ProcessTerminal(new Coords(newCoords), tx0, ty0, tz0); } if (results.Count > 0) { return; } } } if (_debug) { if (node != null) { var bounds = node.GetBounds(); DrawBounds(bounds, Color.white); } else { //inside solid node and still going strong baby! var bounds = _rootNode.GetChildBounds(nodeCoords); DrawBounds(bounds, Color.cyan); } } var txm = 0.5f * (tx0 + tx1); var tym = 0.5f * (ty0 + ty1); var tzm = 0.5f * (tz0 + tz1); var currNode = FirstNode(tx0, ty0, tz0, txm, tym, tzm); while (currNode < 8) { var childIndex = (OctreeNode.ChildIndex)(currNode ^ _dimensionFlipFlags); if (!_intersectMultiple && results.Count > 0) { return; } var nextDepth = currentDepth + 1; var childCoords = new Coords(nodeCoords, OctreeChildCoords.FromIndex(childIndex)); INode childNode; if (insideSolidNode) { childNode = null; } else { childNode = node.GetChild(childIndex); } switch (currNode) { //0= none //1 = only x //2 = only y //3 = 2 + 1 = y and x //4 = only z //5 = 4 + 1 = z and x //6 = 4 + 2 = z and y //7 = 4 + 2 + 1 = z and y and x //z sets 4, y set 2, x sets 1 //except if the bit is already set, then it can't set it again so 8 case 0: //0= none ProcSubtree(tx0, ty0, tz0, txm, tym, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 1, tym, 2, tzm, 4); break; case 1: //1 = only x ProcSubtree(txm, ty0, tz0, tx1, tym, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(tx1, 8, tym, 3, tzm, 5); break; case 2: //2 = only y ProcSubtree(tx0, tym, tz0, txm, ty1, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 3, ty1, 8, tzm, 6); break; case 3: //3 = 2 + 1 = y and x ProcSubtree(txm, tym, tz0, tx1, ty1, tzm, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(tx1, 8, ty1, 8, tzm, 7); break; case 4: //4 = only z ProcSubtree(tx0, ty0, tzm, txm, tym, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 5, tym, 6, tz1, 8); break; case 5: //5 = 4 + 1 = z and x ProcSubtree(txm, ty0, tzm, tx1, tym, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(tx1, 8, tym, 7, tz1, 8); break; case 6: //6 = 4 + 2 = z and y ProcSubtree(tx0, tym, tzm, txm, ty1, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = NewNode(txm, 7, ty1, 8, tz1, 8); break; case 7: //7 = 4 + 2 + 1 = z and y and x ProcSubtree(txm, tym, tzm, tx1, ty1, tz1, childNode, insideSolidNode, nextDepth, wantedDepth, childCoords); currNode = 8; break; } } }
public void ToAndFromIndices() { var wantedCoords = new OctreeChildCoords(1, 1, 0); var actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.RightAboveBack); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.RightAboveBack, actualCoords.ToIndex()); //right wantedCoords = new OctreeChildCoords(wantedCoords.x, wantedCoords.y, 1); actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.RightAboveForward); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.RightAboveForward, actualCoords.ToIndex()); //left //back wantedCoords = new OctreeChildCoords(0, wantedCoords.y, 0); actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.LeftAboveBack); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.LeftAboveBack, actualCoords.ToIndex()); //right wantedCoords = new OctreeChildCoords(wantedCoords.x, wantedCoords.y, 1); actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.LeftAboveForward); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.LeftAboveForward, actualCoords.ToIndex()); //bot //left //fwd wantedCoords = new OctreeChildCoords(1, 0, 0); actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.RightBelowBack); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.RightBelowBack, actualCoords.ToIndex()); //right wantedCoords = new OctreeChildCoords(wantedCoords.x, wantedCoords.y, 1); actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.RightBelowForward); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.RightBelowForward, actualCoords.ToIndex()); //left //back wantedCoords = new OctreeChildCoords(0, wantedCoords.y, 0); actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.LeftBelowBack); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.LeftBelowBack, actualCoords.ToIndex()); //right wantedCoords = new OctreeChildCoords(wantedCoords.x, wantedCoords.y, 1); actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.LeftBelowForward); Assert.AreEqual(wantedCoords, actualCoords); Assert.AreEqual(OctreeNode.ChildIndex.LeftBelowForward, actualCoords.ToIndex()); Assert.Throws <ArgumentOutOfRangeException>( () => { actualCoords = OctreeChildCoords.FromIndex(OctreeNode.ChildIndex.Invalid); }); //and some invalid ones! Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(1, 0, -1).ToIndex()); Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(1, -1, 0).ToIndex()); Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(-1, 0, 0).ToIndex()); Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(0, 2, 1).ToIndex()); Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(2, 0, 1).ToIndex()); Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(0, 0, 2).ToIndex()); Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(2, 0, 2).ToIndex()); Assert.AreEqual(OctreeNode.ChildIndex.Invalid, new OctreeChildCoords(2, 2, 2).ToIndex()); }
public void Equality() { Assert.False(new OctreeChildCoords(1, 0, 1).Equals(null)); // hash collisions and general equality for (var i = 0; i < 8; i++) { var firstIndex = (OctreeNode.ChildIndex)i; for (var j = 0; j < 8; j++) { var secondIndex = (OctreeNode.ChildIndex)j; var firstCoordinate = OctreeChildCoords.FromIndex(firstIndex); var secondCoordinate = OctreeChildCoords.FromIndex(secondIndex); if (i == j) { Assert.AreEqual(firstCoordinate, secondCoordinate); Assert.AreEqual(firstCoordinate.GetHashCode(), secondCoordinate.GetHashCode()); } else { Assert.AreNotEqual(firstCoordinate, secondCoordinate); Assert.AreNotEqual(firstCoordinate.GetHashCode(), secondCoordinate.GetHashCode()); } } } Assert.AreEqual(new Coords(new Coords()), new Coords()); Assert.AreEqual(new OctreeChildCoords(new OctreeChildCoords()), new OctreeChildCoords()); Assert.AreEqual(new OctreeChildCoords(new OctreeChildCoords(1, 0, 0)), new OctreeChildCoords(1, 0, 0)); Assert.AreEqual(new OctreeChildCoords(new OctreeChildCoords(0, 1, 0)), new OctreeChildCoords(0, 1, 0)); Assert.AreEqual(new OctreeChildCoords(new OctreeChildCoords(0, 0, 1)), new OctreeChildCoords(0, 0, 1)); // same constructor, equal Assert.AreEqual(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) })); // construct from parent with no _coords Assert.AreEqual(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new Coords(), new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0))); // construct from parent with no _coords Assert.AreEqual(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new Coords(), new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0))); Assert.IsTrue(Equals(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new Coords(), new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0)))); Assert.IsFalse(Equals(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), null)); Assert.IsFalse(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }).Equals(null)); var a = new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }); var b = a; // ReSharper disable once EqualExpressionComparison Assert.IsTrue(a.Equals(a)); Assert.IsTrue(a.Equals(b)); // construct from parent with one coord Assert.AreEqual(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new Coords(new[] { new OctreeChildCoords(0, 0, 1) }), new OctreeChildCoords(0, 1, 0))); // construct from parent with two _coords Assert.AreEqual(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }))); // get parent Coords Assert.AreEqual(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0), new OctreeChildCoords(1, 1, 0) }).GetParentCoords()); // get parent Coords Assert.AreEqual(new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0) }), new Coords(new[] { new OctreeChildCoords(0, 0, 1), new OctreeChildCoords(0, 1, 0), new OctreeChildCoords(0, 1, 1) }).GetParentCoords()); }
public OctreeChildCoords(OctreeChildCoords other) { x = other.x; y = other.y; z = other.z; }
public bool Equals(OctreeChildCoords other) { return(z == other.z && y == other.y && x == other.x); }
public VoxelNode(Bounds bounds, VoxelNode parent, ChildIndex indexInParent, VoxelTree ocTree) : base(bounds, parent, indexInParent, ocTree) { _coords = new Coords(parent._coords, OctreeChildCoords.FromIndex(indexInParent)); }
public bool Equals(OctreeChildCoords other) { return z == other.z && y == other.y && x == other.x; }