Ejemplo n.º 1
0
        public void EndFlight()
        {
            inUse   = false;
            bCancel = true;
            speed   = 0;
            globeDisplay.IsNavigating = false;

            // reposition target
            PointZ currentObs = new PointZ();
            IPoint newTarget  = new PointClass();

            currentObs.x = camera.Observer.X;
            currentObs.y = camera.Observer.Y;
            currentObs.z = camera.Observer.Z;

            int orX    = 0;
            int orY    = 0;
            int width  = 0;
            int height = 0;

            camera.GetViewport(ref orX, ref orY, ref width, ref height);

            object obj1;
            object obj2;

            try
            {
                globeDisplay.Locate(globeDisplay.ActiveViewer, width / 2, height / 2, true, true, out newTarget, out obj1, out obj2);
            }
            catch (System.Exception e)
            {
                MessageBox.Show(e.Message);
                MessageBox.Show(e.StackTrace.ToString());
            }

            if (newTarget == null) // no intersection with globe, but don't let the target to be too far
            {
                newTarget = camera.Target;
                PointZ tar = new PointZ(currentObs.x, currentObs.y, currentObs.z);

                double elevObs = tar.Norm() - 1.0;
                if (elevObs <= 0.0001)
                {
                    elevObs = 0.0001;
                }

                PointZ oldTarget = new PointZ(newTarget.X, newTarget.Y, newTarget.Z);
                PointZ dir       = (oldTarget - tar);
                double val       = dir.Norm();
                if (val > 0.0)
                {
                    dir.x = dir.x * elevObs * 10 / val;
                    dir.y = dir.y * elevObs * 10 / val;
                    dir.z = dir.z * elevObs * 10 / val;
                }

                tar         = tar + dir;
                newTarget.X = tar.x;
                newTarget.Y = tar.y;
                newTarget.Z = tar.z;
            }

            ESRI.ArcGIS.GlobeCore.IGlobeViewUtil globeViewUtil = globeCamera as ESRI.ArcGIS.GlobeCore.IGlobeViewUtil;
            double obsLat;
            double obsLon;
            double obsAlt;
            double tarLat;
            double tarLon;
            double tarAlt;

            globeViewUtil.GeocentricToGeographic(currentObs.x, currentObs.y, currentObs.z, out obsLon, out obsLat, out obsAlt);
            globeViewUtil.GeocentricToGeographic(newTarget.X, newTarget.Y, newTarget.Z, out tarLon, out tarLat, out tarAlt);
            globeCamera.SetObserverLatLonAlt(obsLat, obsLon, obsAlt / 1000);
            globeCamera.SetTargetLatLonAlt(tarLat, tarLon, tarAlt / 1000);
            camera.RollAngle = 0;
            camera.PropertiesChanged();
            globeDisplay.RefreshViewers();

            //Windows API call to set cursor
            SetCursor(moveFlyCur.Handle.ToInt32());
        }
Ejemplo n.º 2
0
        public void Flight()
        {
            //speed in scene units
            double motionUnit = (0.000001 + Math.Abs(observer.Norm() - 1.0) / 200.0) * motion;
            //Get IMessageDispatcher interface
            IMessageDispatcher pMessageDispatcher;

            pMessageDispatcher = new MessageDispatcherClass();

            //Set the ESC key to be seen as a cancel action
            pMessageDispatcher.CancelOnClick    = false;
            pMessageDispatcher.CancelOnEscPress = true;
            bCancel = false;
            do
            {
                //Get the elapsed time
                long   currentClock      = theClock.TickCount;
                double lastFrameDuration = (double)(currentClock - lastClock) / 1000;
                lastClock = currentClock;

                if (lastFrameDuration < 0.01)
                {
                    lastFrameDuration = 0.01;
                }

                if (lastFrameDuration > 1)
                {
                    lastFrameDuration = 0.1;
                }

                System.Diagnostics.Debug.Print(lastFrameDuration.ToString());

                //Windows API call to get windows client coordinates
                Rectangle rect = new Rectangle();
                if (GetClientRect(globeDisplay.ActiveViewer.hWnd, ref rect) == 0)
                {
                    return;
                }

                //Get normal vectors
                double dXMouseNormal, dYMouseNormal;

                dXMouseNormal = 2 * ((double)mouseX / (double)(rect.Right - rect.Left)) - 1;
                dYMouseNormal = 2 * ((double)mouseY / (double)(rect.Bottom - rect.Top)) - 1;

                PointZ dir = this.RotateNormal(lastFrameDuration, dXMouseNormal, dYMouseNormal);

                PointZ visTarget = new PointZ(observer.x + distance * dir.x, observer.y + distance * dir.y, observer.z + distance * dir.z);
                target.x = visTarget.x;
                target.y = visTarget.y;
                target.z = visTarget.z;

                if (speed != 0)
                {
                    int speedFactor = (speed > 0) ? (1 << speed) : -(1 << (-speed));

                    //Move the camera in the viewing directions
                    observer.x = observer.x + (lastFrameDuration * (2 ^ speedFactor) * motionUnit * dir.x);
                    observer.y = observer.y + (lastFrameDuration * (2 ^ speedFactor) * motionUnit * dir.y);
                    observer.z = observer.z + (lastFrameDuration * (2 ^ speedFactor) * motionUnit * dir.z);
                    target.x   = target.x + (lastFrameDuration * (2 ^ speedFactor) * motionUnit * dir.x);
                    target.y   = target.y + (lastFrameDuration * (2 ^ speedFactor) * motionUnit * dir.y);
                    target.z   = target.z + (lastFrameDuration * (2 ^ speedFactor) * motionUnit * dir.z);
                }

                ESRI.ArcGIS.GlobeCore.IGlobeViewUtil globeViewUtil = globeCamera as ESRI.ArcGIS.GlobeCore.IGlobeViewUtil;
                double obsLat;
                double obsLon;
                double obsAlt;
                double tarLat;
                double tarLon;
                double tarAlt;

                globeViewUtil.GeocentricToGeographic(observer.x, observer.y, observer.z, out obsLon, out obsLat, out obsAlt);
                globeViewUtil.GeocentricToGeographic(target.x, target.y, target.z, out tarLon, out tarLat, out tarAlt);
                globeCamera.SetObserverLatLonAlt(obsLat, obsLon, obsAlt / 1000);
                globeCamera.SetTargetLatLonAlt(tarLat, tarLon, tarAlt / 1000);

                globeCamera.SetAccurateViewDirection(target.x - observer.x, target.y - observer.y, target.z - observer.z);

                double rollAngle = 0;
                if (speed > 0)
                {
                    rollAngle = 10 * dXMouseNormal * Math.Abs(dXMouseNormal);
                }
                camera.RollAngle = rollAngle;

                //Redraw the scene viewer
                globeDisplay.RefreshViewers();

                //Dispatch any waiting messages: OnMouseMove / OnMouseUp / OnKeyUp events
                object objCancel = bCancel as object;
                pMessageDispatcher.Dispatch(globeDisplay.ActiveViewer.hWnd, false, out objCancel);

                //End flight if ESC key pressed
                if (bCancel == true)
                {
                    EndFlight();
                }
            }while (inUse == true && bCancel == false);

            bCancel = false;
        }