示例#1
0
        /// <summary>
        /// Only if deep is true, then HitCubieResult could have some value
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="deep"></param>
        /// <param name="hitResult"></param>
        /// <returns></returns>
        public bool HitTest(Point pt, bool deep, out HitResult hitResult)
        {
            hitResult = null;
            Ray3D ray = Ext3D.Unproject(pt, _viewpoint, _model.Transform, _inverseViewMatrix, _inverseProjectionMatrix);
            //Debug.WriteLine(string.Format("ray: {0}", ray));
            double?d = this.BoundingBox.Intersects(ray);

            if (!deep)
            {
                if (d != null)
                {
                    //Debug.WriteLine(string.Format("first ray: {0}, distance:{1}", ray, (double)d));
                    hitResult = new HitResult()
                    {
                        Distance = (double)d, HitCubicle = null, HitPoint = ray.Origin + (double)d * ray.Direction
                    };
                }
            }
            else
            {
                List <HitResult> results = new List <HitResult>();
                if (d != null)
                {
                    double?d1;
                    foreach (Cubicle cubicle in _cubicles.Values)
                    {
                        Matrix3D localToWorld = _model.Transform; localToWorld.Invert();// *cubicle.Cubie.Transform;
                        ray = Ext3D.Unproject(pt, _viewpoint, localToWorld, _inverseViewMatrix, _inverseProjectionMatrix);
                        //d1 = cubicle.Cubie.BoundingBox.Intersects(ray);
                        d1 = cubicle.BoundingBox.Intersects(ray);
                        if (d1 != null)
                        {
                            HitResult result = new HitResult()
                            {
                                Distance = (double)d1, HitCubicle = cubicle, HitPoint = ray.Origin + (double)d1 * ray.Direction
                            };
                            results.Add(result);
                        }
                    }
                    results.Sort((x, y) => x.Distance.CompareTo(y.Distance));
                    if (results.Count > 0)
                    {
                        hitResult = results[0];
                    }
                }
            }
            return(d != null);
        }
示例#2
0
        public double TestAngle(Point pt, HitResult prevHit, Axis axis)
        {
            Ray3D ray = Ext3D.Unproject(pt, _viewpoint, _model.Transform, _inverseViewMatrix, _inverseProjectionMatrix);
            //Plane yz = new Plane(-1, 0, 0, prevHit.HitPoint.X);
            //Point3 pyz; double? d = yz.Intersects(ray); Debug.WriteLine(string.Format("second ray: {0}: distance: {1}", ray, (double)d));

            //Debug.WriteLine(string.Format("second ray: {0}", ray));
            double angle = 0;

            switch (axis)
            {
            case Axis.X:
                Plane3D yz = new Plane3D(new Vector3D(-1, 0, 0), prevHit.HitPoint.X); Point3D oyz = new Point3D(prevHit.HitPoint.X, 0, 0);
                Point3D pyz; yz.Intersect(ray, out pyz); Vector3D from = prevHit.HitPoint - oyz; Vector3D to = pyz - oyz;


                angle = Ext3D.AngleBetween(from, to);
                if (Vector3D.DotProduct(Ext3D.UnitX, Vector3D.CrossProduct(from, to)) < 0)
                {
                    angle = -angle;
                }

                break;

            case Axis.Z:
                Plane3D xy = new Plane3D(new Vector3D(0, 0, -1), prevHit.HitPoint.Z); Point3D oxy = new Point3D(0, 0, prevHit.HitPoint.Z);
                Point3D pxy; xy.Intersect(ray, out pxy); from = prevHit.HitPoint - oxy; to = pxy - oxy;


                angle = Ext3D.AngleBetween(from, to);
                if (Vector3D.DotProduct(Ext3D.UnitZ, Vector3D.CrossProduct(from, to)) < 0)
                {
                    angle = -angle;
                }

                break;

            case Axis.Y:
                Plane3D zx = new Plane3D(new Vector3D(0, -1, 0), prevHit.HitPoint.Y); Point3D ozx = new Point3D(0, prevHit.HitPoint.Y, 0);
                Point3D pzx; zx.Intersect(ray, out pzx); from = prevHit.HitPoint - ozx; to = pzx - ozx;


                angle = Ext3D.AngleBetween(from, to);
                if (Vector3D.DotProduct(Ext3D.UnitY, Vector3D.CrossProduct(from, to)) < 0)
                {
                    angle = -angle;
                }

                break;
            }

            /*
             * if (angle < 2)
             *  angle = null;
             * else
             * {
             *  Debug.WriteLine(string.Format("axis: {0}, angle:{1}", axis, angle));
             * }
             */
            return(angle);
        }