/// <summary>
 /// Merge all children into this node - the opposite of Split.
 /// Note: We only have to check one level down since a merge will never happen if the children already have children,
 /// since THAT won't happen unless there are already too many objects to merge.
 /// </summary>
 void Merge()
 {
     // Note: We know children != null or we wouldn't be merging
     for (int i = 0; i < 8; i++)
     {
         PointOctreeNode <T> curChild = children[i];
         int numObjects = curChild.objects.Count;
         for (int j = numObjects - 1; j >= 0; j--)
         {
             OctreeObject curObj = curChild.objects[j];
             objects.Add(curObj);
         }
     }
     // Remove the child nodes (and the objects in them - they've been added elsewhere now)
     children = null;
 }
Esempio n. 2
0
    /*
     *  /// <summary>
     *  /// Get the total amount of objects in this node and all its children, grandchildren etc. Useful for debugging.
     *  /// </summary>
     *  /// <param name="startingNum">Used by recursive calls to add to the previous total.</param>
     *  /// <returns>Total objects in this node and its children, grandchildren etc.</returns>
     *  public int GetTotalObjects(int startingNum = 0) {
     *          int totalObjects = startingNum + objects.Count;
     *          if (children != null) {
     *                  for (int i = 0; i < 8; i++) {
     *                          totalObjects += children[i].GetTotalObjects();
     *                  }
     *          }
     *          return totalObjects;
     *  }
     */

    public PointOctreeNode <T> ClearNode(PointOctreeNode <T> node)
    {
        if (node != null)
        {
            if (ReferenceEquals(node.children, null))
            {
                node.objects.Clear();
                return(null);
            }

            foreach (var item in node.children)
            {
                ClearNode(item);
            }
            node.objects.Clear();
            node = null;
            return(node);
        }
        return(null);
    }
Esempio n. 3
0
        private void CheckFunc(PointOctreeNode <Integer> .OctreeObject octreeObject)
        {
            var objectPosition  = DataSet[octreeObject.Obj].Position;
            var distanceCurrent = Vector3.Distance(cachePosition, objectPosition);

            if (distanceCurrent > NearRadius && distanceCurrent < FarRadius && !Loaded.Contains(octreeObject.Obj))
            {
                Loaded.Add(octreeObject.Obj);
                lock (LoadQueue)
                {
                    LoadQueue.Enqueue(octreeObject.Obj);
                }
            }
            else if ((distanceCurrent < NearRadius || distanceCurrent > FarRadius) &&
                     Loaded.Contains(octreeObject.Obj))
            {
                Loaded.Remove(octreeObject.Obj);
                lock (UnloadQueue)
                {
                    UnloadQueue.Enqueue(octreeObject.Obj);
                }
            }
        }
Esempio n. 4
0
    // #### PRIVATE METHODS ####

    /// <summary>
    /// Grow the octree to fit in all objects.
    /// </summary>
    /// <param name="direction">Direction to grow.</param>
    void Grow(Vector3 direction)
    {
        int xDirection = direction.x >= 0 ? 1 : -1;
        int yDirection = direction.y >= 0 ? 1 : -1;
        int zDirection = direction.z >= 0 ? 1 : -1;
        PointOctreeNode <T> oldRoot = rootNode;
        float   half      = rootNode.SideLength / 2;
        float   newLength = rootNode.SideLength * 2;
        Vector3 newCenter = rootNode.Center + new Vector3(xDirection * half, yDirection * half, zDirection * half);

        // Create a new, bigger octree root node
        rootNode = new PointOctreeNode <T>(newLength, minSize, newCenter);

        if (oldRoot.HasAnyObjects())
        {
            // Create 7 new octree children to go with the old root as children of the new root
            int rootPos = rootNode.BestFitChild(oldRoot.Center);
            PointOctreeNode <T>[] children = new PointOctreeNode <T> [8];
            for (int i = 0; i < 8; i++)
            {
                if (i == rootPos)
                {
                    children[i] = oldRoot;
                }
                else
                {
                    xDirection  = i % 2 == 0 ? -1 : 1;
                    yDirection  = i > 3 ? -1 : 1;
                    zDirection  = (i < 2 || (i > 3 && i < 6)) ? -1 : 1;
                    children[i] = new PointOctreeNode <T>(oldRoot.SideLength, minSize, newCenter + new Vector3(xDirection * half, yDirection * half, zDirection * half));
                }
            }

            // Attach the new children to the new root node
            rootNode.SetChildren(children);
        }
    }
Esempio n. 5
0
 /// <summary>
 /// Shrink the octree if possible, else leave it the same.
 /// </summary>
 void Shrink()
 {
     rootNode = rootNode.ShrinkIfPossible(initialSize);
 }
Esempio n. 6
0
    public Tuple <Vector3, int, float> CalculateVecAndTemp(PointOctreeNode <CelestialBody> node, int depth)
    {
        if (depth > this.depth)
        {
            this.depth = depth;
        }
        if (!node.HasChildren)
        {
            List <Vector3> average         = new List <Vector3>();
            List <int>     averageTempList = new List <int>();
            //for (int i = node.start; i < node.end; i++)
            //{
            //    average.Add(points[permutation[i]]);
            //    averageTempList.Add(reader.celestialBodyCloud[permutation[i]].temperature);
            //}

            foreach (PointOctreeNode <CelestialBody> .OctreeObject celBody in node.objects)
            {
                //Debug.Log("Temp: " + ((CelestialBody)celBody.Obj).temperature);
                average.Add(celBody.Obj.position);
                averageTempList.Add(celBody.Obj.temperature);
            }

            if (average.Count > 0 && averageTempList.Count > 0)
            {
                node.averagePositionOfNodes = new Vector3(
                    average.Average(x => x.x),
                    average.Average(x => x.y),
                    average.Average(x => x.z));
                node.averageTempOfNodes = (int)averageTempList.Average();
            }

            float maxDistance = 0;
            foreach (PointOctreeNode <CelestialBody> .OctreeObject celBody in node.objects)
            {
                float mag = (node.averagePositionOfNodes - celBody.Obj.position).sqrMagnitude;
                if (mag > maxDistance)
                {
                    maxDistance = mag;
                }
            }
            node.distanceFromAverage = maxDistance;

            node.nodeDepth = depth;

            node.distanceFromAverage = node.SideLength;
            //return new Tuple<Vector3, int, float>(node.averagePositionOfNodes, node.averageTempOfNodes, node.distanceFromAverage);
            return(new Tuple <Vector3, int, float>(node.averagePositionOfNodes, node.averageTempOfNodes, node.distanceFromAverage));
        }
        else
        {
            List <Tuple <Vector3, int, float> > listOfResults = new List <Tuple <Vector3, int, float> >();
            listOfResults.Add(CalculateVecAndTemp(node.children[0], depth + 1));
            listOfResults.Add(CalculateVecAndTemp(node.children[1], depth + 1));
            listOfResults.Add(CalculateVecAndTemp(node.children[2], depth + 1));
            listOfResults.Add(CalculateVecAndTemp(node.children[3], depth + 1));
            listOfResults.Add(CalculateVecAndTemp(node.children[4], depth + 1));
            listOfResults.Add(CalculateVecAndTemp(node.children[5], depth + 1));
            listOfResults.Add(CalculateVecAndTemp(node.children[6], depth + 1));
            listOfResults.Add(CalculateVecAndTemp(node.children[7], depth + 1));

            node.nodeDepth = depth;

            foreach (Tuple <Vector3, int, float> result in listOfResults)
            {
                node.averagePositionOfNodes += result.Item1;
                node.averageTempOfNodes     += result.Item2;
            }
            node.averagePositionOfNodes /= 8f;
            node.averageTempOfNodes     /= 8;

            float maxDistance    = 0;
            float resultDistance = 0;
            foreach (Tuple <Vector3, int, float> result in listOfResults)
            {
                float mag = (node.averagePositionOfNodes - result.Item1).sqrMagnitude;
                if (mag > maxDistance)
                {
                    maxDistance    = mag;
                    resultDistance = result.Item3;
                }
            }
            node.distanceFromAverage = maxDistance + resultDistance;

            node.distanceFromAverage = node.SideLength;
            return(new Tuple <Vector3, int, float>(node.averagePositionOfNodes, node.averageTempOfNodes, node.distanceFromAverage));
        }
    }
Esempio n. 7
0
    public IEnumerator SplitOctreeLODWithPixelSize()
    {
        placement_manager.coroutineRunning = true;
        for (; ;)
        {
            int count = 0;

            Queue <PointOctreeNode <CelestialBody> > nodeQueue = new Queue <PointOctreeNode <CelestialBody> >();
            nodeList = new List <PointOctreeNode <CelestialBody> >();

            PointOctreeNode <CelestialBody> tempNode = octree.rootNode;

            nodeQueue.Enqueue(tempNode);
            while (nodeQueue.Count > 0)
            {
                tempNode = nodeQueue.Dequeue();

                count++;

                if (count > 2000)
                {
                    count = 0;
                    yield return(null);
                }
                //Debug.Log(tempNode);
                if (tempNode != null && !tempNode.HasChildren)
                {
                    nodeList.Add(tempNode);
                    continue;
                }
                else if (tempNode != null && tempNode.HasChildren)
                {
                    //nodeList.Add(tempNode);
                    Vector3 centerPos = placement_manager.visualCube.transform.position + tempNode.averagePositionOfNodes;
                    Vector3 edgePos   = centerPos + (Vector3.Cross(Camera.main.transform.up, centerPos - Camera.main.transform.position).normalized *(tempNode.distanceFromAverage / 2) * placement_manager.visualCube.transform.localScale.x);
                    //screenCenterPos = Camera.main.WorldToScreenPoint(centerPos);
                    float distanceInPixel = Vector3.Magnitude(Camera.main.WorldToScreenPoint(centerPos) - Camera.main.WorldToScreenPoint(edgePos));

                    if (distanceInPixel > 2)
                    {
                        foreach (PointOctreeNode <CelestialBody> childNode in tempNode.children)
                        {
                            nodeQueue.Enqueue(childNode);
                        }
                    }
                    else
                    {
                        nodeList.Add(tempNode);
                        continue;
                    }
                }
            }
            CalculateAverageLists(nodeList);

            ui_manager.SetLegendCount(averageSpectralM.Count, averageSpectralK.Count, averageSpectralG.Count, averageSpectralF.Count, averageSpectralA.Count);
            yield return(new WaitForSeconds(1f));

            Debug.Log(count);

            //count = 0;
            ////    yield return null;
        }
    }