예제 #1
0
        private void AnimateRestoreView()
        {
            FastDrawing = true;
            var restoreViewCurrentTime = DateTime.Now;

            var    currentTime              = restoreViewCurrentTime;
            var    startTime                = RestoreViewStartTime;
            var    timeElapsed              = currentTime.Subtract(startTime);
            var    timeElapsedInMs          = timeElapsed.TotalMilliseconds;
            var    totalTimeOfAnimationInMs = RestoreViewTotalTime.TotalMilliseconds;
            double percentCompleted         = timeElapsedInMs / totalTimeOfAnimationInMs;

            if (percentCompleted > 1)
            {
                // Animation is completed. Perform one last draw.
                percentCompleted            = 1;
                IsInAnimatedRestoreView     = false;
                View.UserInteractionEnabled = true;
                CameraIsAtInitialPosition   = !ShouldStartRestoreToInitialPosition;
                AnimationTimer.Invalidate();
            }

            // Get some data from the starting view
            Rhino.Geometry.Point3d sourceTarget = RestoreViewStartViewport.TargetPoint;
            Rhino.Geometry.Point3d sourceCamera = RestoreViewStartViewport.CameraLocation;
            double sourceDistance = sourceCamera.DistanceTo(sourceTarget);

            Rhino.Geometry.Vector3d sourceUp = RestoreViewStartViewport.CameraUp;
            sourceUp.Unitize();

            // Get some data from the ending view
            Rhino.Geometry.Point3d targetTarget = RestoreViewFinishViewport.TargetPoint;
            Rhino.Geometry.Point3d targetCamera = RestoreViewFinishViewport.CameraLocation;
            double targetDistance = targetCamera.DistanceTo(targetTarget);

            Rhino.Geometry.Vector3d targetCameraDir = targetCamera - targetTarget;
            Rhino.Geometry.Vector3d targetUp        = RestoreViewFinishViewport.CameraUp;
            targetUp.Unitize();

            // Adjust the target camera location so that the starting camera to target distance
            // and the ending camera to target distance are the same.  Doing this will calculate
            // a constant rotational angular momentum when tweening the camera location.
            // Further down we independently tween the camera to target distance.
            targetCameraDir.Unitize();
            targetCameraDir *= sourceDistance;
            targetCamera     = targetCameraDir + targetTarget;

            // calculate interim viewport values
            double frameDistance = ViewportInfoExtensions.CosInterp(sourceDistance, targetDistance, percentCompleted);

            Rhino.Geometry.Point3d frameTarget = new Rhino.Geometry.Point3d();

            frameTarget.X = ViewportInfoExtensions.CosInterp(sourceTarget.X, targetTarget.X, percentCompleted);
            frameTarget.Y = ViewportInfoExtensions.CosInterp(sourceTarget.Y, targetTarget.Y, percentCompleted);
            frameTarget.Z = ViewportInfoExtensions.CosInterp(sourceTarget.Z, targetTarget.Z, percentCompleted);

            var origin = Rhino.Geometry.Point3d.Origin;

            Rhino.Geometry.Point3d  frameCamera    = origin + (ViewportInfoExtensions.Slerp((sourceCamera - origin), (targetCamera - origin), percentCompleted));
            Rhino.Geometry.Vector3d frameCameraDir = frameCamera - frameTarget;

            // adjust the camera location along the camera direction vector to preserve the target location and the camera distance
            frameCameraDir.Unitize();
            frameCameraDir *= frameDistance;
            frameCamera     = frameCameraDir + frameTarget;

            Rhino.Geometry.Vector3d frameUp = new Rhino.Geometry.Vector3d(ViewportInfoExtensions.Slerp(sourceUp, targetUp, percentCompleted));

            if (percentCompleted >= 1)
            {
                // put the last redraw at the exact end point to eliminate any rounding errors
                Camera.SetTarget(RestoreViewFinishViewport.TargetPoint, RestoreViewFinishViewport.CameraLocation, RestoreViewFinishViewport.CameraUp);
            }
            else
            {
                Camera.SetTarget(frameTarget, frameCamera, frameUp);
            }

            SetFrustum(Camera, App.Manager.CurrentModel.BBox);

            View.SetNeedsDisplay();

            if (!IsInAnimatedRestoreView)
            {
                // FastDrawing is still enabled and we just scheduled a draw of the model at the final location.
                // This entirely completes the animation. Now schedule one more redraw of the model with FastDrawing disabled
                // and this redraw will be done at exactly the same postion.  This prevents the final animation frame
                // from jumping to the final location because the final draw will take longer with FastDrawing disabled.
                PerformSelector(new Selector("RedrawDetailed"), null, 0.05);
            }
        }