Esempio n. 1
0
    private void GenerateTerrain()
    {
        if (densitySize.x > 0 && densitySize.y > 0 && densitySize.z > 0)
        {
            Stopwatch s = new Stopwatch();
            s.Restart();
            s.Start();

            startPoint  = new Vector3((int)startPoint.x, (int)startPoint.y, (int)startPoint.z);
            densitySize = new Vector3((int)densitySize.x, (int)densitySize.y, (int)densitySize.z);

            Vector4[] density = densityGenerator.GetDensity(
                densitySize, pointsSpace, startPoint, noiseScale, noiseWeight, octavesCount,
                amplitudeMultiplier, frequencyMultiplier, seed, sizeMultiplier);

            Vector4[,,] convertedDensity = ConvertArrayOfVector4To3DimensionalArray(density, densitySize * pointsSpace);

            DrawGizmosIfEnable(density);

            OctreeElement root = voxelsOctree.GetOctreeVoxel(convertedDensity);

            if (root != null)
            {
                marchingCubes.GenerateMesh(root, meshGameObject);
            }
            //marchingCubes.GenerateMesh(convertedDensity, meshGameObject);

            s.Stop();
            //Debug.Log("ooo " + s.Elapsed.TotalMilliseconds);
        }
    }
    private OctreeElement[] CreateVoxelsLeaf(Vector4[,,] density, Vector3 size, Vector3 currentPosition, Vector3 startPoint)
    {
        OctreeElement[] octreeElements = new OctreeElement[8];
        int             elements       = 0;

        for (int x = (int)currentPosition.x; x < (int)currentPosition.x + 2; x++)
        {
            for (int y = (int)currentPosition.y; y < (int)currentPosition.y + 2; y++)
            {
                for (int z = (int)currentPosition.z; z < (int)currentPosition.z + 2; z++)
                {
                    if (x <= (int)size.x - 1 && y <= (int)size.y - 1 && z <= (int)size.z - 1)
                    {
                        Voxel voxel = new Voxel((x, x + 1), (y, y + 1), (z, z + 1), new Vector2(x / bigSize.x, z / bigSize.z));
                        (float[,,] densityForVoxel, bool edge) = GetDensityForVoxel(density, new Vector3(x, y, z), startPoint);
                        voxel.SetDensity(densityForVoxel);
                        octreeElements[elements] = voxel;

                        if (edge)
                        {
                            voxel.Edge = true;
                        }
                    }
                    else
                    {
                        octreeElements[elements] = null;
                    }

                    elements++;
                }
            }
        }

        return(octreeElements);
    }
    // Use this for initialization
    void Start()
    {
        boxCollider = GetComponent <BoxCollider>();
        root        = new OctreeElement(null, boxCollider.bounds, 0);
        toBeSplit.Enqueue(root);
        cellCount++;
        float doubleMinCellSize = minCellSize * 2f;

        while (toBeSplit.Count > 0)
        {
            var elem = toBeSplit.Dequeue();

            elem.Empty = !Physics.CheckBox(elem.Bounds.center, elem.Bounds.extents, Quaternion.identity, mask, QueryTriggerInteraction.Ignore);

            if (elem.Bounds.size.magnitude > doubleMinCellSize && !elem.Empty)
            {
                elem.Split();

                foreach (var child in elem.Children)
                {
                    toBeSplit.Enqueue(child);
                    cellCount++;
                }
            }
        }

        CalculateNeighborsRecursive(root);
    }
    private OctreeElement GetNeighborRec(OctreeElement startNode, OctreeElement.Dir dir)
    {
        OctreeElement parent = startNode.Parent;

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

        //find local neighbor
        int localIndex = Array.IndexOf(parent.Children, startNode);

        StorePositionAtDepth(parent.Depth, localIndex);
        int localNeighborIndex = OctreeElement.localNeighborIndex[localIndex][(int)dir];

        if (localNeighborIndex >= 0)
        {
            return(parent.Children[localNeighborIndex]);
        }

        OctreeElement topmostNeighbor = GetNeighborRec(parent, dir);

        //this means the edge of the octree volume so we return null
        if (topmostNeighbor == null)
        {
            return(null);
        }

        //find the lowest mirrored child of the parent neighbor
        OctreeElement lowerMostReflectedChild = GetLowestChild(topmostNeighbor, dir, getNeighborStartingDepth);

        return(lowerMostReflectedChild);
    }
 public OctreeElement(OctreeElement parent, Bounds bounds, int depth)
 {
     Parent = parent;
     Bounds = bounds;
     // TODO Raytrace down to find surface below, there may be a building or tree or similar here.
     approxBoundsHeight = Bounds.center.y + Terrain.activeTerrain.SampleHeight(Bounds.center);
     Depth = depth;
 }
Esempio n. 6
0
    public void Remove(T key)
    {
        OctreeElement element = elementByKey[key];

        elementByKey.Remove(key);

        RemoveInternal(element, 0, IntVector3.zero, root);
    }
 public void Split()
 {
     Children = new OctreeElement[splitDirs.Length];
     for (int i = 0; i < Children.Length; i++)
     {
         Children[i] = new OctreeElement(this, new Bounds(Bounds.center + Vector3.Scale(splitDirs[i], Bounds.extents / 2f), Bounds.extents), Depth + 1);
     }
 }
Esempio n. 8
0
    public void Add(T key, Vector3 position)
    {
        OctreeElement element = new OctreeElement();

        elementByKey.Add(key, element);

        AddInternal(position, 0, IntVector3.zero, root, element);
    }
 private OctreeElement GetLowestChild(OctreeElement start, OctreeElement.Dir dir, int maxDepth)
 {
     if (start.Children != null && start.Depth < maxDepth)
     {
         OctreeElement.Pos reflectedPos = OctreeElement.ReflectedPos[(int)dir][neighborPathPositions[start.Depth]];
         return(GetLowestChild(start.Children[(int)reflectedPos], dir, maxDepth));
     }
     return(start);
 }
Esempio n. 10
0
    private void GetNeighbors(OctreeElement startNode, OctreeElement.Dir dir, ICollection <OctreeElement> neighbors)
    {
        getNeighborStartingDepth = startNode.Depth;
        var topmostNeighbor = GetNeighborRec(startNode, dir);

        if (topmostNeighbor != null)
        {
            GetAllChildrentInDir(topmostNeighbor, dir, neighbors);
        }
    }
Esempio n. 11
0
        public void addEntity(Entity e, Vector3 pos)
        {
            OctreeElement <Entity> el = new OctreeElement <Entity>();

            el.myObject = e;
            el.mySize   = 2; //need to figure out the best way to get this info, default of 2 is fine for now
            convertPosition(ref el, pos);
            theOctree.insert(el);
            theOctreeEntityMap.Add(e.id, el);
            myReverseOctreeEntityMap.Add(el, e.id);
        }
Esempio n. 12
0
    public void Update(T key, Vector3 newPosition)
    {
        OctreeElement element = elementByKey[key];

        element.position = newPosition;
        if (WithinBox(newPosition, GetMin(element.level, element.coords), GetMax(element.level, element.coords)))
        {
            return;
        }
        RemoveInternal(element, 0, IntVector3.zero, root);
        AddInternal(newPosition, 0, IntVector3.zero, root, element);
    }
Esempio n. 13
0
        private void MoveToChild(OctreeElement element, int childIndex)
        {
            if (children[childIndex] == null)
            {
                children[childIndex] = new OctreeNode();
            }

            element.level += 1;
            element.coords = element.coords * 2 + ChildIndexToCoords(childIndex);
            children[childIndex].Put(element);
            children[childIndex].TotalElementCount++;
        }
Esempio n. 14
0
    /// <summary>
    /// Get the smallest known node that encompasses the position.
    /// </summary>
    /// <param name="position">The position that must be containers</param>
    /// <returns>The smallest node containing the position or null if the octree does not contain the position.</returns>
    internal OctreeElement GetNode(Vector3 position)
    {
        OctreeElement node = GetNode(root, position);

#if UNITY_EDITOR
        if (node == null)
        {
            Debug.LogError("Requested a node containing a position " + position + " which is not within the Octree. This should not happen. First check that the position is within the Octree using Contains(position)");
        }
#endif
        return(node);
    }
Esempio n. 15
0
        public Entity nearestNeighbor(Entity e)
        {
            OctreeElement <Entity> el;

            if (theOctreeEntityMap.TryGetValue(e.id, out el))
            {
                OctreeElement <Entity> nel = theOctree.nearestNeighbor(el);
                if (nel != null)
                {
                    return(nel.myObject);
                }
            }
            return(null);
        }
Esempio n. 16
0
 private void GetAllChildrentInDir(OctreeElement start, OctreeElement.Dir dir, ICollection <OctreeElement> elements)
 {
     if (start.Children != null)
     {
         var oppositeDir = (int)OctreeElement.OppositeDirs[(int)dir];
         for (int i = 0; i < OctreeElement.PosInDir[oppositeDir].Length; i++)
         {
             GetAllChildrentInDir(start.Children[(int)OctreeElement.PosInDir[oppositeDir][i]], dir, elements);
         }
     }
     else
     {
         elements.Add(start);
     }
 }
    public OctreeElement GetOctreeVoxel(Vector4[,,] density)
    {
        if (density.GetLength(0) > 1 && density.GetLength(1) > 1 && density.GetLength(2) > 1)
        {
            int treeSize = GetTreeSize(density.GetLength(0) - 1, density.GetLength(1) - 1, density.GetLength(2) - 1);
            // Debug.Log("treeSize: " + treeSize);

            List <OctreeElement> branchesWithVoxels = InitVoxels(density);

            float xDifferent = density[1, 0, 0].x - density[0, 0, 0].x;
            float yDifferent = density[0, 1, 0].y - density[0, 0, 0].y;
            float zDifferent = density[0, 0, 1].z - density[0, 0, 0].z;

            Vector3 size       = new Vector3(density.GetLength(0), density.GetLength(1), density.GetLength(2));
            Vector3 startPoint = new Vector3(density[0, 0, 0].x, density[0, 0, 0].y, density[0, 0, 0].z);

            List <OctreeElement> branchesChildren = branchesWithVoxels;
            List <OctreeElement> biggerBranches   = new List <OctreeElement>();

            while (branchesChildren.Count > 1)
            {
                FillNextLevelOfTree(branchesChildren, biggerBranches, xDifferent,
                                    yDifferent, zDifferent, size, startPoint);
                xDifferent *= 2;
                yDifferent *= 2;
                zDifferent *= 2;

                branchesChildren = biggerBranches;
                biggerBranches   = new List <OctreeElement>();
            }

            root = branchesChildren[0];
            SetVoxelsType(root);
            SetVoxelsType(root);
            SetVoxelsType(root);
            SetVoxelsType(root);
            SetVoxelsType(root);
            SetVoxelsType(root);
            SetVoxelsType(root);
            return(root);
        }

        return(null);
    }
Esempio n. 18
0
    public void GenerateMesh(OctreeElement root, GameObject terrain)
    {
        meshVertices = new List <Vector3>();
        uv           = new List <Vector2>();

        if (VertexesCaseProvider.ReadVerticesIndexesFromFile())
        {
            List <OctreeElement> octreeBranches = root.NextElements.ToList();

            while (octreeBranches.Count != 0)
            {
                int count = octreeBranches.Count;

                for (int i = count - 1; i >= 0; i--)
                {
                    if (octreeBranches[i] != null)
                    {
                        OctreeElement[] nextElements = octreeBranches[i].NextElements;

                        if (nextElements == null)
                        {
                            Voxel voxel = octreeBranches[i] as Voxel;

                            if (voxel.Drawable)
                            {
                                foreach (var vertices in voxel.Vertices)
                                {
                                    meshVertices.AddRange(vertices);
                                    uv.AddRange(voxel.GetUVPositionForVoxel());
                                }
                            }
                        }
                        else
                        {
                            octreeBranches.AddRange(nextElements);
                        }
                    }

                    octreeBranches.RemoveAt(i);
                }
            }
        }
        GenerateMesh(terrain);
    }
Esempio n. 19
0
 private void CalculateNeighborsRecursive(OctreeElement element)
 {
     if (element.Children == null)
     {
         element.Neigbors = new OctreeElement[6][];
         for (int i = 0; i < 6; i++)
         {
             List <OctreeElement> neighbors = new List <OctreeElement>();
             GetNeighbors(element, (OctreeElement.Dir)i, neighbors);
             element.Neigbors[i] = neighbors.ToArray();
         }
     }
     else
     {
         for (int i = 0; i < element.Children.Length; i++)
         {
             CalculateNeighborsRecursive(element.Children[i]);
         }
     }
 }
Esempio n. 20
0
 /// <summary>
 /// Get the smallest known node that encompasses the position.
 /// If the supplied parent node has children and it encompasses the position
 /// work through the children until the one that contains the position is found.
 /// This is repeated recursively to return the smallest node possible.
 /// </summary>
 /// <param name="parent">The node to start the search within.</param>
 /// <param name="position">The position that must be containers</param>
 /// <returns>The smallest child node containing the position or null if the parent does not contain the position.</returns>
 private OctreeElement GetNode(OctreeElement parent, Vector3 position)
 {
     if (parent.Bounds.Contains(position))
     {
         if (parent.Children != null)
         {
             for (int i = 0; i < parent.Children.Length; i++)
             {
                 OctreeElement child = GetNode(parent.Children[i], position);
                 if (child != null)
                 {
                     return(child);
                 }
             }
         }
         else
         {
             return(parent);
         }
     }
     return(null);
 }
Esempio n. 21
0
 private OctreeElement GetNode(OctreeElement parent)
 {
     if (parent.Bounds.Contains(tmpGetNodePos))
     {
         if (parent.Children != null)
         {
             for (int i = 0; i < parent.Children.Length; i++)
             {
                 OctreeElement child = GetNode(parent.Children[i]);
                 if (child != null)
                 {
                     return(child);
                 }
             }
         }
         else
         {
             return(parent);
         }
     }
     return(null);
 }
Esempio n. 22
0
        //returns whether or not the value changed
        public bool convertPosition(ref OctreeElement <Entity> element, Vector3 pos)
        {
            uint X, Y, Z;

            X = (uint)pos.X;
            Y = (uint)pos.Y;
            Z = (uint)pos.Z;

            bool needsUpdate = false;

            if (X != element.myX || Y != element.myY || Z != element.myZ)
            {
                needsUpdate = true;
            }

            //for the moment, just a straight passthrough
            element.myX = X;
            element.myY = Y;
            element.myZ = Z;

            return(needsUpdate);
        }
Esempio n. 23
0
    private void RemoveInternal(OctreeElement element, int level, IntVector3 coords, OctreeNode node)
    {
        node.TotalElementCount--;
        if (element.level == level)
        {
            node.Remove(element.index);
            return;
        }

        IntVector3 coordsInChildLevel = element.coords / (1 << (element.level - level - 1));
        IntVector3 childCoords        = coordsInChildLevel - coords * 2;
        int        childIndex         = ChildCoordsToIndex(childCoords);
        OctreeNode child = node.children[childIndex];

        RemoveInternal(element, level + 1, coordsInChildLevel, child);
        if (child.TotalElementCount == 0)
        {
            node.children[childIndex] = null;
        }
        if (node.TotalElementCount <= mergeThreshold)
        {
            node.Merge();
        }
    }
    public void SetVoxelsType(OctreeElement root)
    {
        Stopwatch d = new Stopwatch();

        d.Restart();

        List <OctreeElement> octreeBranches = root.NextElements.ToList();

        while (octreeBranches.Count != 0)
        {
            int count = octreeBranches.Count;

            for (int i = count - 1; i >= 0; i--)
            {
                if (octreeBranches[i] != null)
                {
                    OctreeElement[] nextElements = octreeBranches[i].NextElements;

                    if (nextElements == null)
                    {
                        Voxel voxel = octreeBranches[i] as Voxel;
                        voxel.SetType();
                    }
                    else
                    {
                        octreeBranches.AddRange(nextElements);
                    }
                }

                octreeBranches.RemoveAt(i);
            }
        }

        d.Stop();
        //Debug.Log("d: " + d.Elapsed.TotalMilliseconds);
    }
 public OctreeBranch(OctreeElement previousElement)
     : base(previousElement, false)
 {
 }
Esempio n. 26
0
 private void MoveFromChild(OctreeElement element)
 {
     element.level -= 1;
     element.coords = element.coords / 2;
     Put(element);
 }
Esempio n. 27
0
    public void GetPathAstar(object context)
    {
        PathRequest request = (PathRequest)context;

        try
        {
            FastPriorityQueue <OctreeElementQueueElemenet> fronteer = new FastPriorityQueue <OctreeElementQueueElemenet>(16);
            Dictionary <OctreeElement, OctreeElement>      cameFrom = new Dictionary <OctreeElement, OctreeElement>();
            Dictionary <OctreeElement, float> weights = new Dictionary <OctreeElement, float>();
            OctreeElement startNode = GetNode(request.from);
            OctreeElement endNode   = GetNode(request.to);
            if (startNode == null || endNode == null)
            {
                return;
            }
            weights.Add(startNode, startNode.BaseCost);
            fronteer.Enqueue(new OctreeElementQueueElemenet(startNode), startNode.WeightedCost(request.controller.preferredFlightHeight, request.controller.minFlightHeight, request.controller.maxFlightHeight));
            OctreeElement current;
            OctreeElement closest         = startNode;
            float         closestDistance = Vector3.SqrMagnitude(startNode.Bounds.center - request.to);
            long          lastMiliseconds = 0;
            Stopwatch     stopwatch       = Stopwatch.StartNew();

            while (fronteer.Count > 0)
            {
                current = fronteer.Dequeue().Element;
                if (current == endNode)
                {
                    break;
                }
                //still building path
                if (current.Neigbors != null)
                {
                    for (int i = 0; i < 6; i++)
                    {
                        for (int n = 0; n < current.Neigbors[i].Length; n++)
                        {
                            var next = current.Neigbors[i][n];
                            if (!next.Empty && next != endNode)
                            {
                                continue;
                            }
                            float sqrDistance = Vector3.SqrMagnitude(next.Bounds.center - request.to);
                            if (sqrDistance < closestDistance)
                            {
                                closestDistance = sqrDistance;
                                closest         = next;
                            }
                            float distance  = (next.Bounds.center - request.to).sqrMagnitude;
                            float newWeight = weights[current] + next.WeightedCost(request.controller.preferredFlightHeight, request.controller.minFlightHeight, request.controller.maxFlightHeight) + distance;
                            if (!weights.ContainsKey(next) || newWeight < weights[next])
                            {
                                weights[next]  = newWeight;
                                cameFrom[next] = current;
                                if (fronteer.MaxSize <= fronteer.Count)
                                {
                                    fronteer.Resize(fronteer.MaxSize * 2);
                                }
                                fronteer.Enqueue(new OctreeElementQueueElemenet(next), newWeight + distance);
                            }
                        }
                    }
                }

                if (maxMilisecondsPerFrame > 0 && stopwatch.ElapsedMilliseconds - lastMiliseconds > maxMilisecondsPerFrame)
                {
                    lastMiliseconds = stopwatch.ElapsedMilliseconds;
                    Thread.Sleep(1);
                }
            }

            current = endNode;
            bool particalPath = false;
            while (current != startNode)
            {
                if (!cameFrom.TryGetValue(current, out current))
                {
                    particalPath = true;
                    current      = closest;
                }
                request.path.Insert(0, current.Bounds.center);
            }

            if (!particalPath)
            {
                request.path.Add(request.to);
            }

            request.isCalulated = true;
        }
        catch (Exception e)
        {
            throw e;
        }
        finally
        {
            request.isCalculating = false;
        }
    }
Esempio n. 28
0
    private void AddInternal(Vector3 position, int level, IntVector3 coords, OctreeNode node, OctreeElement element)
    {
        if (node.NodeElementCount >= splitThreshold && level < maxLevel)
        {
            Vector3 center = GetCenter(level, coords);
            node.Split(center);
        }

        node.TotalElementCount++;
        if (!node.IsLeaf)
        {
            Vector3    center     = GetCenter(level, coords);
            int        childIndex = PositionToChildIndex(position, center);
            OctreeNode child      = node.GetOrCreateChild(childIndex);
            AddInternal(position, level + 1, coords * 2 + ChildIndexToCoords(childIndex), child, element);
            return;
        }
        element.position = position;
        element.level    = level;
        element.coords   = coords;
        node.Put(element);
        //Debug.Log(element.ToString() + " is added at " + Time.time);
    }
Esempio n. 29
0
 public OctreeElementQueueElemenet(OctreeElement element)
 {
     Element = element;
 }
Esempio n. 30
0
 public OctreeElement(OctreeElement parent, Bounds bounds, int depth)
 {
     Parent = parent;
     Bounds = bounds;
     Depth  = depth;
 }