示例#1
0
        public void RequestLeafLoad(QTreeLeaf leaf)
        {
            if (leaf.State == LoadedState.UNLOADED && leaf.ListInfos.Count > 0 && leafLoadRequestQueue.Count < 1000)
            {
                leaf.State = LoadedState.REQUEST_LOAD;

                if (leaf.ListInfos.Count > 0)
                {
                    leafLoadRequestQueue.Enqueue(leaf);
                }
            }
        }
示例#2
0
        private List <VBOStorageInformation> serverBufferIds = new List <VBOStorageInformation>(); //VBOS from all children

        public QTreeNode(BoundingBox boundingBox, QTree parentTree, QTreeNode parentNode, int hierarchyLevel)
        {
            NUM_NODES++;

            this.ParentNodeID = parentNode;
            this.boundingBox  = boundingBox;

            nodeHierarchyLevel = (float)hierarchyLevel / parentTree.NumberOfTreeLevels;

            //if bounding box is bigger than allowed split it nodes
            if (boundingBox.width > MAX_WIDTH || boundingBox.height > MAX_HEIGHT)
            {
                nodes = new QTreeNode[4];

                BoundingBox bb = new BoundingBox();
                bb.width  = boundingBox.width / 2.0f;
                bb.height = boundingBox.height / 2.0f;
                bb.x      = boundingBox.x + bb.width;
                bb.y      = boundingBox.y;
                nodes[NE] = new QTreeNode(bb, parentTree, this, hierarchyLevel + 1);

                bb.x      = boundingBox.x;
                nodes[NW] = new QTreeNode(bb, parentTree, this, hierarchyLevel + 1);

                bb.y     += bb.height;
                nodes[SW] = new QTreeNode(bb, parentTree, this, hierarchyLevel + 1);

                bb.x     += bb.width;
                nodes[SE] = new QTreeNode(bb, parentTree, this, hierarchyLevel + 1);
            }
            else
            {
                //node is final - contains only data which is present in QTreeLeaf
                leaf = new QTreeLeaf(boundingBox, parentTree.TreeID, this);
            }
        }
示例#3
0
        /// <summary>
        /// leads leafs in a separate thread
        /// </summary>
        private void LeafLoader()
        {
            TimeSpan  accLoadTime = new TimeSpan();
            long      loadCount   = 0;
            TimeSpan  accReadTime = new TimeSpan();
            TimeSpan  readTemp    = new TimeSpan();
            Stopwatch stopwatch   = new Stopwatch();

            long      accPointsPerLeaf = 0;
            QTreeLeaf leaf             = null;

            while (runLeafLoader)
            {
                if (LasMetrics.GetInstance().leafLoadToggle&& leafLoadRequestQueue.Count > 0)
                {
                    leaf = leafLoadRequestQueue.Dequeue();

                    if (leaf == null)
                    {
                        continue;
                    }

                    if (leaf.State == LoadedState.REQUEST_LOAD)                      //if leaf still wants to be loaded
                    {
                        stopwatch.Start();
                        long readTicks = 0;

                        for (int i = 0; i < leaf.ListInfos.Count; i++)
                        {
                            readTemp = stopwatch.Elapsed;

                            Point3D[] pts = GetPoints(GetQtreeByGuid(leaf.ParentTreeID), leaf.ListInfos[i].startingPointIndex, leaf.ListInfos[i].numberOfPoints);

                            readTicks    = stopwatch.ElapsedTicks;
                            accReadTime += (stopwatch.Elapsed - readTemp);

                            leaf.InsertPoints(i, pts);
                        }

                        if (CALCULATE_NORMALS == true)
                        {
                            leaf.CalculateNormals();
                        }

                        long loadTicks = stopwatch.ElapsedTicks;
                        accLoadTime += stopwatch.Elapsed;

                        stopwatch.Stop();

                        loadCount++;

                        stopwatch.Reset();

                        leaf.State = LoadedState.BUFFERED_IN_RAM;

                        if (loadCount > 0)
                        {
                            double avgLoadTime       = accLoadTime.TotalMilliseconds / loadCount;
                            double avgLoadTimeNoRead = (accLoadTime - accReadTime).TotalMilliseconds / loadCount;

                            //Console.WriteLine("Avg. time from disk to GPU: {0} ms, without disk reads: {1} ms", avgLoadTime, avgLoadTimeNoRead);

                            LasMetrics.GetInstance().avgLoad       = avgLoadTime;
                            LasMetrics.GetInstance().avgLoadNoDisk = avgLoadTimeNoRead;

                            accPointsPerLeaf += leaf.NumberOfPoints;
                            LasMetrics.GetInstance().avgPointsPerLeaf = (double)accPointsPerLeaf / loadCount;
                        }
                    }

                    leaf = null;
                }
                else
                {
                    Thread.Sleep(leafLoaderMSsleepInterval);
                }
            }
        }
示例#4
0
        /// <summary>
        /// calculates normals for point list at specified index
        /// </summary>
        /// <param name="pointListIdx"></param>
        private void CalculateNormals(int pointListIdx)
        {
            //2 consecutive points from the pointListIdx array will be taken and closest from the previous
            //or next point list

            Point3D[] pointList = ContainedPointLists[pointListIdx];

            int len = pointList.Length;
            int closestPointIdxPrevList = -1;
            int closestPointIdxNextList = -1;

            int closestListIdx = -1;
            int closestPointIdxOnClosestList = -1;

            //iterate over array and calculate normals for one point back. last point will have same normal as one before
            for (int i = 1; i < pointList.Length - 1; i++)
            {
                Point3D p1 = pointList[i];
                Point3D p2 = pointList[i - 1];
                Point3D p3;

                closestPointIdxPrevList = findClosestPoint(pointListIdx - 1, p2, p1, i);
                closestPointIdxNextList = findClosestPoint(pointListIdx + 1, p2, p1, i);

                if (closestPointIdxPrevList < 0 && closestPointIdxNextList < 0)
                {
                    //problem - only one list in BB?!
                    pointList[i].nx = 0;
                    pointList[i].ny = 1;
                    pointList[i].nz = 0;
                    continue;
                }
                else
                {
                    //calculate and compare distances from closest points on other lists between each other and pick
                    //the point that is closer
                    float len1 = float.MaxValue;
                    float len2 = float.MaxValue;

                    if (closestPointIdxPrevList >= 0)
                    {
                        Point3D p3a = ContainedPointLists[pointListIdx - 1][closestPointIdxPrevList];
                        len1 = (p3a - p1).Length + (p3a - p2).Length;
                    }

                    if (closestPointIdxNextList >= 0)
                    {
                        Point3D p3b = ContainedPointLists[pointListIdx + 1][closestPointIdxNextList];
                        len2 = (p3b - p1).Length + (p3b - p2).Length;
                    }

                    if (len1 < len2)
                    {
                        p3             = ContainedPointLists[pointListIdx - 1][closestPointIdxPrevList];
                        closestListIdx = pointListIdx - 1;
                        closestPointIdxOnClosestList = closestPointIdxPrevList;
                    }
                    else
                    {
                        p3             = ContainedPointLists[pointListIdx + 1][closestPointIdxNextList];
                        closestListIdx = pointListIdx + 1;
                        closestPointIdxOnClosestList = closestPointIdxNextList;
                    }
                }

                //handle long And narrow triangles by expanding p1 and p2 farther away from each other
                if (QTreeLeaf.isLongAndNarrow(p1, p2, p3))
                {
                    bool solutionFound = false;

                    int leftIndex  = i - 2;
                    int rightIndex = i + 1;

                    Point3D left = p1, right = p2;
                    int     iterationsNeeded = 0;
                    while (leftIndex >= 0 && rightIndex < pointList.Length && iterationsNeeded < MAX_ITERATIONS_NORMAL)
                    {
                        iterationsNeeded++;

                        p1 = pointList[leftIndex];
                        p2 = pointList[rightIndex];

                        if (!isLongAndNarrow(p1, p2, p3))
                        {
                            solutionFound = true;
                            break;
                        }

                        leftIndex--;
                        rightIndex++;
                    }

                    if (!solutionFound)
                    {
                        p1 = pointList[i];

                        iterationsNeeded = 0;

                        //go through closest list and all the point there to find a more suitable p2
                        for (int cli = closestPointIdxOnClosestList + 1; cli < ContainedPointLists[closestListIdx].Length &&
                             iterationsNeeded < MAX_ITERATIONS_SECOND
                             ; cli++)
                        {
                            p2 = ContainedPointLists[closestListIdx][cli];

                            iterationsNeeded++;

                            if (!isLongAndNarrow(p1, p2, p3))
                            {
                                solutionFound = true;
                                break;
                            }
                        }

                        if (!solutionFound)
                        {
                            iterationsNeeded = 0;
                            //try the other way too
                            for (int cli = closestPointIdxOnClosestList - 1; cli >= 0 &&
                                 iterationsNeeded < MAX_ITERATIONS_SECOND; cli--)
                            {
                                p2 = ContainedPointLists[closestListIdx][cli];

                                iterationsNeeded++;

                                if (!isLongAndNarrow(p1, p2, p3))
                                {
                                    solutionFound = true;
                                    break;
                                }
                            }
                        }

                        if (!solutionFound)
                        {
                            //TODO: find yet another way or revert to the first three points
                            p2 = pointList[i - 1];

                            //seach for p3 on this same list, in case it goes back and forth like it sometimes does

                            iterationsNeeded = 0;
                            //up to point i
                            for (int s = 0; s < pointList.Length && iterationsNeeded < MAX_ITERATIONS_SAME; s++)
                            {
                                if (s < i - 5 || s > i + 5)
                                {
                                    Point3D ppp = pointList[s];
                                    iterationsNeeded++;

                                    if (!isLongAndNarrow(p1, p2, ppp))
                                    {
                                        solutionFound = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }


                //Vector3f normal = Vector3f.CrossProduct(pointList[i - 1] - pointList[i+1], pointList[i+1] - closestPointList[closestPointIdx]);
                //Vector3f normal = Vector3f.CrossProduct(pointList[i - 1] - pointList[i + 1], closestPointList[closestPointIdx] - pointList[i + 1]);
                Vector3f normal = Vector3f.CrossProduct(p2 - p1, p3 - p1);

                normal.Normalize();
                pointList[i].nx = normal.x;
                pointList[i].ny = normal.y;
                pointList[i].nz = normal.z;

                if (normal.z < 0) //z and y coordinates are inverted!! - Z is height here
                {
                    pointList[i].nx = -normal.x;
                    pointList[i].ny = -normal.y;
                    pointList[i].nz = -normal.z;
                }
            }

            //last point has same normal as the one before her. first one is same as second one
            if (len > 1)
            {
                pointList[0].nx = pointList[1].nx;
                pointList[0].ny = pointList[1].ny;
                pointList[0].nz = pointList[1].nz;


                pointList[len - 1].nx = pointList[len - 2].nx;
                pointList[len - 1].ny = pointList[len - 2].ny;
                pointList[len - 1].nz = pointList[len - 2].nz;
            }
        }