123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- /*global define*/
- define([
- '../Core/BoundingRectangle',
- '../Core/Cartesian2',
- '../Core/Cartesian3',
- '../Core/Cartesian4',
- '../Core/Cartographic',
- '../Core/defined',
- '../Core/DeveloperError',
- '../Core/Math',
- '../Core/Matrix4',
- './SceneMode'
- ], function(
- BoundingRectangle,
- Cartesian2,
- Cartesian3,
- Cartesian4,
- Cartographic,
- defined,
- DeveloperError,
- CesiumMath,
- Matrix4,
- SceneMode) {
- "use strict";
- /**
- * Functions that do scene-dependent transforms between rendering-related coordinate systems.
- *
- * @namespace
- * @alias SceneTransforms
- */
- var SceneTransforms = {};
- var actualPositionScratch = new Cartesian4(0, 0, 0, 1);
- var positionCC = new Cartesian4();
- var viewProjectionScratch = new Matrix4();
- /**
- * Transforms a position in WGS84 coordinates to window coordinates. This is commonly used to place an
- * HTML element at the same screen position as an object in the scene.
- *
- * @param {Scene} scene The scene.
- * @param {Cartesian3} position The position in WGS84 (world) coordinates.
- * @param {Cartesian2} [result] An optional object to return the input position transformed to window coordinates.
- * @returns {Cartesian2} The modified result parameter or a new Cartesian3 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid.
- *
- * @example
- * // Output the window position of longitude/latitude (0, 0) every time the mouse moves.
- * var scene = widget.scene;
- * var ellipsoid = scene.globe.ellipsoid;
- * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0));
- * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
- * handler.setInputAction(function(movement) {
- * console.log(Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position));
- * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- */
- SceneTransforms.wgs84ToWindowCoordinates = function(scene, position, result) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(scene)) {
- throw new DeveloperError('scene is required.');
- }
- if (!defined(position)) {
- throw new DeveloperError('position is required.');
- }
- //>>includeEnd('debug');
- // Transform for 3D, 2D, or Columbus view
- var actualPosition = SceneTransforms.computeActualWgs84Position(scene.frameState, position, actualPositionScratch);
- if (!defined(actualPosition)) {
- return undefined;
- }
- // View-projection matrix to transform from world coordinates to clip coordinates
- var camera = scene.camera;
- var viewProjection = Matrix4.multiply(camera.frustum.projectionMatrix, camera.viewMatrix, viewProjectionScratch);
- Matrix4.multiplyByVector(viewProjection, Cartesian4.fromElements(actualPosition.x, actualPosition.y, actualPosition.z, 1, positionCC), positionCC);
- if ((positionCC.z < 0) && (scene.mode !== SceneMode.SCENE2D)) {
- return undefined;
- }
- result = SceneTransforms.clipToGLWindowCoordinates(scene, positionCC, result);
- result.y = scene.canvas.clientHeight - result.y;
- return result;
- };
- /**
- * Transforms a position in WGS84 coordinates to drawing buffer coordinates. This may produce different
- * results from SceneTransforms.wgs84ToWindowCoordinates when the browser zoom is not 100%, or on high-DPI displays.
- *
- * @param {Scene} scene The scene.
- * @param {Cartesian3} position The position in WGS84 (world) coordinates.
- * @param {Cartesian2} [result] An optional object to return the input position transformed to window coordinates.
- * @returns {Cartesian2} The modified result parameter or a new Cartesian3 instance if one was not provided. This may be <code>undefined</code> if the input position is near the center of the ellipsoid.
- *
- * @example
- * // Output the window position of longitude/latitude (0, 0) every time the mouse moves.
- * var scene = widget.scene;
- * var ellipsoid = scene.globe.ellipsoid;
- * var position = Cesium.Cartesian3.fromDegrees(0.0, 0.0));
- * var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
- * handler.setInputAction(function(movement) {
- * console.log(Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position));
- * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- */
- SceneTransforms.wgs84ToDrawingBufferCoordinates = function(scene, position, result) {
- //>>includeStart('debug', pragmas.debug);
- if (!defined(scene)) {
- throw new DeveloperError('scene is required.');
- }
- if (!defined(position)) {
- throw new DeveloperError('position is required.');
- }
- //>>includeEnd('debug');
- // Transform for 3D, 2D, or Columbus view
- var actualPosition = SceneTransforms.computeActualWgs84Position(scene.frameState, position, actualPositionScratch);
- if (!defined(actualPosition)) {
- return undefined;
- }
- // View-projection matrix to transform from world coordinates to clip coordinates
- var camera = scene.camera;
- var viewProjection = Matrix4.multiply(camera.frustum.projectionMatrix, camera.viewMatrix, viewProjectionScratch);
- Matrix4.multiplyByVector(viewProjection, Cartesian4.fromElements(actualPosition.x, actualPosition.y, actualPosition.z, 1, positionCC), positionCC);
- if ((positionCC.z < 0) && (scene.mode !== SceneMode.SCENE2D)) {
- return undefined;
- }
- return SceneTransforms.clipToDrawingBufferCoordinates(scene, positionCC, result);
- };
- var projectedPosition = new Cartesian3();
- var positionInCartographic = new Cartographic();
- /**
- * @private
- */
- SceneTransforms.computeActualWgs84Position = function(frameState, position, result) {
- var mode = frameState.mode;
- if (mode === SceneMode.SCENE3D) {
- return Cartesian3.clone(position, result);
- }
- var projection = frameState.mapProjection;
- var cartographic = projection.ellipsoid.cartesianToCartographic(position, positionInCartographic);
- if (!defined(cartographic)) {
- return undefined;
- }
- projection.project(cartographic, projectedPosition);
- if (mode === SceneMode.COLUMBUS_VIEW) {
- return Cartesian3.fromElements(projectedPosition.z, projectedPosition.x, projectedPosition.y, result);
- }
- if (mode === SceneMode.SCENE2D) {
- return Cartesian3.fromElements(0.0, projectedPosition.x, projectedPosition.y, result);
- }
- // mode === SceneMode.MORPHING
- var morphTime = frameState.morphTime;
- return Cartesian3.fromElements(
- CesiumMath.lerp(projectedPosition.z, position.x, morphTime),
- CesiumMath.lerp(projectedPosition.x, position.y, morphTime),
- CesiumMath.lerp(projectedPosition.y, position.z, morphTime),
- result);
- };
- var positionNDC = new Cartesian3();
- var positionWC = new Cartesian3();
- var viewport = new BoundingRectangle();
- var viewportTransform = new Matrix4();
- /**
- * @private
- */
- SceneTransforms.clipToGLWindowCoordinates = function(scene, position, result) {
- var canvas = scene.canvas;
- // Perspective divide to transform from clip coordinates to normalized device coordinates
- Cartesian3.divideByScalar(position, position.w, positionNDC);
- // Assuming viewport takes up the entire canvas...
- viewport.width = canvas.clientWidth;
- viewport.height = canvas.clientHeight;
- Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, viewportTransform);
- // Viewport transform to transform from clip coordinates to window coordinates
- Matrix4.multiplyByPoint(viewportTransform, positionNDC, positionWC);
- return Cartesian2.fromCartesian3(positionWC, result);
- };
- /**
- * @private
- */
- SceneTransforms.clipToDrawingBufferCoordinates = function(scene, position, result) {
- // Perspective divide to transform from clip coordinates to normalized device coordinates
- Cartesian3.divideByScalar(position, position.w, positionNDC);
- // Assuming viewport takes up the entire canvas...
- viewport.width = scene.drawingBufferWidth;
- viewport.height = scene.drawingBufferHeight;
- Matrix4.computeViewportTransformation(viewport, 0.0, 1.0, viewportTransform);
- // Viewport transform to transform from clip coordinates to drawing buffer coordinates
- Matrix4.multiplyByPoint(viewportTransform, positionNDC, positionWC);
- return Cartesian2.fromCartesian3(positionWC, result);
- };
- /**
- * @private
- */
- SceneTransforms.transformWindowToDrawingBuffer = function(scene, windowPosition, result) {
- var canvas = scene.canvas;
- var xScale = scene.drawingBufferWidth / canvas.clientWidth;
- var yScale = scene.drawingBufferHeight / canvas.clientHeight;
- return Cartesian2.fromElements(windowPosition.x * xScale, windowPosition.y * yScale, result);
- };
- return SceneTransforms;
- });
|