Exemplo n.º 1
0
        private static Point3D?CastRay_Cylinder(Point3D point, Vector3D direction, double radius, RayHitTestParameters mouseDownClickRay, RayHitTestParameters mouseDownCenterRay, RayHitTestParameters currentClickRay)
        {
            // Get points on the cylinder
            Point3D?mouseDownClickPoint  = null;
            Point3D?mouseDownCenterPoint = null;
            Point3D?currentClickPoint    = null;

            Point3D[] nearestCylinderPoints, nearestLinePoints;
            if (Math3D.GetClosestPoints_Cylinder_Line(out nearestCylinderPoints, out nearestLinePoints, point, direction, radius, currentClickRay.Origin, currentClickRay.Direction, Math3D.RayCastReturn.ClosestToRay))
            {
                currentClickPoint = nearestCylinderPoints[0];

                if (Math3D.GetClosestPoints_Cylinder_Line(out nearestCylinderPoints, out nearestLinePoints, point, direction, radius, mouseDownClickRay.Origin, mouseDownClickRay.Direction, Math3D.RayCastReturn.ClosestToRay))
                {
                    mouseDownClickPoint = nearestCylinderPoints[0];

                    if (Math3D.GetClosestPoints_Cylinder_Line(out nearestCylinderPoints, out nearestLinePoints, point, direction, radius, mouseDownCenterRay.Origin, mouseDownCenterRay.Direction, Math3D.RayCastReturn.ClosestToRay))
                    {
                        mouseDownCenterPoint = nearestCylinderPoints[0];
                    }
                }
            }

            if (mouseDownCenterPoint == null || mouseDownClickPoint == null || currentClickPoint == null)
            {
                return(currentClickPoint);               // it doesn't matter if this one is null or not, the offset can't be determined, so just return the raw click value
            }

            // Circle only cared about an offset angle, but cylinder needs two things:
            //		Offset line (the part of the offset that is parallel to the cylinder's axis)
            //		Offset angle (the part of the offset that is perpendicular to the cylinder's axis)
            Vector3D   offsetLinear = (mouseDownCenterPoint.Value - mouseDownClickPoint.Value).GetProjectedVector(direction);
            Quaternion offsetRadial = GetRotation_Circle(point, direction, mouseDownClickPoint.Value, mouseDownCenterPoint.Value);



            //TODO: Get the radial offset working as well (sphere is also messed up, the same fix should work for both)



            //TODO: See if this is the most effiecient way or not
            Transform3DGroup transform = new Transform3DGroup();

            //transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(offsetRadial)));
            transform.Children.Add(new TranslateTransform3D(offsetLinear));

            //TODO: Bring currentClickPoint into local coords, do the transform, then put it back into global coords

            // Find the point along the cylinder's axis that is nearest to the current click.  This will become the center of the model coords
            Point3D modelCenter = Math3D.GetClosestPoint_Line_Point(point, direction, currentClickPoint.Value);

            // Shift the click point into model coords
            Vector3D modelClick = currentClickPoint.Value - modelCenter;

            // Adjust by the offset transform (needed to put into model coords, because there is a rotation)
            modelClick = transform.Transform(modelClick);

            // Now put back into world coords
            return(modelCenter + modelClick);
        }
Exemplo n.º 2
0
        /// <summary>
        /// This overload is a straight ray cast, nothing extra
        /// </summary>
        public Point3D?CastRay(RayHitTestParameters ray)
        {
            Point3D?retVal = null;

            switch (_shape)
            {
            case ShapeType.Line:
                #region Line

                Point3D?point1, point2;
                if (Math3D.GetClosestPoints_Line_Line(out point1, out point2, _point, _direction, ray.Origin, ray.Direction))
                {
                    retVal = point1.Value;
                }

                #endregion
                break;

            case ShapeType.Lines:
                #region Lines

                retVal = CastRay_LinesCircles(_lines, null, ray);

                #endregion
                break;

            case ShapeType.Plane:
                #region Plane

                retVal = Math3D.GetIntersection_Plane_Line(_plane, ray.Origin, ray.Direction);

                #endregion
                break;

            case ShapeType.Circle:
                #region Circle

                Point3D[] nearestCirclePoints, nearestLinePoints;
                if (Math3D.GetClosestPoints_Circle_Line(out nearestCirclePoints, out nearestLinePoints, _plane, _point, _radius, ray.Origin, ray.Direction, Math3D.RayCastReturn.ClosestToRay))
                {
                    retVal = nearestCirclePoints[0];
                }

                #endregion
                break;

            case ShapeType.Circles:
                #region Circles

                retVal = CastRay_LinesCircles(null, _circles, ray);

                #endregion
                break;

            case ShapeType.LinesCircles:
                #region LinesCircles

                retVal = CastRay_LinesCircles(_lines, _circles, ray);

                #endregion
                break;

            case ShapeType.Cylinder:
                #region Cylinder

                Point3D[] nearestCylinderPoints, nearestLinePoints2;
                if (Math3D.GetClosestPoints_Cylinder_Line(out nearestCylinderPoints, out nearestLinePoints2, _point, _direction, _radius, ray.Origin, ray.Direction, Math3D.RayCastReturn.ClosestToRay))
                {
                    retVal = nearestCylinderPoints[0];
                }

                #endregion
                break;

            case ShapeType.Sphere:
                #region Sphere

                Point3D[] nearestSpherePoints, nearestLinePoints3;
                Math3D.GetClosestPoints_Sphere_Line(out nearestSpherePoints, out nearestLinePoints3, _point, _radius, ray.Origin, ray.Direction, Math3D.RayCastReturn.ClosestToRay);
                {
                    retVal = nearestSpherePoints[0];
                }

                #endregion
                break;

            case ShapeType.Mesh:
                throw new ApplicationException("finish this");

            case ShapeType.None:
                retVal = null;
                break;

            default:
                throw new ApplicationException("Unknown ShapeType: " + _shape.ToString());
            }

            return(retVal);
        }