예제 #1
0
 public void OnMouseMove(Point new_pos)
 {
     if (selected == null)
     {
         return;
     }
     if (moving)
     {
         TRay world_ray = render.ToWorld(new_pos);
         if (rotating)
         {
             Vector3 temp       = Vector3.Cross(world_ray.dir, moving_dir);
             float   new_proj   = Vector3.Dot(world_ray.pos, temp);
             Matrix  new_orient = start_orient * Matrix.RotationAxis(moving_dir, new_proj);
             selected.SetRotation(new_orient);
         }
         else
         {
             float curr_proj = 0;;
             (new TRay(start_pos, moving_dir)).PointNearestToOtherRay(world_ray, ref curr_proj);
             selected.SetPos(start_pos + moving_dir * (curr_proj - start_proj));
         }
     }
     else
     {
         TestAxises(new_pos);
     }
 }
예제 #2
0
        public void PointNearestToOtherRay(TRay r, ref float point)
        {
            Vector3 t = Vector3.Cross(dir, r.dir);
            TPlane  p = new TPlane(Vector3.Cross(t, r.dir), r.pos);

            Inters(p, ref point);
        }
예제 #3
0
        public bool Overlaps(TRay ray)
        {
            float b; Vector3 t;

            t = ray.pos - pos;
            b = (Vector3.Dot(ray.dir, t)) * 2.0f;
            return(b * b - 4 * Vector3.Dot(ray.dir, ray.dir) * (Vector3.Dot(t, t) - radius * radius) >= 0);
        }
예제 #4
0
 public void RayQuery(TVector <int> result, TRay ray)
 {
     result.Pop(result.Length);
     if (nodes[root].dims.Overlaps(ray))
     {
         RayQuery(nodes[root], result, ray);
     }
     DeleteRepeatingValues(result);
 }
예제 #5
0
        public bool Overlaps(TRay ray)
        {
            Matrix m = orient;

            m.Invert();//TODO можно лишь транспонировать матрицу 3x3,а смещение вычислять вручную
            TRay modified_ray = new TRay(Vector3.TransformCoordinate(ray.pos, m), Vector3.TransformNormal(ray.dir, m));

            return(aabb.Overlaps(modified_ray));
        }
예제 #6
0
        void TestAxises(Point new_pos)
        {
            float   size = size_mul * Vector3.Length(selected.GetPos() - cam.GetPos());
            Vector3 pos  = selected.GetPos();
            Matrix  m;
            Vector3 bx, by, bz;

            if (world_movement)
            {
                m  = Matrix.Translation(selected.GetPos());
                bx = new Vector3(1, 0, 0);
                by = new Vector3(0, 1, 0);
                bz = new Vector3(0, 0, 1);
            }
            else
            {
                m  = selected.GetOrient();
                bx = new Vector3(m.M11, m.M12, m.M13);
                by = new Vector3(m.M21, m.M22, m.M23);
                bz = new Vector3(m.M31, m.M32, m.M33);
            }
            TOBB x, y, z;
            TOBB xy, yz, zx;//TODO перемещение в плоскости

            //создаем OBB's на месте направляющих осей для определения пересечения
            x = new TOBB(new Vector3(1, 0, 0) * size * 0.5f, new Vector3(size, aabb_size_mul * size, aabb_size_mul * size));
            x.SetOrient(m);
            y = new TOBB(new Vector3(0, 1, 0) * size * 0.5f, new Vector3(aabb_size_mul * size, size, aabb_size_mul * size));
            y.SetOrient(m);
            z = new TOBB(new Vector3(0, 0, 1) * size * 0.5f, new Vector3(aabb_size_mul * size, aabb_size_mul * size, size));
            z.SetOrient(m);
            TRay world_ray = render.ToWorld(new_pos);

            x_selected = false;
            y_selected = false;
            z_selected = false;
            x_selected = x.Overlaps(world_ray);
            if (x_selected)
            {
                return;
            }
            y_selected = y.Overlaps(world_ray);
            if (x_selected || y_selected)
            {
                return;
            }
            z_selected = z.Overlaps(world_ray);
        }
예제 #7
0
        public bool Overlaps(TRay ray)
        {
            //
            float   max_length = 10000;
            Vector3 mid        = ray.pos + ray.dir * (max_length / 2.0f);
            Vector3 dir        = ray.dir;
            float   hl         = (max_length / 2.0f);
            Vector3 T          = pos - mid;
            Vector3 E          = widths;

            E.Multiply(0.5f);
            float r;

            // проверяем, является ли одна из осей X,Y,Z разделяющей
            if ((Math.Abs(T.X) > E.X + hl * Math.Abs(dir.X)) ||
                (Math.Abs(T.Y) > E.Y + hl * Math.Abs(dir.Y)) ||
                (Math.Abs(T.Z) > E.Z + hl * Math.Abs(dir.Z)))
            {
                return(false);
            }

            // проверяем X ^ dir
            r = E.Y * Math.Abs(dir.Z) + E.Z * Math.Abs(dir.Y);
            if (Math.Abs(T.Y * dir.Z - T.Z * dir.Y) > r)
            {
                return(false);
            }

            // проверяем Y ^ dir
            r = E.X * Math.Abs(dir.Z) + E.Z * Math.Abs(dir.X);
            if (Math.Abs(T.Z * dir.X - T.X * dir.Z) > r)
            {
                return(false);
            }

            // проверяем Z ^ dir
            r = E.X * Math.Abs(dir.Y) + E.Y * Math.Abs(dir.X);
            if (Math.Abs(T.X * dir.Y - T.Y * dir.X) > r)
            {
                return(false);
            }

            return(true);
        }
예제 #8
0
 void RayQuery(TOctreeNode node, TVector <int> result, TRay ray)
 {
     if (node.is_end != -1)
     {
         result.Add(items[node.is_end]);
     }
     else
     {
         for (int i = 0; i < 8; i++)
         {
             if (node.child[i] != -1)
             {
                 if (nodes[node.child[i]].dims.Overlaps(ray))
                 {
                     RayQuery(nodes[node.child[i]], result, ray);
                 }
             }
         }
     }
 }
예제 #9
0
 public void OnMouseDown(Point new_pos)
 {
     if (selected == null)
     {
         return;
     }
     x_selected = false;
     y_selected = false;
     z_selected = false;
     TestAxises(new_pos);
     if (x_selected)
     {
         moving_dir = bx;
     }
     else if (y_selected)
     {
         moving_dir = by;
     }
     else if (z_selected)
     {
         moving_dir = bz;
     }
     if (x_selected || y_selected || z_selected)
     {
         TRay world_ray = render.ToWorld(new_pos);
         moving = true;
         if (rotating)
         {
             start_orient = selected.GetOrient();
             Vector3 temp = Vector3.Cross(world_ray.dir, moving_dir);
             start_proj = Vector3.Dot(world_ray.pos, temp);
         }
         else
         {
             start_pos = selected.GetPos();
             (new TRay(start_pos, moving_dir)).PointNearestToOtherRay(world_ray, ref start_proj);
         }
     }
 }