private void Trackball_GetOrbitRadius(object sender, GetOrbitRadiusArgs e)
 {
     //TODO: This isn't perfect.  The camera isn't rotating around the ship, but where they clicked.  It's subtle, but while the user is orbiting the camera,
     //the ship will drift relative to the camera
     if (_selectedBean != null)
     {
         e.Result = _selectedBean.CameraOffset.Length;
     }
 }
Beispiel #2
0
        protected virtual double OnGetOrbitRadius()
        {
            //TODO:  Don't just get the radius, get a live point to follow

            // Raise an event, requesting the radius
            if (this.GetOrbitRadius != null)
            {
                GetOrbitRadiusArgs args = new GetOrbitRadiusArgs(_camera.Position, _camera.LookDirection);
                this.GetOrbitRadius(this, args);

                if (args.Result != null)
                {
                    // They set the value, return it
                    return args.Result.Value;
                }
            }

            // If execution gets here, then the event never returned anything.  Figure out the radius myself

            if (!_shouldHitTestOnOrbit)
            {
                // This works great when looking at the origin, but is really weird when offset from the orign
                return _camera.Position.ToVector().Length;
            }

            #region Ray Cast

            // If there are no hits when fired from the dead center, fire off some more rays a random offset from the center
            //TODO: See if there is a more efficient way of getting all 3D objects on screen

            double width = _eventSource.ActualWidth;
            double height = _eventSource.ActualHeight;
            double halfWidth = width * .5d;
            double halfHeight = height * .5d;

            for (int cntr = 0; cntr < 50; cntr++)
            {
                Vector3D rayVector = new Vector3D(0, 0, 0);
                if (cntr > 0)		// the first attempt will be the center of the viewport
                {
                    rayVector = Math3D.GetRandomVector_Circular(.25d);
                }

                double? distance = OrbitGetObjectDistance(_eventSource, new Point(halfWidth + (rayVector.X * width), halfHeight + (rayVector.Y * height)));
                if (distance != null && (distance.Value * distance.Value) < _camera.Position.ToVector().LengthSquared)		// if it's greater than the distance to the origin, then I want to ignore it
                {
                    return distance.Value;
                }
            }

            #endregion

            return _camera.Position.ToVector().Length;

            #region Wrong Idea

            //Vector3D position = _camera.Position.ToVector();

            //if (Vector3D.DotProduct(_camera.LookDirection, position) >= 0)
            //{
            //    // They are looking away from the origin, so just use the distance to the origin
            //    return position.Length;
            //}
            //else
            //{
            //    // Get a ray from the origin that intersects the look ray at 90 degrees

            //    // This first orthogonal is a reference
            //    Vector3D orth1 = Vector3D.CrossProduct(_camera.LookDirection, position);

            //    // This second orthogonal is orthogonal to the look direction, but in the plane of the pos/look dir
            //    Vector3D orth2 = Vector3D.CrossProduct(orth1, _camera.LookDirection);

            //    // Now I need to intersect look direction with the line coming from the origin in the direction of the second orthogonal
            //    Point3D? intersectPoint = Math3D.GetIntersectionOfTwoLines(new Point3D(0, 0, 0), orth2, _camera.Position, _camera.LookDirection);
            //    if (intersectPoint == null)
            //    {
            //        // This should never happen?  Only if math drift is too much?
            //        return position.Length;
            //    }
            //    else
            //    {
            //        double retVal = (_camera.Position - intersectPoint.Value).Length;
            //        double distToOrigin = position.Length;

            //        return Math.Min(retVal, distToOrigin);		// I can't just blindly return the calculated distance, because they could be looking nearly parallel to the line to the origin.  In that case the distance returned would be huge
            //    }
            //}

            #endregion
        }
        private void Trackball_GetOrbitRadius(object sender, GetOrbitRadiusArgs e)
        {
            //TODO:  e should also pass in the mouse click point, so there is camera position, and click position, this
            // listener can decide which they want (I can't reuse the same direction, because of the perspective)

            RayCastResult result = _world.CastRay(e.Position, e.Direction, 30d, World.BodyFilterType.ExcludeBodies);

            if (result != null)
            {
                e.Result = result.HitDistance;
            }

        }