Beispiel #1
0
 public Box3f(AxisAlignedBox3f aaBox)
 {
     Extent = 0.5f * aaBox.Diagonal;
     Center = aaBox.Min + Extent;
     AxisX  = Vector3f.AxisX;
     AxisY  = Vector3f.AxisY;
     AxisZ  = Vector3f.AxisZ;
 }
Beispiel #2
0
 public Box3f(AxisAlignedBox3f aaBox)
 {
     // [RMS] this should produce Empty for aaBox.Empty...
     Extent = new Vector3f(aaBox.Width * 0.5f, aaBox.Height * 0.5f, aaBox.Depth * 0.5f);
     Center = aaBox.Center;
     AxisX  = Vector3f.AxisX;
     AxisY  = Vector3f.AxisY;
     AxisZ  = Vector3f.AxisZ;
 }
Beispiel #3
0
        public static AxisAlignedBox3f Bounds <T>(IEnumerable <T> values, Func <T, Vector3f> PositionF)
        {
            AxisAlignedBox3f box = AxisAlignedBox3f.Empty;

            foreach (T t in values)
            {
                box.Contain(PositionF(t));
            }
            return(box);
        }
        public static AxisAlignedBox3f Bounds(IEnumerable <Vector3f> positions)
        {
            AxisAlignedBox3f box = AxisAlignedBox3f.Empty;

            foreach (Vector3f v in positions)
            {
                box.Contain(v);
            }
            return(box);
        }
Beispiel #5
0
        int split_tri_set_sorted(int[] triangles, Vector3d[] centers, int iStart, int iCount, int depth, int minTriCount,
                                 boxes_set tris, boxes_set nodes, out AxisAlignedBox3f box)
        {
            box = AxisAlignedBox3f.Empty;
            int iBox = -1;

            if (iCount < minTriCount)
            {
                // append new triangles box
                iBox = tris.iBoxCur++;
                tris.box_to_index.insert(tris.iIndicesCur, iBox);

                tris.index_list.insert(iCount, tris.iIndicesCur++);
                for (int i = 0; i < iCount; ++i)
                {
                    tris.index_list.insert(triangles[iStart + i], tris.iIndicesCur++);
                    box.Contain(mesh.GetTriBounds(triangles[iStart + i]));
                }

                tris.box_centers.insert(box.Center, iBox);
                tris.box_extents.insert(box.Extents, iBox);

                return(-(iBox + 1));
            }

            AxisComp c = new AxisComp()
            {
                Axis = depth % 3
            };

            Array.Sort(centers, triangles, iStart, iCount, c);
            int mid = iCount / 2;
            int n0  = mid;
            int n1  = iCount - mid;

            // create child boxes
            AxisAlignedBox3f box1;
            int child0 = split_tri_set_sorted(triangles, centers, iStart, n0, depth + 1, minTriCount, tris, nodes, out box);
            int child1 = split_tri_set_sorted(triangles, centers, iStart + mid, n1, depth + 1, minTriCount, tris, nodes, out box1);

            box.Contain(box1);

            // append new box
            iBox = nodes.iBoxCur++;
            nodes.box_to_index.insert(nodes.iIndicesCur, iBox);

            nodes.index_list.insert(child0, nodes.iIndicesCur++);
            nodes.index_list.insert(child1, nodes.iIndicesCur++);

            nodes.box_centers.insert(box.Center, iBox);
            nodes.box_extents.insert(box.Extents, iBox);

            return(iBox);
        }
Beispiel #6
0
        // accumulate triangle counts and track each box-parent index.
        // also checks that triangles are contained in boxes
        private void test_coverage(int[] tri_counts, int[] parent_indices, int iBox)
        {
            int idx = box_to_index[iBox];

            debug_check_child_tris_in_box(iBox);

            if (idx < triangles_end)
            {
                // triange-list case, array is [N t1 t2 ... tN]
                int n = index_list[idx];
                AxisAlignedBox3f box = get_box(iBox);
                for (int i = 1; i <= n; ++i)
                {
                    int ti = index_list[idx + i];
                    tri_counts[ti]++;

                    Index3i tv = mesh.GetTriangle(ti);
                    for (int j = 0; j < 3; ++j)
                    {
                        Vector3f v = (Vector3f)mesh.GetVertex(tv[j]);
                        if (!box.Contains(v))
                        {
                            Util.gBreakToDebugger();
                        }
                    }
                }
            }
            else
            {
                int i0 = index_list[idx];
                if (i0 < 0)
                {
                    // negative index means we only have one 'child' box to descend into
                    i0 = (-i0) - 1;
                    parent_indices[i0] = iBox;
                    test_coverage(tri_counts, parent_indices, i0);
                }
                else
                {
                    // positive index, two sequential child box indices to descend into
                    i0 = i0 - 1;
                    parent_indices[i0] = iBox;
                    test_coverage(tri_counts, parent_indices, i0);
                    int i1 = index_list[idx + 1];
                    i1 = i1 - 1;
                    parent_indices[i1] = iBox;
                    test_coverage(tri_counts, parent_indices, i1);
                }
            }
        }
Beispiel #7
0
        public AxisAlignedBox3f Intersect(AxisAlignedBox3f box)
        {
            AxisAlignedBox3f intersect = new AxisAlignedBox3f(
                Math.Max(Min.x, box.Min.x), Math.Max(Min.y, box.Min.y), Math.Max(Min.z, box.Min.z),
                Math.Min(Max.x, box.Max.x), Math.Min(Max.y, box.Max.y), Math.Min(Max.z, box.Max.z));

            if (intersect.Height <= 0 || intersect.Width <= 0 || intersect.Depth <= 0)
            {
                return(AxisAlignedBox3f.Empty);
            }
            else
            {
                return(intersect);
            }
        }
Beispiel #8
0
        // Appends a box that contains free triangles in one-ring of vertex vid.
        // If tri count is < spill threshold, push onto spill list instead.
        // Returns # of free tris found.
        int add_one_ring_box(int vid, byte[] used_triangles, int[] temp_tris,
                             ref int iBoxCur, ref int iIndicesCur,
                             DVector <int> spill, int nSpillThresh)
        {
            // collect free triangles
            int num_free = 0;

            foreach (int tid in mesh.VtxTrianglesItr(vid))
            {
                if (used_triangles[tid] == 0)
                {
                    temp_tris[num_free++] = tid;
                }
            }

            // none free, get out
            if (num_free == 0)
            {
                return(0);
            }

            // if we only had a couple free triangles, wait and see if
            // they get picked up by another vert
            if (num_free < nSpillThresh)
            {
                spill.Add(vid);
                return(num_free);
            }

            // append new box
            AxisAlignedBox3f box = AxisAlignedBox3f.Empty;
            int iBox             = iBoxCur++;

            box_to_index.insert(iIndicesCur, iBox);

            index_list.insert(num_free, iIndicesCur++);
            for (int i = 0; i < num_free; ++i)
            {
                index_list.insert(temp_tris[i], iIndicesCur++);
                used_triangles[temp_tris[i]]++;     // incrementing for sanity check below, just need to set to 1
                box.Contain(mesh.GetTriBounds(temp_tris[i]));
            }

            box_centers.insert(box.Center, iBox);
            box_extents.insert(box.Extents, iBox);
            return(num_free);
        }
Beispiel #9
0
        public AxisAlignedBox3f ToAABB()
        {
            // [TODO] probably more efficient way to do this...at minimum can move center-shift
            // to after the containments...
            Vector3f         extAxis0 = Extent.x * AxisX;
            Vector3f         extAxis1 = Extent.y * AxisY;
            Vector3f         extAxis2 = Extent.z * AxisZ;
            AxisAlignedBox3f result   = new AxisAlignedBox3f(Center - extAxis0 - extAxis1 - extAxis2);

            result.Contain(Center + extAxis0 - extAxis1 - extAxis2);
            result.Contain(Center + extAxis0 + extAxis1 - extAxis2);
            result.Contain(Center - extAxis0 + extAxis1 - extAxis2);
            result.Contain(Center - extAxis0 - extAxis1 + extAxis2);
            result.Contain(Center + extAxis0 - extAxis1 + extAxis2);
            result.Contain(Center + extAxis0 + extAxis1 + extAxis2);
            result.Contain(Center - extAxis0 + extAxis1 + extAxis2);
            return(result);
        }
Beispiel #10
0
        // do full tree traversal below iBox to make sure that all child triangles are contained
        void debug_check_child_tris_in_box(int iBox)
        {
            AxisAlignedBox3f box = get_box(iBox);
            TreeTraversal    t   = new TreeTraversal()
            {
                NextTriangleF = (tID) => {
                    Index3i tv = mesh.GetTriangle(tID);
                    for (int j = 0; j < 3; ++j)
                    {
                        Vector3f v = (Vector3f)mesh.GetVertex(tv[j]);
                        if (box.Contains(v) == false)
                        {
                            Util.gBreakToDebugger();
                        }
                    }
                }
            };

            tree_traversal(iBox, 0, t);
        }
Beispiel #11
0
        int split_tri_set_midpoint(int[] triangles, Vector3d[] centers, int iStart, int iCount, int depth, int minTriCount,
                                   boxes_set tris, boxes_set nodes, out AxisAlignedBox3f box)
        {
            box = AxisAlignedBox3f.Empty;
            int iBox = -1;

            if (iCount < minTriCount)
            {
                // append new triangles box
                iBox = tris.iBoxCur++;
                tris.box_to_index.insert(tris.iIndicesCur, iBox);

                tris.index_list.insert(iCount, tris.iIndicesCur++);
                for (int i = 0; i < iCount; ++i)
                {
                    tris.index_list.insert(triangles[iStart + i], tris.iIndicesCur++);
                    box.Contain(mesh.GetTriBounds(triangles[iStart + i]));
                }

                tris.box_centers.insert(box.Center, iBox);
                tris.box_extents.insert(box.Extents, iBox);

                return(-(iBox + 1));
            }

            //compute interval along an axis and find midpoint
            int        axis     = depth % 3;
            Interval1d interval = Interval1d.Empty;

            for (int i = 0; i < iCount; ++i)
            {
                interval.Contain(centers[iStart + i][axis]);
            }
            double midpoint = interval.Center;

            int n0, n1;

            if (Math.Abs(interval.a - interval.b) > MathUtil.ZeroTolerance)
            {
                // we have to re-sort the centers & triangles lists so that centers < midpoint
                // are first, so that we can recurse on the two subsets. We walk in from each side,
                // until we find two out-of-order locations, then we swap them.
                int l = 0;
                int r = iCount - 1;
                while (l < r)
                {
                    // [RMS] is <= right here? if v.axis == midpoint, then this loop
                    //   can get stuck unless one of these has an equality test. But
                    //   I did not think enough about if this is the right thing to do...
                    while (centers[iStart + l][axis] <= midpoint)
                    {
                        l++;
                    }
                    while (centers[iStart + r][axis] > midpoint)
                    {
                        r--;
                    }
                    if (l >= r)
                    {
                        break;      //done!
                    }
                    //swap
                    Vector3d tmpc = centers[iStart + l]; centers[iStart + l] = centers[iStart + r];  centers[iStart + r] = tmpc;
                    int      tmpt = triangles[iStart + l]; triangles[iStart + l] = triangles[iStart + r]; triangles[iStart + r] = tmpt;
                }

                n0 = l;
                n1 = iCount - n0;
                Debug.Assert(n0 >= 1 && n1 >= 1);
            }
            else
            {
                // interval is near-empty, so no point trying to do sorting, just split half and half
                n0 = iCount / 2;
                n1 = iCount - n0;
            }

            // create child boxes
            AxisAlignedBox3f box1;
            int child0 = split_tri_set_midpoint(triangles, centers, iStart, n0, depth + 1, minTriCount, tris, nodes, out box);
            int child1 = split_tri_set_midpoint(triangles, centers, iStart + n0, n1, depth + 1, minTriCount, tris, nodes, out box1);

            box.Contain(box1);

            // append new box
            iBox = nodes.iBoxCur++;
            nodes.box_to_index.insert(nodes.iIndicesCur, iBox);

            nodes.index_list.insert(child0, nodes.iIndicesCur++);
            nodes.index_list.insert(child1, nodes.iIndicesCur++);

            nodes.box_centers.insert(box.Center, iBox);
            nodes.box_extents.insert(box.Extents, iBox);

            return(iBox);
        }
Beispiel #12
0
 public bool Intersects(AxisAlignedBox3f box)
 {
     return(!((box.Max.x <= Min.x) || (box.Min.x >= Max.x) ||
              (box.Max.y <= Min.y) || (box.Min.y >= Max.y) ||
              (box.Max.z <= Min.z) || (box.Min.z >= Max.z)));
 }
Beispiel #13
0
 public void Contain(AxisAlignedBox3f box)
 {
     Contain(box.Min);
     Contain(box.Max);
 }