Пример #1
0
        public override box3d bounds()
        {
            box3d b = new box3d();

            b[0] = p0;
            b[1] = p0;

            if (p1.x < b.xl)
            {
                b.xl = p1.x;
            }
            if (p1.y < b.yl)
            {
                b.yl = p1.y;
            }
            if (p1.z < b.zl)
            {
                b.zl = p1.z;
            }
            if (p1.x > b.xh)
            {
                b.xh = p1.x;
            }
            if (p1.y > b.yh)
            {
                b.yh = p1.y;
            }
            if (p1.z > b.zh)
            {
                b.zh = p1.z;
            }

            if (p2.x < b.xl)
            {
                b.xl = p2.x;
            }
            if (p2.y < b.yl)
            {
                b.yl = p2.y;
            }
            if (p2.z < b.zl)
            {
                b.zl = p2.z;
            }
            if (p2.x > b.xh)
            {
                b.xh = p2.x;
            }
            if (p2.y > b.yh)
            {
                b.yh = p2.y;
            }
            if (p2.z > b.zh)
            {
                b.zh = p2.z;
            }

            return(b);
        }
Пример #2
0
        public virtual box3d bounds()
        {
            box3d b = new box3d();

            b.xh = b.yh = b.zh = Double.MaxValue;
            b.xl = b.yl = b.zl = Double.MinValue;
            return(b);
        }
Пример #3
0
 public static bool rayBoxIntersectPos(vect3d ray_pos, vect3d ray_dir, box3d box, out double dist, out vect3d pos, out int d, out int n)
 {
     if (rayBoxIntersectDist(ray_pos, ray_dir, box, out dist, out d, out n))
     {
         pos = ray_pos + ray_dir * dist;
         return(true);
     }
     pos = new vect3d(0);
     return(false);
 }
Пример #4
0
        public GroupTree(List <Occluder> list, Shader s)
        {
            shader = s;

            //// randomize list
            //for (int i = list.Count - 1; i > 1; i--)
            //{
            //    int r = Custom.Rand.rand.Next(i - 1);
            //    var t = list[i];
            //    list[i] = list[r];
            //    list[r] = t;
            //}

            // calculate bounds of whole volume
            box3d bounds = new box3d();

            bounds.xh = bounds.yh = bounds.zh = Double.MinValue;
            bounds.xl = bounds.yl = bounds.zl = Double.MaxValue;

            foreach (var v in list)
            {
                box3d b = v.bounds();

                if (b.xl < bounds.xl)
                {
                    bounds.xl = b.xl;
                }
                if (b.yl < bounds.yl)
                {
                    bounds.yl = b.yl;
                }
                if (b.zl < bounds.zl)
                {
                    bounds.zl = b.zl;
                }
                if (b.xh > bounds.xh)
                {
                    bounds.xh = b.xh;
                }
                if (b.yh > bounds.yh)
                {
                    bounds.yh = b.yh;
                }
                if (b.zh > bounds.zh)
                {
                    bounds.zh = b.zh;
                }
            }

            // build the tree
            tree = new KDTreeOccluder(list, bounds, 0, Double.MaxValue);
        }
Пример #5
0
 public override bool intersects_box(box3d b)
 {
     return(Custom.Intersect.intersect_aabb_tri(b[0], b[1], p0, p1, p2));
 }
Пример #6
0
        public static bool rayBoxIntersectDist(vect3d ray_pos, vect3d ray_dir, box3d box, out double dist, out int face_d, out int face_n)
        {
            vect3d box_low  = box[0];
            vect3d box_high = box[1];

            dist = 0;
            double Tnear = -1e30;
            double Tfar = 1e30;
            double T1, T2;

            face_d = -1;
            face_n = -1;
            // check bounding box to see if it enters level
            // this method assumes bounding box is already in coordinate system of the level
            for (int d = 0; d < 3; d++)
            {
                int n_temp = 0;
                if (ray_dir[d] == 0)
                {
                    if (ray_pos[d] > box_high[d] || ray_pos[d] < box_low[d])
                    {
                        return(false);
                    }

                    //int dp = (d + 1) % 3;
                    //int dpp = (d + 2) % 3;

                    //if (ray_pos[dp] > box_high[dp] || ray_pos[dp] < box_low[dp])
                    //    return false;
                    //if (ray_pos[dpp] > box_high[dpp] || ray_pos[dpp] < box_low[dpp])
                    //    return false;
                }
                else
                {
                    T1 = (box_low[d] - ray_pos[d]) / ray_dir[d];
                    T2 = (box_high[d] - ray_pos[d]) / ray_dir[d];
                    if (T1 > T2)
                    {
                        //swap(T1, T2); // since T1 intersection should be the nearest
                        double t = T1;
                        T1     = T2;
                        T2     = t;
                        n_temp = (n_temp + 1) % 2;
                    }
                    if (T1 > Tnear)
                    {
                        face_d = d;
                        face_n = n_temp;
                        Tnear  = T1; // largest Tnear
                    }
                    if (T2 < Tfar)
                    {
                        Tfar = T2;    // smallest Tfar
                    }
                    if (Tnear > Tfar) // box is missed
                    {
                        return(false);
                    }
                    if (Tfar < 0)
                    {
                        return(false); // box is behind ray
                    }
                }
            }
            dist = Tnear;
            if (dist < 0)
            {
                return(false);
            }
            return(true);
        }
Пример #7
0
 public virtual bool intersects_box(box3d b)
 {
     return(true);
 }
Пример #8
0
        public KDTreeOccluder(List <Occluder> list_in, box3d bounds_in, int depth, double parent_val)
        {
            if (depth > max_depth)
            {
                max_depth = depth;
                Console.WriteLine("reached depth {0}", depth);
            }

            bounds = bounds_in;
            list   = list_in;
            double area = bounds.area();

            // calc the optimal way to split the node
            int    min_axis = 0;
            double min_pos  = 0;
            double min_val  = Double.MaxValue;

            int samples = 5;
            int a       = depth % 3;

            for (int i = 0; i < samples; i++)
            {
                double pos = bounds[0, a] + (bounds[1, a] - bounds[0, a]) * (double)(i + .5) / (double)samples;
                double cnt_l = 0, cnt_r = 0;
                box3d  b_l = bounds, b_r = bounds;
                b_l[1, a] = pos;
                b_r[0, a] = pos;

                for (int k = 0; k < list.Count; k++)
                {
                    bool cross_l, cross_r;
                    list[k].check_crossing(pos, a, out cross_l, out cross_r);
                    if (cross_l)
                    {
                        cnt_l++;
                    }
                    if (cross_r)
                    {
                        cnt_r++;
                    }
                }

                double val = 1 + (cnt_l * b_l.area() + cnt_r * b_r.area()) / area;

                if (val < min_val)
                {
                    min_val  = val;
                    min_axis = a;
                    min_pos  = pos;
                }
            }

            // split
            if (min_val < parent_val && depth < 100)
            {
                // is internal
                box3d b_l = bounds, b_r = bounds;
                b_l[1, min_axis] = min_pos;
                b_r[0, min_axis] = min_pos;

                List <Occluder> L = new List <Occluder>(), R = new List <Occluder>();
                foreach (var v in list)
                {
                    if (v.intersects_box(b_l))
                    {
                        L.Add(v);
                    }
                    if (v.intersects_box(b_r))
                    {
                        R.Add(v);
                    }
                }

                left  = new KDTreeOccluder(L, b_l, depth + 1, min_val);
                right = new KDTreeOccluder(R, b_r, depth + 1, min_val);
            }
            else
            {
                // is leaf
            }
        }