UNPKG

cesium

Version:

CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.

1,390 lines (1,268 loc) 160 kB
define([ '../Core/BoundingRectangle', '../Core/BoundingSphere', '../Core/BoxGeometry', '../Core/Cartesian2', '../Core/Cartesian3', '../Core/Cartesian4', '../Core/Cartographic', '../Core/Color', '../Core/ColorGeometryInstanceAttribute', '../Core/createGuid', '../Core/CullingVolume', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', '../Core/deprecationWarning', '../Core/destroyObject', '../Core/DeveloperError', '../Core/EllipsoidGeometry', '../Core/Event', '../Core/GeographicProjection', '../Core/GeometryInstance', '../Core/GeometryPipeline', '../Core/getTimestamp', '../Core/Intersect', '../Core/Interval', '../Core/JulianDate', '../Core/Math', '../Core/Matrix4', '../Core/mergeSort', '../Core/Occluder', '../Core/OrthographicFrustum', '../Core/OrthographicOffCenterFrustum', '../Core/PerspectiveFrustum', '../Core/PerspectiveOffCenterFrustum', '../Core/PixelFormat', '../Core/RequestScheduler', '../Core/ShowGeometryInstanceAttribute', '../Core/TaskProcessor', '../Core/Transforms', '../Renderer/ClearCommand', '../Renderer/ComputeEngine', '../Renderer/Context', '../Renderer/ContextLimits', '../Renderer/DrawCommand', '../Renderer/Framebuffer', '../Renderer/Pass', '../Renderer/PassState', '../Renderer/PixelDatatype', '../Renderer/ShaderProgram', '../Renderer/ShaderSource', '../Renderer/Texture', './BrdfLutGenerator', './Camera', './CreditDisplay', './DebugCameraPrimitive', './DepthPlane', './DerivedCommand', './DeviceOrientationCameraController', './Fog', './FrameState', './FrustumCommands', './GlobeDepth', './InvertClassification', './JobScheduler', './MapMode2D', './OIT', './PerformanceDisplay', './PerInstanceColorAppearance', './PickDepth', './PostProcessStageCollection', './Primitive', './PrimitiveCollection', './SceneFramebuffer', './SceneMode', './SceneTransforms', './SceneTransitioner', './ScreenSpaceCameraController', './ShadowMap', './SunPostProcess', './TweenCollection' ], function( BoundingRectangle, BoundingSphere, BoxGeometry, Cartesian2, Cartesian3, Cartesian4, Cartographic, Color, ColorGeometryInstanceAttribute, createGuid, CullingVolume, defaultValue, defined, defineProperties, deprecationWarning, destroyObject, DeveloperError, EllipsoidGeometry, Event, GeographicProjection, GeometryInstance, GeometryPipeline, getTimestamp, Intersect, Interval, JulianDate, CesiumMath, Matrix4, mergeSort, Occluder, OrthographicFrustum, OrthographicOffCenterFrustum, PerspectiveFrustum, PerspectiveOffCenterFrustum, PixelFormat, RequestScheduler, ShowGeometryInstanceAttribute, TaskProcessor, Transforms, ClearCommand, ComputeEngine, Context, ContextLimits, DrawCommand, Framebuffer, Pass, PassState, PixelDatatype, ShaderProgram, ShaderSource, Texture, BrdfLutGenerator, Camera, CreditDisplay, DebugCameraPrimitive, DepthPlane, DerivedCommand, DeviceOrientationCameraController, Fog, FrameState, FrustumCommands, GlobeDepth, InvertClassification, JobScheduler, MapMode2D, OIT, PerformanceDisplay, PerInstanceColorAppearance, PickDepth, PostProcessStageCollection, Primitive, PrimitiveCollection, SceneFramebuffer, SceneMode, SceneTransforms, SceneTransitioner, ScreenSpaceCameraController, ShadowMap, SunPostProcess, TweenCollection) { 'use strict'; var requestRenderAfterFrame = function (scene) { return function () { scene.frameState.afterRender.push(function() { scene.requestRender(); }); }; }; /** * The container for all 3D graphical objects and state in a Cesium virtual scene. Generally, * a scene is not created directly; instead, it is implicitly created by {@link CesiumWidget}. * <p> * <em><code>contextOptions</code> parameter details:</em> * </p> * <p> * The default values are: * <code> * { * webgl : { * alpha : false, * depth : true, * stencil : false, * antialias : true, * premultipliedAlpha : true, * preserveDrawingBuffer : false, * failIfMajorPerformanceCaveat : false * }, * allowTextureFilterAnisotropic : true * } * </code> * </p> * <p> * The <code>webgl</code> property corresponds to the {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} * object used to create the WebGL context. * </p> * <p> * <code>webgl.alpha</code> defaults to false, which can improve performance compared to the standard WebGL default * of true. If an application needs to composite Cesium above other HTML elements using alpha-blending, set * <code>webgl.alpha</code> to true. * </p> * <p> * The other <code>webgl</code> properties match the WebGL defaults for {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes}. * </p> * <p> * <code>allowTextureFilterAnisotropic</code> defaults to true, which enables anisotropic texture filtering when the * WebGL extension is supported. Setting this to false will improve performance, but hurt visual quality, especially for horizon views. * </p> * * @alias Scene * @constructor * * @param {Object} [options] Object with the following properties: * @param {Canvas} options.canvas The HTML canvas element to create the scene for. * @param {Object} [options.contextOptions] Context and WebGL creation properties. See details above. * @param {Element} [options.creditContainer] The HTML element in which the credits will be displayed. * @param {Element} [options.creditViewport] The HTML element in which to display the credit popup. If not specified, the viewport will be a added as a sibling of the canvas. * @param {MapProjection} [options.mapProjection=new GeographicProjection()] The map projection to use in 2D and Columbus View modes. * @param {Boolean} [options.orderIndependentTranslucency=true] If true and the configuration supports it, use order independent translucency. * @param {Boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View. * @param {Number} [options.terrainExaggeration=1.0] A scalar used to exaggerate the terrain. Note that terrain exaggeration will not modify any other primitive as they are positioned relative to the ellipsoid. * @param {Boolean} [options.shadows=false] Determines if shadows are cast by the sun. * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. * @param {Boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. * @param {Number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}. * * @see CesiumWidget * @see {@link http://www.khronos.org/registry/webgl/specs/latest/#5.2|WebGLContextAttributes} * * @exception {DeveloperError} options and options.canvas are required. * * @example * // Create scene without anisotropic texture filtering * var scene = new Cesium.Scene({ * canvas : canvas, * contextOptions : { * allowTextureFilterAnisotropic : false * } * }); */ function Scene(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); var canvas = options.canvas; var contextOptions = options.contextOptions; var creditContainer = options.creditContainer; var creditViewport = options.creditViewport; //>>includeStart('debug', pragmas.debug); if (!defined(canvas)) { throw new DeveloperError('options and options.canvas are required.'); } //>>includeEnd('debug'); var hasCreditContainer = defined(creditContainer); var context = new Context(canvas, contextOptions); if (!hasCreditContainer) { creditContainer = document.createElement('div'); creditContainer.style.position = 'absolute'; creditContainer.style.bottom = '0'; creditContainer.style['text-shadow'] = '0 0 2px #000000'; creditContainer.style.color = '#ffffff'; creditContainer.style['font-size'] = '10px'; creditContainer.style['padding-right'] = '5px'; canvas.parentNode.appendChild(creditContainer); } if (!defined(creditViewport)) { creditViewport = canvas.parentNode; } this._id = createGuid(); this._jobScheduler = new JobScheduler(); this._frameState = new FrameState(context, new CreditDisplay(creditContainer, ' • ', creditViewport), this._jobScheduler); this._frameState.scene3DOnly = defaultValue(options.scene3DOnly, false); this._removeCreditContainer = !hasCreditContainer; this._creditContainer = creditContainer; var ps = new PassState(context); ps.viewport = new BoundingRectangle(); ps.viewport.x = 0; ps.viewport.y = 0; ps.viewport.width = context.drawingBufferWidth; ps.viewport.height = context.drawingBufferHeight; this._passState = ps; this._canvas = canvas; this._context = context; this._computeEngine = new ComputeEngine(context); this._globe = undefined; this._primitives = new PrimitiveCollection(); this._groundPrimitives = new PrimitiveCollection(); this._logDepthBuffer = context.fragmentDepth; this._logDepthBufferDirty = true; this._updateFrustums = false; this._tweens = new TweenCollection(); this._shaderFrameCount = 0; this._sunPostProcess = undefined; this._computeCommandList = []; this._frustumCommandsList = []; this._overlayCommandList = []; this._pickFramebuffer = undefined; this._useOIT = defaultValue(options.orderIndependentTranslucency, true); this._executeOITFunction = undefined; var globeDepth; if (context.depthTexture) { globeDepth = new GlobeDepth(); } var oit; if (this._useOIT && defined(globeDepth)) { oit = new OIT(context); } this._globeDepth = globeDepth; this._depthPlane = new DepthPlane(); this._oit = oit; this._sceneFramebuffer = new SceneFramebuffer(); this._clearColorCommand = new ClearCommand({ color : new Color(), stencil : 0, owner : this }); this._depthClearCommand = new ClearCommand({ depth : 1.0, owner : this }); this._stencilClearCommand = new ClearCommand({ stencil : 0 }); this._pickDepths = []; this._debugGlobeDepths = []; this._pickDepthPassState = undefined; this._pickDepthFramebuffer = undefined; this._pickDepthFramebufferWidth = undefined; this._pickDepthFramebufferHeight = undefined; this._depthOnlyRenderStateCache = {}; this._transitioner = new SceneTransitioner(this); this._preUpdate = new Event(); this._postUpdate = new Event(); this._renderError = new Event(); this._preRender = new Event(); this._postRender = new Event(); this._cameraStartFired = false; this._cameraMovedTime = undefined; this._pickPositionCache = {}; this._pickPositionCacheDirty = false; this._minimumDisableDepthTestDistance = 0.0; /** * Exceptions occurring in <code>render</code> are always caught in order to raise the * <code>renderError</code> event. If this property is true, the error is rethrown * after the event is raised. If this property is false, the <code>render</code> function * returns normally after raising the event. * * @type {Boolean} * @default false */ this.rethrowRenderErrors = false; /** * Determines whether or not to instantly complete the * scene transition animation on user input. * * @type {Boolean} * @default true */ this.completeMorphOnUserInput = true; /** * The event fired at the beginning of a scene transition. * @type {Event} * @default Event() */ this.morphStart = new Event(); /** * The event fired at the completion of a scene transition. * @type {Event} * @default Event() */ this.morphComplete = new Event(); /** * The {@link SkyBox} used to draw the stars. * * @type {SkyBox} * @default undefined * * @see Scene#backgroundColor */ this.skyBox = undefined; /** * The sky atmosphere drawn around the globe. * * @type {SkyAtmosphere} * @default undefined */ this.skyAtmosphere = undefined; /** * The {@link Sun}. * * @type {Sun} * @default undefined */ this.sun = undefined; /** * Uses a bloom filter on the sun when enabled. * * @type {Boolean} * @default true */ this.sunBloom = true; this._sunBloom = undefined; /** * The {@link Moon} * * @type Moon * @default undefined */ this.moon = undefined; /** * The background color, which is only visible if there is no sky box, i.e., {@link Scene#skyBox} is undefined. * * @type {Color} * @default {@link Color.BLACK} * * @see Scene#skyBox */ this.backgroundColor = Color.clone(Color.BLACK); this._mode = SceneMode.SCENE3D; this._mapProjection = defined(options.mapProjection) ? options.mapProjection : new GeographicProjection(); /** * The current morph transition time between 2D/Columbus View and 3D, * with 0.0 being 2D or Columbus View and 1.0 being 3D. * * @type {Number} * @default 1.0 */ this.morphTime = 1.0; /** * The far-to-near ratio of the multi-frustum when using a normal depth buffer. * <p> * This value is used to create the near and far values for each frustum of the multi-frustum. It is only used * when {@link Scene#logarithmicDepthBuffer} is <code>false</code>. When <code>logarithmicDepthBuffer</code> is * <code>true</code>, use {@link Scene#logarithmicDepthFarToNearRatio}. * </p> * * @type {Number} * @default 1000.0 */ this.farToNearRatio = 1000.0; /** * The far-to-near ratio of the multi-frustum when using a logarithmic depth buffer. * <p> * This value is used to create the near and far values for each frustum of the multi-frustum. It is only used * when {@link Scene#logarithmicDepthBuffer} is <code>true</code>. When <code>logarithmicDepthBuffer</code> is * <code>false</code>, use {@link Scene#farToNearRatio}. * </p> * * @type {Number} * @default 1e9 */ this.logarithmicDepthFarToNearRatio = 1e9; /** * Determines the uniform depth size in meters of each frustum of the multifrustum in 2D. If a primitive or model close * to the surface shows z-fighting, decreasing this will eliminate the artifact, but decrease performance. On the * other hand, increasing this will increase performance but may cause z-fighting among primitives close to the surface. * * @type {Number} * @default 1.75e6 */ this.nearToFarDistance2D = 1.75e6; /** * This property is for debugging only; it is not for production use. * <p> * A function that determines what commands are executed. As shown in the examples below, * the function receives the command's <code>owner</code> as an argument, and returns a boolean indicating if the * command should be executed. * </p> * <p> * The default is <code>undefined</code>, indicating that all commands are executed. * </p> * * @type Function * * @default undefined * * @example * // Do not execute any commands. * scene.debugCommandFilter = function(command) { * return false; * }; * * // Execute only the billboard's commands. That is, only draw the billboard. * var billboards = new Cesium.BillboardCollection(); * scene.debugCommandFilter = function(command) { * return command.owner === billboards; * }; */ this.debugCommandFilter = undefined; /** * This property is for debugging only; it is not for production use. * <p> * When <code>true</code>, commands are randomly shaded. This is useful * for performance analysis to see what parts of a scene or model are * command-dense and could benefit from batching. * </p> * * @type Boolean * * @default false */ this.debugShowCommands = false; /** * This property is for debugging only; it is not for production use. * <p> * When <code>true</code>, commands are shaded based on the frustums they * overlap. Commands in the closest frustum are tinted red, commands in * the next closest are green, and commands in the farthest frustum are * blue. If a command overlaps more than one frustum, the color components * are combined, e.g., a command overlapping the first two frustums is tinted * yellow. * </p> * * @type Boolean * * @default false */ this.debugShowFrustums = false; this._debugFrustumStatistics = undefined; /** * This property is for debugging only; it is not for production use. * <p> * Displays frames per second and time between frames. * </p> * * @type Boolean * * @default false */ this.debugShowFramesPerSecond = false; /** * This property is for debugging only; it is not for production use. * <p> * Displays depth information for the indicated frustum. * </p> * * @type Boolean * * @default false */ this.debugShowGlobeDepth = false; /** * This property is for debugging only; it is not for production use. * <p> * Indicates which frustum will have depth information displayed. * </p> * * @type Number * * @default 1 */ this.debugShowDepthFrustum = 1; /** * This property is for debugging only; it is not for production use. * <p> * When <code>true</code>, draws outlines to show the boundaries of the camera frustums * </p> * * @type Boolean * * @default false */ this.debugShowFrustumPlanes = false; this._debugShowFrustumPlanes = false; this._debugFrustumPlanes = undefined; /** * When <code>true</code>, enables picking using the depth buffer. * * @type Boolean * @default true */ this.useDepthPicking = true; /** * When <code>true</code>, enables picking translucent geometry using the depth buffer. Note that {@link Scene#useDepthPicking} must also be true for this enabling to work. * * <p> * Render must be called between picks. * <br>There is a decrease in performance when enabled. There are extra draw calls to write depth for * translucent geometry. * </p> * * @example * // picking the position of a translucent primitive * viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) { * var pickedFeature = viewer.scene.pick(movement.position); * if (!Cesium.defined(pickedFeature)) { * // nothing picked * return; * } * viewer.scene.render(); * var worldPosition = viewer.scene.pickPosition(movement.position)); * }, Cesium.ScreenSpaceEventType.LEFT_CLICK); * * @type {Boolean} * @default false */ this.pickTranslucentDepth = false; /** * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. * @type {Number} * @default 500.0 * @private */ this.cameraEventWaitTime = 500.0; /** * Blends the atmosphere to geometry far from the camera for horizon views. Allows for additional * performance improvements by rendering less geometry and dispatching less terrain requests. * @type {Fog} */ this.fog = new Fog(); this._sunCamera = new Camera(this); /** * The shadow map in the scene. When enabled, models, primitives, and the globe may cast and receive shadows. * By default the light source of the shadow map is the sun. * @type {ShadowMap} */ this.shadowMap = new ShadowMap({ context : context, lightCamera : this._sunCamera, enabled : defaultValue(options.shadows, false) }); /** * When <code>false</code>, 3D Tiles will render normally. When <code>true</code>, classified 3D Tile geometry will render normally and * unclassified 3D Tile geometry will render with the color multiplied by {@link Scene#invertClassificationColor}. * @type {Boolean} * @default false */ this.invertClassification = false; /** * The highlight color of unclassified 3D Tile geometry when {@link Scene#invertClassification} is <code>true</code>. * <p>When the color's alpha is less than 1.0, the unclassified portions of the 3D Tiles will not blend correctly with the classified positions of the 3D Tiles.</p> * <p>Also, when the color's alpha is less than 1.0, the WEBGL_depth_texture and EXT_frag_depth WebGL extensions must be supported.</p> * @type {Color} * @default Color.WHITE */ this.invertClassificationColor = Color.clone(Color.WHITE); this._actualInvertClassificationColor = Color.clone(this._invertClassificationColor); this._invertClassification = new InvertClassification(); /** * The focal length for use when with cardboard or WebVR. * @type {Number} */ this.focalLength = undefined; /** * The eye separation distance in meters for use with cardboard or WebVR. * @type {Number} */ this.eyeSeparation = undefined; /** * Post processing effects applied to the final render. * @type {PostProcessStageCollection} */ this.postProcessStages = new PostProcessStageCollection(); this._brdfLutGenerator = new BrdfLutGenerator(); this._terrainExaggeration = defaultValue(options.terrainExaggeration, 1.0); this._performanceDisplay = undefined; this._debugVolume = undefined; var camera = new Camera(this); this._camera = camera; this._screenSpaceCameraController = new ScreenSpaceCameraController(this); this._mapMode2D = defaultValue(options.mapMode2D, MapMode2D.INFINITE_SCROLL); if (this._logDepthBuffer) { this._camera.frustum.near = 0.1; this._camera.frustum.far = 10000000000.0; } this._cameraClone = Camera.clone(camera); this._frustumChanged = true; // Keeps track of the state of a frame. FrameState is the state across // the primitives of the scene. This state is for internally keeping track // of celestial and environment effects that need to be updated/rendered in // a certain order as well as updating/tracking framebuffer usage. this._environmentState = { skyBoxCommand : undefined, skyAtmosphereCommand : undefined, sunDrawCommand : undefined, sunComputeCommand : undefined, moonCommand : undefined, isSunVisible : false, isMoonVisible : false, isReadyForAtmosphere : false, isSkyAtmosphereVisible : false, clearGlobeDepth : false, useDepthPlane : false, originalFramebuffer : undefined, useGlobeDepthFramebuffer : false, useOIT : false, useInvertClassification : false, usePostProcess : false }; this._useWebVR = false; this._cameraVR = undefined; this._aspectRatioVR = undefined; /** * When <code>true</code>, rendering a frame will only occur when needed as determined by changes within the scene. * Enabling improves performance of the application, but requires using {@link Scene#requestRender} * to render a new frame explicitly in this mode. This will be necessary in many cases after making changes * to the scene in other parts of the API. * * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} * @see Scene#maximumRenderTimeChange * @see Scene#requestRender * * @type {Boolean} * @default false */ this.requestRenderMode = defaultValue(options.requestRenderMode, false); this._renderRequested = true; /** * If {@link Scene#requestRenderMode} is <code>true</code>, this value defines the maximum change in * simulation time allowed before a render is requested. Lower values increase the number of frames rendered * and higher values decrease the number of frames rendered. If <code>undefined</code>, changes to * the simulation time will never request a render. * This value impacts the rate of rendering for changes in the scene like lighting, entity property updates, * and animations. * * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} * @see Scene#requestRenderMode * * @type {Number} * @default 0.5 */ this.maximumRenderTimeChange = defaultValue(options.maximumRenderTimeChange, 0.0); this._lastRenderTime = undefined; this._removeRequestListenerCallback = RequestScheduler.requestCompletedEvent.addEventListener(requestRenderAfterFrame(this)); this._removeTaskProcessorListenerCallback = TaskProcessor.taskCompletedEvent.addEventListener(requestRenderAfterFrame(this)); this._removeGlobeCallbacks = []; // initial guess at frustums. var near = camera.frustum.near; var far = camera.frustum.far; var farToNearRatio = this._logDepthBuffer ? this.logarithmicDepthFarToNearRatio : this.farToNearRatio; var numFrustums = Math.ceil(Math.log(far / near) / Math.log(farToNearRatio)); updateFrustums(near, far, farToNearRatio, numFrustums, this._logDepthBuffer, this._frustumCommandsList, false, undefined); // give frameState, camera, and screen space camera controller initial state before rendering updateFrameState(this, 0.0, JulianDate.now()); this.initializeFrame(); } function updateGlobeListeners(scene, globe) { for (var i = 0; i < scene._removeGlobeCallbacks.length; ++i) { scene._removeGlobeCallbacks[i](); } scene._removeGlobeCallbacks.length = 0; var removeGlobeCallbacks = []; if (defined(globe)) { removeGlobeCallbacks.push(globe.imageryLayersUpdatedEvent.addEventListener(requestRenderAfterFrame(scene))); removeGlobeCallbacks.push(globe.terrainProviderChanged.addEventListener(requestRenderAfterFrame(scene))); } scene._removeGlobeCallbacks = removeGlobeCallbacks; } defineProperties(Scene.prototype, { /** * Gets the canvas element to which this scene is bound. * @memberof Scene.prototype * * @type {Canvas} * @readonly */ canvas : { get : function() { return this._canvas; } }, /** * The drawingBufferWidth of the underlying GL context. * @memberof Scene.prototype * * @type {Number} * @readonly * * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferWidth|drawingBufferWidth} */ drawingBufferHeight : { get : function() { return this._context.drawingBufferHeight; } }, /** * The drawingBufferHeight of the underlying GL context. * @memberof Scene.prototype * * @type {Number} * @readonly * * @see {@link https://www.khronos.org/registry/webgl/specs/1.0/#DOM-WebGLRenderingContext-drawingBufferHeight|drawingBufferHeight} */ drawingBufferWidth : { get : function() { return this._context.drawingBufferWidth; } }, /** * The maximum aliased line width, in pixels, supported by this WebGL implementation. It will be at least one. * @memberof Scene.prototype * * @type {Number} * @readonly * * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>ALIASED_LINE_WIDTH_RANGE</code>. */ maximumAliasedLineWidth : { get : function() { return ContextLimits.maximumAliasedLineWidth; } }, /** * The maximum length in pixels of one edge of a cube map, supported by this WebGL implementation. It will be at least 16. * @memberof Scene.prototype * * @type {Number} * @readonly * * @see {@link https://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml|glGet} with <code>GL_MAX_CUBE_MAP_TEXTURE_SIZE</code>. */ maximumCubeMapSize : { get : function() { return ContextLimits.maximumCubeMapSize; } }, /** * Returns true if the pickPosition function is supported. * @memberof Scene.prototype * * @type {Boolean} * @readonly */ pickPositionSupported : { get : function() { return this._context.depthTexture; } }, /** * Gets or sets the depth-test ellipsoid. * @memberof Scene.prototype * * @type {Globe} */ globe : { get: function() { return this._globe; }, set: function(globe) { this._globe = this._globe && this._globe.destroy(); this._globe = globe; updateGlobeListeners(this, globe); } }, /** * Gets the collection of primitives. * @memberof Scene.prototype * * @type {PrimitiveCollection} * @readonly */ primitives : { get : function() { return this._primitives; } }, /** * Gets the collection of ground primitives. * @memberof Scene.prototype * * @type {PrimitiveCollection} * @readonly */ groundPrimitives : { get : function() { return this._groundPrimitives; } }, /** * Gets the camera. * @memberof Scene.prototype * * @type {Camera} * @readonly */ camera : { get : function() { return this._camera; } }, // TODO: setCamera /** * Gets the controller for camera input handling. * @memberof Scene.prototype * * @type {ScreenSpaceCameraController} * @readonly */ screenSpaceCameraController : { get : function() { return this._screenSpaceCameraController; } }, /** * Get the map projection to use in 2D and Columbus View modes. * @memberof Scene.prototype * * @type {MapProjection} * @readonly * * @default new GeographicProjection() */ mapProjection : { get: function() { return this._mapProjection; } }, /** * Gets state information about the current scene. If called outside of a primitive's <code>update</code> * function, the previous frame's state is returned. * @memberof Scene.prototype * * @type {FrameState} * @readonly * * @private */ frameState : { get: function() { return this._frameState; } }, /** * Gets the collection of tweens taking place in the scene. * @memberof Scene.prototype * * @type {TweenCollection} * @readonly * * @private */ tweens : { get : function() { return this._tweens; } }, /** * Gets the collection of image layers that will be rendered on the globe. * @memberof Scene.prototype * * @type {ImageryLayerCollection} * @readonly */ imageryLayers : { get : function() { if (!defined(this.globe)) { return undefined; } return this.globe.imageryLayers; } }, /** * The terrain provider providing surface geometry for the globe. * @memberof Scene.prototype * * @type {TerrainProvider} */ terrainProvider : { get : function() { if (!defined(this.globe)) { return undefined; } return this.globe.terrainProvider; }, set : function(terrainProvider) { if (defined(this.globe)) { this.globe.terrainProvider = terrainProvider; } } }, /** * Gets an event that's raised when the terrain provider is changed * @memberof Scene.prototype * * @type {Event} * @readonly */ terrainProviderChanged : { get : function() { if (!defined(this.globe)) { return undefined; } return this.globe.terrainProviderChanged; } }, /** * Gets the event that will be raised before the scene is updated or rendered. Subscribers to the event * receive the Scene instance as the first parameter and the current time as the second parameter. * @memberof Scene.prototype * * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} * @see Scene#postUpdate * @see Scene#preRender * @see Scene#postRender * * @type {Event} * @readonly */ preUpdate : { get : function() { return this._preUpdate; } }, /** * Gets the event that will be raised immediately after the scene is updated and before the scene is rendered. * Subscribers to the event receive the Scene instance as the first parameter and the current time as the second * parameter. * @memberof Scene.prototype * * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} * @see Scene#preUpdate * @see Scene#preRender * @see Scene#postRender * * @type {Event} * @readonly */ postUpdate : { get : function() { return this._postUpdate; } }, /** * Gets the event that will be raised when an error is thrown inside the <code>render</code> function. * The Scene instance and the thrown error are the only two parameters passed to the event handler. * By default, errors are not rethrown after this event is raised, but that can be changed by setting * the <code>rethrowRenderErrors</code> property. * @memberof Scene.prototype * * @type {Event} * @readonly */ renderError : { get : function() { return this._renderError; } }, /** * Gets the event that will be raised after the scene is updated and immediately before the scene is rendered. * Subscribers to the event receive the Scene instance as the first parameter and the current time as the second * parameter. * @memberof Scene.prototype * * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} * @see Scene#preUpdate * @see Scene#postUpdate * @see Scene#postRender * * @type {Event} * @readonly */ preRender : { get : function() { return this._preRender; } }, /** * Gets the event that will be raised immediately after the scene is rendered. Subscribers to the event * receive the Scene instance as the first parameter and the current time as the second parameter. * @memberof Scene.prototype * * @see {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering} * @see Scene#preUpdate * @see Scene#postUpdate * @see Scene#postRender * * @type {Event} * @readonly */ postRender : { get : function() { return this._postRender; } }, /** * Gets the simulation time when the scene was last rendered. Returns undefined if the scene has not yet been * rendered. * @memberof Scene.prototype * * @type {JulianDate} * @readonly */ lastRenderTime : { get : function() { return this._lastRenderTime; } }, /** * @memberof Scene.prototype * @private * @readonly */ context : { get : function() { return this._context; } }, /** * This property is for debugging only; it is not for production use. * <p> * When {@link Scene.debugShowFrustums} is <code>true</code>, this contains * properties with statistics about the number of command execute per frustum. * <code>totalCommands</code> is the total number of commands executed, ignoring * overlap. <code>commandsInFrustums</code> is an array with the number of times * commands are executed redundantly, e.g., how many commands overlap two or * three frustums. * </p> * * @memberof Scene.prototype * * @type {Object} * @readonly * * @default undefined */ debugFrustumStatistics : { get : function() { return this._debugFrustumStatistics; } }, /** * Gets whether or not the scene is optimized for 3D only viewing. * @memberof Scene.prototype * @type {Boolean} * @readonly */ scene3DOnly : { get : function() { return this._frameState.scene3DOnly; } }, /** * Gets whether or not the scene has order independent translucency enabled. * Note that this only reflects the original construction option, and there are * other factors that could prevent OIT from functioning on a given system configuration. * @memberof Scene.prototype * @type {Boolean} * @readonly */ orderIndependentTranslucency : { get : function() { return defined(this._oit); } }, /** * Gets the unique identifier for this scene. * @memberof Scene.prototype * @type {String} * @readonly */ id : { get : function() { return this._id; } }, /** * Gets or sets the current mode of the scene. * @memberof Scene.prototype * @type {SceneMode} * @default {@link SceneMode.SCENE3D} */ mode : { get : function() { return this._mode; }, set : function(value) { //>>includeStart('debug', pragmas.debug); if (this.scene3DOnly && value !== SceneMode.SCENE3D) { throw new DeveloperError('Only SceneMode.SCENE3D is valid when scene3DOnly is true.'); } //>>includeEnd('debug'); if (value === SceneMode.SCENE2D) { this.morphTo2D(0); } else if (value === SceneMode.SCENE3D) { this.morphTo3D(0); } else if (value === SceneMode.COLUMBUS_VIEW) { this.morphToColumbusView(0); //>>includeStart('debug', pragmas.debug); } else { throw new DeveloperError('value must be a valid SceneMode enumeration.'); //>>includeEnd('debug'); } this._mode = value; } }, /** * Gets the number of frustums used in the last frame. * @memberof Scene.prototype * @type {Number} * * @private */ numberOfFrustums : { get : function() { return this._frustumCommandsList.length; } }, /** * Gets the scalar used to exaggerate the terrain. * @memberof Scene.prototype * @type {Number} */ terrainExaggeration : { get : function() { return this._terrainExaggeration; } }, /** * When <code>true</code>, splits the scene into two viewports with steroscopic views for the left and right eyes. * Used for cardboard and WebVR. * @memberof Scene.prototype * @type {Boolean} * @default false */ useWebVR : { get : function() { return this._useWebVR; }, set : function(value) { //>>includeStart('debug', pragmas.debug); if (this.camera.frustum instanceof OrthographicFrustum) { throw new DeveloperError('VR is unsupported with an orthographic projection.'); } //>>includeEnd('debug'); this._useWebVR = value; if (this._useWebVR) { this._frameState.creditDisplay.container.style.visibility = 'hidden'; this._cameraVR = new Camera(this); if (!defined(this._deviceOrientationCameraController)) { this._deviceOrientationCameraController = new DeviceOrientationCameraController(this); } this._aspectRatioVR = this._camera.frustum.aspectRatio; } else { this._frameState.creditDisplay.container.style.visibility = 'visible'; this._cameraVR = undefined; this._deviceOrientationCameraController = this._deviceOrientationCameraController && !this._deviceOrientationCameraController.isDestroyed() && this._deviceOrientationCameraController.destroy(); this._camera.frustum.aspectRatio = this._aspectRatioVR; this._camera.frustum.xOffset = 0.0; } } }, /** * Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction. * @memberof Scene.prototype * @type {Boolean} */ mapMode2D : { get : function() { return this._mapMode2D; } }, /** * Gets or sets the position of the Imagery splitter within the viewport. Valid values are between 0.0 and 1.0. * @memberof Scene.prototype * * @type {Number} */ imagerySplitPosition : { get: function() { return this._frameState.imagerySplitPosition; }, set: function(value) { this._frameState.imagerySplitPosition = value; } }, /** * The distance from the camera at which to disable the depth test of billboards, labels and points * to, for example, prevent clipping against