private static Point3D?CastRay_Sphere(Point3D center, double radius, RayHitTestParameters mouseDownClickRay, RayHitTestParameters mouseDownCenterRay, RayHitTestParameters currentClickRay) { // Get points on the sphere Point3D[] nearestSpherePoints, nearestLinePoints; Math3D.GetClosestPoints_Sphere_Line(out nearestSpherePoints, out nearestLinePoints, center, radius, currentClickRay.Origin, currentClickRay.Direction, Math3D.RayCastReturn.ClosestToRay); Point3D currentClickPoint = nearestSpherePoints[0]; //TODO: The rest of this method is flawed, it should be fixed (I don't think it's as simplistic as I'm making it - or there is just a flaw in the math) // Actually, I think the flaw is taking it to world coords, rotating, and putting back? return(currentClickPoint); //Math3D.GetClosestPointsBetweenLineSphere(out nearestSpherePoints, out nearestLinePoints, center, radius, mouseDownClickRay.Origin, mouseDownClickRay.Direction, Math3D.RayCastReturn.ClosestToRay); //Point3D mouseDownClickPoint = nearestSpherePoints[0]; //Math3D.GetClosestPointsBetweenLineSphere(out nearestSpherePoints, out nearestLinePoints, center, radius, mouseDownCenterRay.Origin, mouseDownCenterRay.Direction, Math3D.RayCastReturn.ClosestToRay); //Point3D mouseDownCenterPoint = nearestSpherePoints[0]; //// Get the offset from mouse down click to center //Vector3D mouseDownClickLine = mouseDownClickPoint - center; //Vector3D mouseDownCenterLine = mouseDownCenterPoint - center; //Quaternion offset = Math3D.GetRotation(mouseDownClickLine, mouseDownCenterLine); //// Convert to local coords, rotate //Vector3D currentClickLine = currentClickPoint - center; //currentClickLine = new RotateTransform3D(new QuaternionRotation3D(offset)).Transform(currentClickLine); //// Now convert back to world coords //return center + currentClickLine; }
/// <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); }