basicorbitviewmodel.java

来自「world wind java sdk 源码」· Java 代码 · 共 290 行

JAVA
290
字号
/*
Copyright (C) 2001, 2007 United States Government as represented by
the Administrator of the National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.view;

import gov.nasa.worldwind.geom.*;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.util.Logging;

/**
 * @author dcollins
 * @version $Id: BasicOrbitViewModel.java 9587 2009-03-20 20:58:58Z dcollins $
 */
public class BasicOrbitViewModel implements OrbitViewModel
{
    protected static class BasicModelCoordinates implements OrbitViewModel.ModelCoordinates
    {
        private final Position center;
        private final Angle heading;
        private final Angle pitch;
        private final double zoom;

        public BasicModelCoordinates(Position center, Angle heading, Angle pitch, double zoom)
        {
            if (center == null)
            {
                String message = Logging.getMessage("nullValue.CenterIsNull");
                Logging.logger().severe(message);
                throw new IllegalArgumentException(message);
            }
            if (heading == null)
            {
                String message = Logging.getMessage("nullValue.HeadingIsNull");
                Logging.logger().severe(message);
                throw new IllegalArgumentException(message);
            }
            if (pitch == null)
            {
                String message = Logging.getMessage("nullValue.PitchIsNull");
                Logging.logger().severe(message);
                throw new IllegalArgumentException(message);
            }

            this.center = center;
            this.heading = heading;
            this.pitch = pitch;
            this.zoom = zoom;
        }

        public Position getCenterPosition()
        {
            return this.center;
        }

        public Angle getHeading()
        {
            return this.heading;
        }

        public Angle getPitch()
        {
            return this.pitch;
        }

        public double getZoom()
        {
            return this.zoom;
        }
    }

    public BasicOrbitViewModel()
    {
    }

    public Matrix computeTransformMatrix(Globe globe, Position center, Angle heading, Angle pitch, double zoom)
    {
        if (globe == null)
        {
            String message = Logging.getMessage("nullValue.GlobeIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (center == null)
        {
            String message = Logging.getMessage("nullValue.CenterIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (heading == null)
        {
            String message = Logging.getMessage("nullValue.HeadingIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (pitch == null)
        {
            String message = Logging.getMessage("nullValue.PitchIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        // Construct the model-view transform matrix for the specified coordinates.
        // Because this is a model-view transform, matrices are applied in reverse order.
        Matrix transform;
        // Zoom, heading, pitch.
        transform = this.computeHeadingPitchZoomTransform(heading, pitch, zoom);
        // Center position.
        transform = transform.multiply(this.computeCenterTransform(globe, center));

        return transform;
    }

    public ModelCoordinates computeModelCoordinates(Globe globe, Vec4 eyePoint, Vec4 centerPoint, Vec4 up)
    {
        if (globe == null)
        {
            String message = Logging.getMessage("nullValue.GlobeIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (eyePoint == null)
        {
            String message = "nullValue.EyePointIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (centerPoint == null)
        {
            String message = "nullValue.CenterPointIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (up == null)
        {
            String message = "nullValue.UpIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        Matrix modelview = Matrix.fromViewLookAt(eyePoint, centerPoint, up);
        return this.computeModelCoordinates(globe, modelview, centerPoint);
    }

    public ModelCoordinates computeModelCoordinates(Globe globe, Matrix modelTransform, Vec4 centerPoint)
    {
        if (globe == null)
        {
            String message = Logging.getMessage("nullValue.GlobeIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (modelTransform == null)
        {
            String message = "nullValue.ModelTransformIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (centerPoint == null)
        {
            String message = "nullValue.CenterPointIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        // Compute the center position.
        Position centerPos = globe.computePositionFromPoint(centerPoint);
        // Compute the center position transform.
        Matrix centerTransform = this.computeCenterTransform(globe, centerPos);
        Matrix centerTransformInv = centerTransform.getInverse();
        if (centerTransformInv == null)
        {
            String message = Logging.getMessage("generic.NoninvertibleMatrix");
            Logging.logger().severe(message);
            throw new IllegalStateException(message);
        }

        // Compute the heading-pitch-zoom transform.
        Matrix hpzTransform = modelTransform.multiply(centerTransformInv);
        // Extract the heading, pitch, and zoom values from the transform.
        Angle heading = this.computeHeading(hpzTransform);
        Angle pitch = this.computePitch(hpzTransform);
        double zoom = this.computeZoom(hpzTransform);
        if (heading == null || pitch == null)
            return null;

        return new BasicModelCoordinates(centerPos, heading, pitch, zoom);
    }

    protected Matrix computeCenterTransform(Globe globe, Position center)
    {
        if (globe == null)
        {
            String message = Logging.getMessage("nullValue.GlobeIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (center == null)
        {
            String message = Logging.getMessage("nullValue.CenterIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        // The view eye position will be the same as the center position.
        // This is only the case without any zoom, heading, and pitch.
        Vec4 eyePoint = globe.computePointFromPosition(center);
        // The view forward direction will be colinear with the
        // geoid surface normal at the center position.
        Vec4 normal = globe.computeSurfaceNormalAtLocation(center.getLatitude(), center.getLongitude());
        Vec4 lookAtPoint = eyePoint.subtract3(normal);
        // The up direction will be pointing towards the north pole.
        Vec4 north = globe.computeNorthPointingTangentAtLocation(center.getLatitude(), center.getLongitude());
        // Creates a viewing matrix looking from eyePoint towards lookAtPoint,
        // with the given up direction. The forward, right, and up vectors
        // contained in the matrix are guaranteed to be orthogonal. This means
        // that the Matrix's up may not be equivalent to the specified up vector
        // here (though it will point in the same general direction).
        // In this case, the forward direction would not be affected.
        return Matrix.fromViewLookAt(eyePoint, lookAtPoint, north);
    }

    protected Matrix computeHeadingPitchZoomTransform(Angle heading, Angle pitch, double zoom)
    {
        if (heading == null)
        {
            String message = Logging.getMessage("nullValue.HeadingIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        if (pitch == null)
        {
            String message = Logging.getMessage("nullValue.PitchIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        Matrix transform;
        // Zoom.
        transform = Matrix.fromTranslation(0, 0, -zoom);
        // Pitch is treated clockwise as rotation about the X-axis. We flip the pitch value so that a positive
        // rotation produces a clockwise rotation (when facing the axis).
        transform = transform.multiply(Matrix.fromRotationX(pitch.multiply(-1.0)));
        // Heading.
        transform = transform.multiply(Matrix.fromRotationZ(heading));
        return transform;
    }

    protected Angle computeHeading(Matrix headingPitchZoomTransform)
    {
        if (headingPitchZoomTransform == null)
        {
            String message = "nullValue.HeadingPitchZoomTransformTransformIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        return headingPitchZoomTransform.getRotationZ();
    }

    protected Angle computePitch(Matrix headingPitchZoomTransform)
    {
        if (headingPitchZoomTransform == null)
        {
            String message = "nullValue.HeadingPitchZoomTransformTransformIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        Angle a = headingPitchZoomTransform.getRotationX();
        if (a != null)
            a = a.multiply(-1.0);
        return a;
    }

    protected double computeZoom(Matrix headingPitchZoomTransform)
    {
        if (headingPitchZoomTransform == null)
        {
            String message = "nullValue.HeadingPitchZoomTransformTransformIsNull";
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        Vec4 v = headingPitchZoomTransform.getTranslation();
        return v != null ? v.getLength3() : 0.0;
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?