コード例 #1
0
ファイル: SuperVoxelTree.cs プロジェクト: toxicFork/vox
        private void CreateNewNeighbourSuperVoxelTree(Node neighbourNode, NeighbourSide side)
        {
            var myBounds = GetBounds();

            var neighbourBounds = neighbourNode.GetBounds();

            Assert.AreEqual(neighbourBounds.extents, myBounds.extents);

            var myItem = GetItem();

            var myVoxelTree = myItem;

            if (myVoxelTree == null)
            {
                return;
            }

            var neighbourVoxelTree = new VoxelTree(neighbourBounds.center, neighbourBounds.size, false);

            var originalGameObject = myVoxelTree.GetGameObject();

            Assert.IsNotNull(originalGameObject, "Original game object should not be null!");

            var newGameObject = new GameObject(side + " neighbour for " + originalGameObject.name);

            newGameObject.transform.SetParent(originalGameObject.transform, false);

            neighbourVoxelTree.SetOwnerNode(neighbourNode);

            neighbourVoxelTree.SetGameObject(newGameObject);

            neighbourVoxelTree.CopyPropertiesFrom(myVoxelTree);

            neighbourNode.SetItem(neighbourVoxelTree);
        }
コード例 #2
0
	private static OctreeChildCoords[] GetChildCoordsOfSide(NeighbourSide side) {
		OctreeChildCoords[] childCoords;

		switch (side) {
			case NeighbourSide.Above:
				childCoords = AboveCoords;
				break;
			case NeighbourSide.Below:
				childCoords = BelowCoords;
				break;
			case NeighbourSide.Right:
				childCoords = RightCoords;
				break;
			case NeighbourSide.Left:
				childCoords = LeftCoords;
				break;
			case NeighbourSide.Back:
				childCoords = BackCoords;
				break;
			case NeighbourSide.Forward:
				childCoords = ForwardCoords;
				break;
			default:
				throw new ArgumentOutOfRangeException("side", side, null);
		}
		return childCoords;
	}
コード例 #3
0
	private void CreateFacesForSideInternal(ICollection<OctreeRenderFace> faces, NeighbourSide side,
		Bounds currentBounds,
		Coords coords, int meshIndex, bool parentPartial = false) {
		AssertNotDeleted();
		var sidestate = GetSideState(coords, side);

		switch (sidestate) {
			case SideState.FullButTransparent:
				if (!hasItem || !IsTransparent()) {
					AddFaceToList(faces, side, currentBounds, meshIndex);
				}
				break;
			case SideState.Empty:
				AddFaceToList(faces, side, currentBounds, meshIndex);
				break;
			case SideState.PartialButTransparent:
				if (IsTransparent()) {
					AddPartialFaces(faces, side, currentBounds, coords, meshIndex, parentPartial);
				} else {
					AddFaceToList(faces, side, currentBounds, meshIndex);
				}
				break;
			case SideState.Partial:
				AddPartialFaces(faces, side, currentBounds, coords, meshIndex, parentPartial);
				break;
			case SideState.Full:
				break;
			default:
				throw new ArgumentOutOfRangeException();
		}
	}
コード例 #4
0
ファイル: SuperVoxelTree.cs プロジェクト: toxicFork/vox
        private static ChildIndex GetWantedIndexInParent(NeighbourSide sideToGrowTowards)
        {
            switch (sideToGrowTowards)
            {
            case NeighbourSide.Above:
            case NeighbourSide.Right:
            case NeighbourSide.Forward:
                return(ChildIndex.LeftBelowBack);

            case NeighbourSide.Left:
                return(ChildIndex.RightBelowBack);

            case NeighbourSide.Back:
                return(ChildIndex.LeftBelowForward);

            case NeighbourSide.Below:
                return(ChildIndex.LeftAboveBack);

            case NeighbourSide.Invalid:
                throw new ArgumentOutOfRangeException("sideToGrowTowards", sideToGrowTowards, null);

            default:
                throw new ArgumentOutOfRangeException("sideToGrowTowards", sideToGrowTowards, null);
            }
        }
コード例 #5
0
ファイル: OctreeNode.cs プロジェクト: toxicFork/vox
    public static NeighbourSide GetOpposite(NeighbourSide side)
    {
        switch (side)
        {
        case NeighbourSide.Above:
            return(NeighbourSide.Below);

        case NeighbourSide.Below:
            return(NeighbourSide.Above);

        case NeighbourSide.Right:
            return(NeighbourSide.Left);

        case NeighbourSide.Left:
            return(NeighbourSide.Right);

        case NeighbourSide.Back:
            return(NeighbourSide.Forward);

        case NeighbourSide.Forward:
            return(NeighbourSide.Back);

        default:
            throw new ArgumentOutOfRangeException("side", side, null);
        }
    }
コード例 #6
0
ファイル: SuperVoxelTree.cs プロジェクト: toxicFork/vox
        private SuperVoxelTree ExpandRootAndReturnTree(NeighbourSide side, bool isReadOnly)
        {
            if (!GetRoot().CreateParentTowardsSide(side, isReadOnly))
            {
                return(null);
            }

            return(ocTree);
        }
コード例 #7
0
 public RayIntersectionResult(bool hit)
 {
     this.hit = hit;
     node = null;
     _coords = new Coords();
     entryDistance = 0;
     position = new Vector3();
     normal = new Vector3();
     neighbourSide = NeighbourSide.Invalid;
     tree = null;
 }
コード例 #8
0
    private VoxelTree GetOrCreateNeighbour(NeighbourSide side, bool readOnly)
    {
        var ownerNeighbour = _ownerNode.GetOrCreateNeighbour(side, readOnly);

        if (ownerNeighbour == null)
        {
            return(null);
        }

        return(ownerNeighbour.GetItem());
    }
コード例 #9
0
 public RayIntersectionResult(bool hit)
 {
     this.hit      = hit;
     node          = null;
     _coords       = new Coords();
     entryDistance = 0;
     position      = new Vector3();
     normal        = new Vector3();
     neighbourSide = NeighbourSide.Invalid;
     tree          = null;
 }
コード例 #10
0
ファイル: SuperVoxelTree.cs プロジェクト: toxicFork/vox
        public Node GetOrCreateNeighbour(NeighbourSide side, bool readOnly)
        {
            if (!CreateParentTowardsSide(side, readOnly))
            {
                return(null);
            }

            //
            ////        var neighbourCoords =
            ////            VoxelTree.GetNeighbourCoords(new Coords(new[] {OctreeChildCoords.FromIndex(_indexInParent)}), side);
            //
            ////        if (neighbourCoords == null) {
            //        // uh oh, gotta go further
            //
            // cases:
            // length 0: not gonna happen.
            // not at edge, if parent was null, we get neighbour Coords result.
            // at edge: ??

            var neighbourCoordsInfinite = GetNeighbourCoordsInfinite(ocTree,
                                                                     GetCoords(), side, ExpandRootAndReturnTree);

            if (neighbourCoordsInfinite == null)
            {
                throw new Exception("Neighbour coords are null!");
            }
            else
            {
                var neighbourCoordsResult = neighbourCoordsInfinite.Value;

                var neighbourCoords = neighbourCoordsResult.coordsResult;

                var root = GetRoot();

                var neighbour = root.GetChildAtCoords(neighbourCoords);

                if (neighbour == null)
                {
                    if (readOnly)
                    {
                        return(null);
                    }

                    neighbour = root.AddRecursive(neighbourCoords, false);
                    CreateNewNeighbourSuperVoxelTree(neighbour, side);
                }

                return(neighbour);
            }
        }
コード例 #11
0
    public RayIntersectionResult(IOctree tree, 
		INode node,
		Coords coords,
		float entryDistance,
		Vector3 position,
		Vector3 normal, NeighbourSide neighbourSide)
    {
        hit = true;
        this.tree = tree;
        this.node = node;
        _coords = coords;
        this.entryDistance = entryDistance;
        this.position = position;
        this.normal = normal;
        this.neighbourSide = neighbourSide;
    }
コード例 #12
0
        private static bool IsBetweenSameWords(string[] words, int index, NeighbourSide side)
        {
            if (side == NeighbourSide.Right)
            {
                return(false);
            }

            var neighbourIndex = index - 2;

            if (neighbourIndex < 0)
            {
                return(false);
            }

            return(words[index] == words[neighbourIndex]);
        }
コード例 #13
0
 public RayIntersectionResult(IOctree tree,
                              INode node,
                              Coords coords,
                              float entryDistance,
                              Vector3 position,
                              Vector3 normal, NeighbourSide neighbourSide)
 {
     hit                = true;
     this.tree          = tree;
     this.node          = node;
     _coords            = coords;
     this.entryDistance = entryDistance;
     this.position      = position;
     this.normal        = normal;
     this.neighbourSide = neighbourSide;
 }
コード例 #14
0
    protected Bounds GetNeighbourBounds(NeighbourSide side)
    {
        var rootBounds = GetRoot().GetBounds();

        var center = rootBounds.center;
        var size   = rootBounds.size;

        switch (side)
        {
        case NeighbourSide.Above:
            center += Vector3.up * size.y;
            break;

        case NeighbourSide.Below:
            center += Vector3.down * size.y;
            break;

        case NeighbourSide.Right:
            center += Vector3.right * size.x;
            break;

        case NeighbourSide.Left:
            center += Vector3.left * size.x;
            break;

        case NeighbourSide.Back:
            center += Vector3.back * size.z;
            break;

        case NeighbourSide.Forward:
            center += Vector3.forward * size.z;
            break;

        case NeighbourSide.Invalid:
            break;

        default:
            throw new ArgumentOutOfRangeException("side", side, null);
        }

        var neighbourBounds = new Bounds(center, size);

        return(neighbourBounds);
    }
コード例 #15
0
	private void AddPartialFaces(ICollection<OctreeRenderFace> faces, NeighbourSide side, Bounds currentBounds, Coords coords, int meshIndex,
		bool parentPartial) {
		if (IsTransparent() && !parentPartial) {
			var childCoords = GetChildCoordsOfSide(side);

			// ReSharper disable once ForCanBeConvertedToForeach
			for (var i = 0; i < childCoords.Length; i++) {
				var childCoord = childCoords[i];
				var childBounds = GetChildBoundsInternal(currentBounds, childCoord.ToIndex());
				var childAbsCoords = new Coords(coords, childCoord);

//                        var _coords = new Coords();

				CreateFacesForSideInternal(faces, side, childBounds, childAbsCoords, meshIndex);
			}
		} else {
			AddFaceToList(faces, side, currentBounds, meshIndex);
		}
	}
コード例 #16
0
    public Bounds GetNeighbourBoundsForChild(Coords coords, NeighbourSide neighbourSide)
    {
        var childBounds = GetRoot().GetChildBounds(coords);

        Vector3 sideDirection;

        switch (neighbourSide)
        {
        case NeighbourSide.Above:
            sideDirection = Vector3.up;
            break;

        case NeighbourSide.Below:
            sideDirection = Vector3.down;
            break;

        case NeighbourSide.Right:
            sideDirection = Vector3.right;
            break;

        case NeighbourSide.Left:
            sideDirection = Vector3.left;
            break;

        case NeighbourSide.Back:
            sideDirection = Vector3.back;
            break;

        case NeighbourSide.Forward:
            sideDirection = Vector3.forward;
            break;

        case NeighbourSide.Invalid:
            throw new ArgumentOutOfRangeException("neighbourSide", neighbourSide, null);

        default:
            throw new ArgumentOutOfRangeException("neighbourSide", neighbourSide, null);
        }

        return(new Bounds(childBounds.center + Vector3.Scale(sideDirection, childBounds.size), childBounds.size));
    }
コード例 #17
0
ファイル: SuperVoxelTree.cs プロジェクト: toxicFork/vox
        private bool CreateParentTowardsSide(NeighbourSide side, bool readOnly)
        {
            if (parent == null)
            {
                // we're the root
                if (readOnly)
                {
                    return(false);
                }

                var wantedIndexInParent = GetWantedIndexInParent(side);

                parent = new Node(CreateParentBounds(wantedIndexInParent), ocTree);

                ocTree.SetRoot(parent);

                indexInParent = wantedIndexInParent;

                parent.ReplaceChild(wantedIndexInParent, this);
            }

            return(true);
        }
コード例 #18
0
	private bool SideSolid(NeighbourSide side) {
		return _sideSolidCount != null && _sideSolidCount[side] > 0;
	}
コード例 #19
0
        private static bool NeedSkip(string[] words, int index, NeighbourSide side)
        {
            var neighbourIndex = side == NeighbourSide.Left ? index - 1 : index + 1;

            return(NeedSkip(words, index, neighbourIndex) || IsBetweenSameWords(words, index, side));
        }
コード例 #20
0
ファイル: OctreeNode.cs プロジェクト: toxicFork/vox
    protected static void GetNeighbourSides(ChildIndex childIndex,
                                            out NeighbourSide verticalSide,
                                            out NeighbourSide horizontalSide,
                                            out NeighbourSide depthSide)
    {
        switch (childIndex)
        {
        case ChildIndex.Invalid:
            // self
            verticalSide   = NeighbourSide.Invalid;
            horizontalSide = NeighbourSide.Invalid;
            depthSide      = NeighbourSide.Invalid;
            break;

        case ChildIndex.LeftBelowBack:
            verticalSide   = NeighbourSide.Below;
            depthSide      = NeighbourSide.Back;
            horizontalSide = NeighbourSide.Left;
            break;

        case ChildIndex.RightBelowBack:
            verticalSide   = NeighbourSide.Below;
            depthSide      = NeighbourSide.Back;
            horizontalSide = NeighbourSide.Right;
            break;

        case ChildIndex.LeftAboveBack:
            verticalSide   = NeighbourSide.Above;
            depthSide      = NeighbourSide.Back;
            horizontalSide = NeighbourSide.Left;
            break;

        case ChildIndex.RightAboveBack:
            verticalSide   = NeighbourSide.Above;
            depthSide      = NeighbourSide.Back;
            horizontalSide = NeighbourSide.Right;
            break;

        case ChildIndex.LeftBelowForward:
            verticalSide   = NeighbourSide.Below;
            depthSide      = NeighbourSide.Forward;
            horizontalSide = NeighbourSide.Left;
            break;

        case ChildIndex.RightBelowForward:
            verticalSide   = NeighbourSide.Below;
            depthSide      = NeighbourSide.Forward;
            horizontalSide = NeighbourSide.Right;
            break;

        case ChildIndex.LeftAboveForward:
            verticalSide   = NeighbourSide.Above;
            depthSide      = NeighbourSide.Forward;
            horizontalSide = NeighbourSide.Left;
            break;

        case ChildIndex.RightAboveForward:
            verticalSide   = NeighbourSide.Above;
            depthSide      = NeighbourSide.Forward;
            horizontalSide = NeighbourSide.Right;
            break;

        default:
            throw new ArgumentOutOfRangeException("childIndex", childIndex, null);
        }
    }
コード例 #21
0
	private SideState GetSideState(Coords coords, NeighbourSide side) {
		AssertNotDeleted();
		var neighbourCoordsInfinite = GetTree().GetNeighbourCoordsInfinite(coords, side, true);

		//out of the boundaries
		if (neighbourCoordsInfinite == null) {
			return SideState.Empty;
		} else {
			var neighbourCoordsResult = neighbourCoordsInfinite.Value;

#if USE_ALL_NODES
		OctreeNode<T> neighbourNode;

		if (_allNodes.TryGetValue(neighbourCoords.GetHashCode(), out neighbourNode)) {
			if (neighbourNode.IsLeafNode()) {
				return neighbourNode.HasItem() ? SideState.Full : SideState.Empty;
			}

			// not null and not leaf, so the neighbour node must be partial

			SideState sideState;
			if (neighbourNode.SideSolid(GetOpposite(side))) {
				// if the opposite side of current node is solid, then this is a partial node.
				sideState = SideState.Partial;
			} else {
				sideState = SideState.Empty;
			}

			return sideState;
		}

		// that child doesn't exist

		//let's check the parents
		while (neighbourCoords.Length > 0) {
			// get the next parent
			neighbourCoords = neighbourCoords.GetParentCoords();

			//does the next parent exist?
			if (!_allNodes.TryGetValue(neighbourCoords.GetHashCode(), out neighbourNode)) {
				continue;
			}

			if (neighbourNode.IsDeleted()) {
				continue;
			}

			// is the parent a leaf?
			if (neighbourNode.IsLeafNode()) {
				return neighbourNode.HasItem() ? SideState.Full : SideState.Empty;
			}

			// is not a leaf so cannot have an item

			break;
		}

		return SideState.Empty;
#else

//        if (neighbourCoords.GetTree() == null) {
//            return SideState.Empty;
//        }

			var currentNode = (VoxelNode) neighbourCoordsResult.tree.GetRoot(); // neighbourCoords.GetTree().GetRoot();

			// follow the children until you get to the node
			foreach (var coord in neighbourCoordsResult.coordsResult) {
				if (currentNode == null) {
					return SideState.Empty;
				}

				if (currentNode.IsLeafNode()) {
					if (currentNode.HasItem()) {
						if (currentNode.IsTransparent()) {
							return SideState.FullButTransparent;
						}
						return SideState.Full;
					} else {
						return SideState.Empty;
					}
				}

				currentNode = currentNode.GetChild(coord.ToIndex());
			}

			//last currentNode is the actual node at the neighbour Coords

			if (currentNode == null) {
				return SideState.Empty;
			}

			if (currentNode.IsLeafNode()) {
				if (currentNode.HasItem()) {
					if (currentNode.IsTransparent()) {
						return SideState.FullButTransparent;
					}
					return SideState.Full;
				} else {
					return SideState.Empty;
				}
			}

			// not null and not leaf, so it must be partial
			// try to recursively get all nodes on this side
			SideState sideState;
			if (currentNode.SideSolid(GetOpposite(side))) {
				if (currentNode.SideTransparent(side)) {
					sideState = SideState.PartialButTransparent;
				} else {
					// if the opposite side of current node is solid, then this is a partial node.
					sideState = SideState.Partial;
				}
			} else {
				sideState = SideState.Empty;
			}
			return sideState;
		}
#endif
	}
コード例 #22
0
	public IEnumerable<VoxelNode> GetAllSolidNeighbours(NeighbourSide side) {
		var neighbourCoordsInfinite = GetTree().GetNeighbourCoordsInfinite(GetCoords(), side, true);
		//out of the map!
		if (neighbourCoordsInfinite == null) {
			return null;
		} else {
			var neighbourCoordsResult = neighbourCoordsInfinite.Value;

#if USE_ALL_NODES
		OctreeNode<T> neighbourNode;

		if (_allNodes.TryGetValue(neighbourCoords.GetHashCode(), out neighbourNode)) {
			if (neighbourNode.IsSolid()) {
				return new HashSet<OctreeNode<T>> {neighbourNode};
			}

			return neighbourNode._sideSolidChildren[GetOpposite(side)];
		}

		// that child doesn't exist

		//let's check the parents
		while (neighbourCoords.Length > 0) {
			// get the next parent
			neighbourCoords = neighbourCoords.GetParentCoords();

			//does the next parent exist?
			if (!_allNodes.TryGetValue(neighbourCoords.GetHashCode(), out neighbourNode)) {
				continue;
			}

			// is the parent a leaf?
			if (neighbourNode.IsSolid()) {
				return new HashSet<OctreeNode<T>> {neighbourNode};
			}

			// is not a leaf so cannot have an item

			break;
		}

		return null;
#else

//        if (neighbourCoords.GetTree() == null) {
//            return null;
//        }

			var currentNeighbourNode = (VoxelNode) neighbourCoordsResult.tree.GetRoot();

			foreach (var coord in neighbourCoordsResult.coordsResult) {
				if (currentNeighbourNode == null || currentNeighbourNode.IsDeleted()) {
					return null;
				}

				if (currentNeighbourNode.IsSolid()) {
					return new HashSet<VoxelNode> {currentNeighbourNode};
				}

				currentNeighbourNode = currentNeighbourNode.GetChild(coord.ToIndex());
				}

			//        last currentNode is the actual node at the neighbour Coords
			if (currentNeighbourNode == null || currentNeighbourNode.IsDeleted()) {
				return null;
			}

			if (currentNeighbourNode.IsSolid()) {
				return new HashSet<VoxelNode> {currentNeighbourNode};
			}

			return currentNeighbourNode._sideSolidChildren[GetOpposite(side)];
		}
#endif
	}
コード例 #23
0
	private void CreateFacesForSideInternal(NeighbourSide side, int meshIndex, ICollection<OctreeRenderFace> faces) {
		CreateFacesForSideInternal(faces, side, bounds, GetCoords(), meshIndex);
	}
コード例 #24
0
	private static void AddFaceToList(ICollection<OctreeRenderFace> faces, NeighbourSide side, Bounds bounds,
		int meshIndex) {
		var face = new OctreeRenderFace(meshIndex);

		var min = bounds.min;
		var max = bounds.max;

		Vector3 n;

		switch (side) {
			case NeighbourSide.Above:
				face.vertices[0] = new Vector3(min.x, max.y, min.z);
				face.vertices[1] = new Vector3(min.x, max.y, max.z);
				face.vertices[2] = max;
				face.vertices[3] = new Vector3(max.x, max.y, min.z);

				n = Vector3.up;

				face.uvs[0] = new Vector2(min.x, min.z);
				face.uvs[1] = new Vector2(min.x, max.z);
				face.uvs[2] = new Vector2(max.x, max.z);
				face.uvs[3] = new Vector2(max.x, min.z);
				break;
			case NeighbourSide.Below:
				face.vertices[0] = new Vector3(min.x, min.y, max.z);
				face.vertices[1] = min;
				face.vertices[2] = new Vector3(max.x, min.y, min.z);
				face.vertices[3] = new Vector3(max.x, min.y, max.z);

				n = Vector3.down;

				face.uvs[0] = new Vector2(min.x, max.z);
				face.uvs[1] = new Vector2(min.x, min.z);
				face.uvs[2] = new Vector2(max.x, min.z);
				face.uvs[3] = new Vector2(max.x, max.z);
				break;
			case NeighbourSide.Left:
				face.vertices[0] = new Vector3(min.x, min.y, max.z);
				face.vertices[1] = new Vector3(min.x, max.y, max.z);
				face.vertices[2] = new Vector3(min.x, max.y, min.z);
				face.vertices[3] = min;

				n = Vector3.left;

				face.uvs[0] = new Vector2(max.z, min.y);
				face.uvs[1] = new Vector2(max.z, max.y);
				face.uvs[2] = new Vector2(min.z, max.y);
				face.uvs[3] = new Vector2(min.z, min.y);
				break;
			case NeighbourSide.Right:
				face.vertices[0] = new Vector3(max.x, min.y, min.z);
				face.vertices[1] = new Vector3(max.x, max.y, min.z);
				face.vertices[2] = max;
				face.vertices[3] = new Vector3(max.x, min.y, max.z);


				n = Vector3.right;

				face.uvs[0] = new Vector2(min.z, min.y);
				face.uvs[1] = new Vector2(min.z, max.y);
				face.uvs[2] = new Vector2(max.z, max.y);
				face.uvs[3] = new Vector2(max.z, min.y);
				break;
			case NeighbourSide.Forward:
				face.vertices[0] = new Vector3(max.x, min.y, max.z);
				face.vertices[1] = max;
				face.vertices[2] = new Vector3(min.x, max.y, max.z);
				face.vertices[3] = new Vector3(min.x, min.y, max.z);

				n = Vector3.forward;

				face.uvs[0] = new Vector2(max.x, min.y);
				face.uvs[1] = new Vector2(max.x, max.y);
				face.uvs[2] = new Vector2(min.x, max.y);
				face.uvs[3] = new Vector2(min.x, min.y);
				break;
			case NeighbourSide.Back:
				face.vertices[0] = min;
				face.vertices[1] = new Vector3(min.x, max.y, min.z);
				face.vertices[2] = new Vector3(max.x, max.y, min.z);
				face.vertices[3] = new Vector3(max.x, min.y, min.z);

				n = Vector3.back;

				face.uvs[0] = new Vector2(min.x, min.y);
				face.uvs[1] = new Vector2(min.x, max.y);
				face.uvs[2] = new Vector2(max.x, max.y);
				face.uvs[3] = new Vector2(max.x, min.y);
				break;
			default:
				throw new ArgumentOutOfRangeException("side", side, null);
		}

		face.normal = n;

		faces.Add(face);
	}
コード例 #25
0
    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));
    }
コード例 #26
0
    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));
    }
コード例 #27
0
	private bool SideTransparent(NeighbourSide side) {
		return _sideTransparentCount != null && _sideTransparentCount[side] > 0;
	}
コード例 #28
0
 public NeighbourCoordsResult?GetNeighbourCoordsInfinite(Coords coords, NeighbourSide side, bool readOnly = false)
 {
     return(GetNeighbourCoordsInfinite(this, coords, side, GetOrCreateNeighbour, readOnly));
 }