cesium/packages/engine/Source/Scene/PointPrimitiveCollection.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1224 lines
38 KiB
JavaScript
Raw Permalink Normal View History

Migrate Cesium to ES6 Modules See https://github.com/AnalyticalGraphicsInc/cesium/pull/8224 for details. eslint There are a handful of new .eslintrc.json files, mostly to identify the files that are still AMD modules (Sandcastle/Workers). These are needed because you can't change the parser type with a comment directive (since the parser is the thing reading the file). We can finally detect unusued modules! So those have all been cleaned up as well. requirejs -> rollup & clean-css requirejs, almond, and karma-requirejs have all been removed. We now use rollup for building and minifying (via uglify) JS code and clean-css for css. These changes are fairly straight-forward and just involve calling rollup instead of requirejs in the build process. Overall build time is significantly faster. CI is ~11 minutes compared to ~17 in master. Running makeZipFile on my machine takes 69 seconds compared to 112 seconds in master. There's probably plenty of room for additional optimization here too. We wrote an published a small npm module, rollup-plugin-strip-pragma, for stripping the requirejs pragmas we use out of the release builds. This is maintained in the Tools/rollup-plugin-strip-pragma directory. As for what we produce. The built version of Cesium is now a UMD module. So it should work anywhere that hasn't made the jump to ES6 yet. For users that were already using the "legacy" combined/minified approach, nothing changes. One awesome thing about roll-up is that it compiles all of the workers at once and automatically detects shared codes and generates separate bundles under the hood. This means the size of our worker modules shrink dramatically and Cesium itself will load them much faster. The total minified/gzipped size of all workers in master is 2.6 MB compared to 225 KB in this branch! This should be most noticeable on demos like Geometry & Appearances which load lots of workers for the various geometry typs. roll-up is also used to build Cesium Viewer, which is now an ES6 app. We use clean-css via gulp and it is also a straightforward change from requirejs that requires no special mention. Workers While the spec allows for ES6 Web Workers, no browser actually supports them yet. That means we needed a way to get our workers into non-ES6 form. Thankfully, roll-up can generate AMD modules, which means we now have a build step to compile our Worker source code back into AMD and use the existing TaskProcessor to load and execute them. This build step is part of the standard build task and is called createWorkers. During development, these "built" workers are un-optimized so you can still debug them and read the code. Since there is a build step, that means if you are changing code that affects a worker, you need to re-run build, or you can use the build-watch task to do it automatically. The ES6 versions of Worker code has moved into Source/WorkersES6 and we build the workers into their "old home" of Source/Workers. cesiumWorkerBootstrapper and transferTypedArrayTest which were already non-AMD ES5 scripts remain living in the Workers directory. Surprisingly little was changed about TaskProcessor or the worker system in general, especially considering that I thought this would be one of the major hurdles. ThirdParty A lot of our ThirdParty either already had a hand-written wrapper for AMD (which I updated to ES6) or had UMD which created problems when importing the same code in both Node and the browser. I basically had to update the wrapper of every third-party library to fix these problems. In some cases I updated the library version itself (Autolinker, topojson). Nothing to be too concerned about, but future clean-up would be using npm versions of these libraries and auto-generating the wrappers as needed so we don't hand-edit things. Sandcastle Sandcastle is eternal and manages to live another day in it's ancient requirejs/dojo 1.x form. Sandcastle now automatically uses the ES6 version of Cesium if it is available and fallsback to the ES5 unminified version if it is now. The built version of Sandcastle always uses CesiumUnminified, just like master. This means Sandcastle still works in IE11 if you run the combine step first (or use the relase zip) Removed Cesium usage from Sandcastle proper, since it wasn't really needed Generate a VERSION propertyin the gallery index since Cesium is no longer being included. Remove requirejs from Sandcastle bucket Update bucket to use the built version of Cesium if it is available by fallbackto the ES6 version during development. Standalone.html was also updated There's a bit of room for further clean-up here, but I think this gets us into master. I did not rename bucket-requirejs.html because I'm pretty sure it would break previously shared demos. We can put in some backwards compatible code later on if we want. (But I'd rather just see a full Sandcastle rewrite). Specs Specs are now all ES6, except for TestWorkers, which remain standard JS worker modules. This means you can no longer run the unbuilt unit tests in IE11. No changes for Chrome and Firefox. Since the specs use ES6 modules and built Cesium is an ES5 UMD, I added a build-specs build step which generates a combined ES5 version of the specs which rely on Cesium as a global variable. We then inject these files into jasmine instead of the standard specs and everything works exactly as it did before. SpecRunner.html has been updated to inject the correct version of the script depending on the build/release query parameters. The Specs must always use Cesium by importing Source/Cesium.js, this is so we can replace it with the built Cesium as describe above. There's a bunch of room for clean-up here, such as unifying our two copies of jasmine into a single helper file, but I didn't want to start doing that clean-up as part of this already overly big PR. The important thing is that we can still test the built version and still test on IE/Edge as needed. I also found and fixed two bugs that were causing failing unit tests, one in BingMapsImageryProviderSpec.js (which was overwriting createImage andnot setting it back) and ShadowVolumeAppearance.js (which had a module level caching bug). I think these may have been the cause of random CI failures in master as well, but only time will tell. For coverage, we had to switch to karma-coverage-istanbul-instrumenter for native ES6 support, but that's it. Finally, I updated appveryor to build Cesium and run the built tests under IE. We still don't fail the build for IE, but we should probably fix that if we want to keep it going. NodeJS When NODE_ENV is production, we now require in the minified CesiumJS directly, which works great because it's now a UMD module. Otherwise, we use the excellant esmpackage to load individual modules, it was a fairly straightforward swap from our old requirejs usage. We could probably drop esm too if we don't care about debugging or if we provie source maps at some point.
2019-10-03 23:51:23 +08:00
import BoundingSphere from "../Core/BoundingSphere.js";
import Color from "../Core/Color.js";
import ComponentDatatype from "../Core/ComponentDatatype.js";
import Frozen from "../Core/Frozen.js";
Migrate Cesium to ES6 Modules See https://github.com/AnalyticalGraphicsInc/cesium/pull/8224 for details. eslint There are a handful of new .eslintrc.json files, mostly to identify the files that are still AMD modules (Sandcastle/Workers). These are needed because you can't change the parser type with a comment directive (since the parser is the thing reading the file). We can finally detect unusued modules! So those have all been cleaned up as well. requirejs -> rollup & clean-css requirejs, almond, and karma-requirejs have all been removed. We now use rollup for building and minifying (via uglify) JS code and clean-css for css. These changes are fairly straight-forward and just involve calling rollup instead of requirejs in the build process. Overall build time is significantly faster. CI is ~11 minutes compared to ~17 in master. Running makeZipFile on my machine takes 69 seconds compared to 112 seconds in master. There's probably plenty of room for additional optimization here too. We wrote an published a small npm module, rollup-plugin-strip-pragma, for stripping the requirejs pragmas we use out of the release builds. This is maintained in the Tools/rollup-plugin-strip-pragma directory. As for what we produce. The built version of Cesium is now a UMD module. So it should work anywhere that hasn't made the jump to ES6 yet. For users that were already using the "legacy" combined/minified approach, nothing changes. One awesome thing about roll-up is that it compiles all of the workers at once and automatically detects shared codes and generates separate bundles under the hood. This means the size of our worker modules shrink dramatically and Cesium itself will load them much faster. The total minified/gzipped size of all workers in master is 2.6 MB compared to 225 KB in this branch! This should be most noticeable on demos like Geometry & Appearances which load lots of workers for the various geometry typs. roll-up is also used to build Cesium Viewer, which is now an ES6 app. We use clean-css via gulp and it is also a straightforward change from requirejs that requires no special mention. Workers While the spec allows for ES6 Web Workers, no browser actually supports them yet. That means we needed a way to get our workers into non-ES6 form. Thankfully, roll-up can generate AMD modules, which means we now have a build step to compile our Worker source code back into AMD and use the existing TaskProcessor to load and execute them. This build step is part of the standard build task and is called createWorkers. During development, these "built" workers are un-optimized so you can still debug them and read the code. Since there is a build step, that means if you are changing code that affects a worker, you need to re-run build, or you can use the build-watch task to do it automatically. The ES6 versions of Worker code has moved into Source/WorkersES6 and we build the workers into their "old home" of Source/Workers. cesiumWorkerBootstrapper and transferTypedArrayTest which were already non-AMD ES5 scripts remain living in the Workers directory. Surprisingly little was changed about TaskProcessor or the worker system in general, especially considering that I thought this would be one of the major hurdles. ThirdParty A lot of our ThirdParty either already had a hand-written wrapper for AMD (which I updated to ES6) or had UMD which created problems when importing the same code in both Node and the browser. I basically had to update the wrapper of every third-party library to fix these problems. In some cases I updated the library version itself (Autolinker, topojson). Nothing to be too concerned about, but future clean-up would be using npm versions of these libraries and auto-generating the wrappers as needed so we don't hand-edit things. Sandcastle Sandcastle is eternal and manages to live another day in it's ancient requirejs/dojo 1.x form. Sandcastle now automatically uses the ES6 version of Cesium if it is available and fallsback to the ES5 unminified version if it is now. The built version of Sandcastle always uses CesiumUnminified, just like master. This means Sandcastle still works in IE11 if you run the combine step first (or use the relase zip) Removed Cesium usage from Sandcastle proper, since it wasn't really needed Generate a VERSION propertyin the gallery index since Cesium is no longer being included. Remove requirejs from Sandcastle bucket Update bucket to use the built version of Cesium if it is available by fallbackto the ES6 version during development. Standalone.html was also updated There's a bit of room for further clean-up here, but I think this gets us into master. I did not rename bucket-requirejs.html because I'm pretty sure it would break previously shared demos. We can put in some backwards compatible code later on if we want. (But I'd rather just see a full Sandcastle rewrite). Specs Specs are now all ES6, except for TestWorkers, which remain standard JS worker modules. This means you can no longer run the unbuilt unit tests in IE11. No changes for Chrome and Firefox. Since the specs use ES6 modules and built Cesium is an ES5 UMD, I added a build-specs build step which generates a combined ES5 version of the specs which rely on Cesium as a global variable. We then inject these files into jasmine instead of the standard specs and everything works exactly as it did before. SpecRunner.html has been updated to inject the correct version of the script depending on the build/release query parameters. The Specs must always use Cesium by importing Source/Cesium.js, this is so we can replace it with the built Cesium as describe above. There's a bunch of room for clean-up here, such as unifying our two copies of jasmine into a single helper file, but I didn't want to start doing that clean-up as part of this already overly big PR. The important thing is that we can still test the built version and still test on IE/Edge as needed. I also found and fixed two bugs that were causing failing unit tests, one in BingMapsImageryProviderSpec.js (which was overwriting createImage andnot setting it back) and ShadowVolumeAppearance.js (which had a module level caching bug). I think these may have been the cause of random CI failures in master as well, but only time will tell. For coverage, we had to switch to karma-coverage-istanbul-instrumenter for native ES6 support, but that's it. Finally, I updated appveryor to build Cesium and run the built tests under IE. We still don't fail the build for IE, but we should probably fix that if we want to keep it going. NodeJS When NODE_ENV is production, we now require in the minified CesiumJS directly, which works great because it's now a UMD module. Otherwise, we use the excellant esmpackage to load individual modules, it was a fairly straightforward swap from our old requirejs usage. We could probably drop esm too if we don't care about debugging or if we provie source maps at some point.
2019-10-03 23:51:23 +08:00
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
import DeveloperError from "../Core/DeveloperError.js";
import EncodedCartesian3 from "../Core/EncodedCartesian3.js";
import CesiumMath from "../Core/Math.js";
import Matrix4 from "../Core/Matrix4.js";
import PrimitiveType from "../Core/PrimitiveType.js";
import WebGLConstants from "../Core/WebGLConstants.js";
import BufferUsage from "../Renderer/BufferUsage.js";
import ContextLimits from "../Renderer/ContextLimits.js";
import DrawCommand from "../Renderer/DrawCommand.js";
import Pass from "../Renderer/Pass.js";
import RenderState from "../Renderer/RenderState.js";
import ShaderProgram from "../Renderer/ShaderProgram.js";
import ShaderSource from "../Renderer/ShaderSource.js";
import VertexArrayFacade from "../Renderer/VertexArrayFacade.js";
import PointPrimitiveCollectionFS from "../Shaders/PointPrimitiveCollectionFS.js";
import PointPrimitiveCollectionVS from "../Shaders/PointPrimitiveCollectionVS.js";
import BlendingState from "./BlendingState.js";
import BlendOption from "./BlendOption.js";
import PointPrimitive from "./PointPrimitive.js";
import SceneMode from "./SceneMode.js";
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const SHOW_INDEX = PointPrimitive.SHOW_INDEX;
const POSITION_INDEX = PointPrimitive.POSITION_INDEX;
const COLOR_INDEX = PointPrimitive.COLOR_INDEX;
const OUTLINE_COLOR_INDEX = PointPrimitive.OUTLINE_COLOR_INDEX;
const OUTLINE_WIDTH_INDEX = PointPrimitive.OUTLINE_WIDTH_INDEX;
const PIXEL_SIZE_INDEX = PointPrimitive.PIXEL_SIZE_INDEX;
2015-04-08 05:36:08 +08:00
const SCALE_BY_DISTANCE_INDEX = PointPrimitive.SCALE_BY_DISTANCE_INDEX;
const TRANSLUCENCY_BY_DISTANCE_INDEX =
PointPrimitive.TRANSLUCENCY_BY_DISTANCE_INDEX;
const DISTANCE_DISPLAY_CONDITION_INDEX =
PointPrimitive.DISTANCE_DISPLAY_CONDITION_INDEX;
const DISABLE_DEPTH_DISTANCE_INDEX =
PointPrimitive.DISABLE_DEPTH_DISTANCE_INDEX;
const SPLIT_DIRECTION_INDEX = PointPrimitive.SPLIT_DIRECTION_INDEX;
2015-04-08 05:36:08 +08:00
const NUMBER_OF_PROPERTIES = PointPrimitive.NUMBER_OF_PROPERTIES;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const attributeLocations = {
positionHighAndSize: 0,
positionLowAndOutline: 1,
2015-04-08 05:36:08 +08:00
compressedAttribute0: 2, // color, outlineColor, pick color
compressedAttribute1: 3, // show, translucency by distance, some free space
scaleByDistance: 4,
distanceDisplayConditionAndDisableDepthAndSplitDirection: 5,
2015-04-08 05:36:08 +08:00
};
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
/**
* A renderable collection of points.
2015-04-08 05:36:08 +08:00
* <br /><br />
* Points are added and removed from the collection using {@link PointPrimitiveCollection#add}
* and {@link PointPrimitiveCollection#remove}.
2015-04-08 05:36:08 +08:00
*
* @alias PointPrimitiveCollection
* @constructor
*
* @param {object} [options] Object with the following properties:
* @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms each point from model to world coordinates.
* @param {boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown.
* @param {BlendOption} [options.blendOption=BlendOption.OPAQUE_AND_TRANSLUCENT] The point blending option. The default
* is used for rendering both opaque and translucent points. However, if either all of the points are completely opaque or all are completely translucent,
2018-04-18 21:17:22 +08:00
* setting the technique to BlendOption.OPAQUE or BlendOption.TRANSLUCENT can improve performance by up to 2x.
* @param {boolean} [options.show=true] Determines if the primitives in the collection will be shown.
2015-04-08 05:36:08 +08:00
*
* @performance For best performance, prefer a few collections, each with many points, to
* many collections with only a few points each. Organize collections so that points
* with the same update frequency are in the same collection, i.e., points that do not
* change should be in one collection; points that change every frame should be in another
2015-04-08 05:36:08 +08:00
* collection; and so on.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
*
* @example
* // Create a pointPrimitive collection with two points
* const points = scene.primitives.add(new Cesium.PointPrimitiveCollection());
2015-05-05 02:40:31 +08:00
* points.add({
* position : new Cesium.Cartesian3(1.0, 2.0, 3.0),
2015-04-08 05:36:08 +08:00
* color : Cesium.Color.YELLOW
* });
2015-05-05 02:40:31 +08:00
* points.add({
* position : new Cesium.Cartesian3(4.0, 5.0, 6.0),
2015-04-08 05:36:08 +08:00
* color : Cesium.Color.CYAN
* });
2016-02-09 02:23:57 +08:00
*
* @see PointPrimitiveCollection#add
* @see PointPrimitiveCollection#remove
* @see PointPrimitive
2015-04-08 05:36:08 +08:00
*/
function PointPrimitiveCollection(options) {
options = options ?? Frozen.EMPTY_OBJECT;
2020-04-17 08:31:36 +08:00
this._sp = undefined;
2015-04-08 05:36:08 +08:00
this._spTranslucent = undefined;
this._rsOpaque = undefined;
this._rsTranslucent = undefined;
this._vaf = undefined;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
this._pointPrimitives = [];
this._pointPrimitivesToUpdate = [];
2015-04-08 05:36:08 +08:00
this._pointPrimitivesToUpdateIndex = 0;
this._pointPrimitivesRemoved = false;
this._createVertexArray = false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
this._shaderScaleByDistance = false;
this._compiledShaderScaleByDistance = false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
this._shaderTranslucencyByDistance = false;
this._compiledShaderTranslucencyByDistance = false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
this._shaderDistanceDisplayCondition = false;
this._compiledShaderDistanceDisplayCondition = false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
this._shaderDisableDepthDistance = false;
this._compiledShaderDisableDepthDistance = false;
2020-04-17 08:31:36 +08:00
this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES);
2020-04-17 08:31:36 +08:00
this._maxPixelSize = 1.0;
2020-04-17 08:31:36 +08:00
this._baseVolume = new BoundingSphere();
this._baseVolumeWC = new BoundingSphere();
2015-04-08 05:36:08 +08:00
this._baseVolume2D = new BoundingSphere();
this._boundingVolume = new BoundingSphere();
this._boundingVolumeDirty = false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
this._colorCommands = [];
2020-04-17 08:31:36 +08:00
2021-01-06 06:37:34 +08:00
/**
* Determines if primitives in this collection will be shown.
*
* @type {boolean}
2021-01-06 06:37:34 +08:00
* @default true
*/
2025-03-04 03:03:53 +08:00
this.show = options.show ?? true;
2021-01-06 06:37:34 +08:00
2020-04-17 08:31:36 +08:00
/**
2015-04-08 05:36:08 +08:00
* The 4x4 transformation matrix that transforms each point in this collection from model to world coordinates.
* When this is the identity matrix, the pointPrimitives are drawn in world coordinates, i.e., Earth's WGS84 coordinates.
* Local reference frames can be used by providing a different transformation matrix, like that returned
* by {@link Transforms.eastNorthUpToFixedFrame}.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @type {Matrix4}
* @default {@link Matrix4.IDENTITY}
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
*
* @example
* const center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883);
* pointPrimitives.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
* pointPrimitives.add({
2015-04-08 05:36:08 +08:00
* color : Cesium.Color.ORANGE,
* position : new Cesium.Cartesian3(0.0, 0.0, 0.0) // center
2020-04-17 08:31:36 +08:00
* });
2015-04-08 05:36:08 +08:00
* pointPrimitives.add({
* color : Cesium.Color.YELLOW,
* position : new Cesium.Cartesian3(1000000.0, 0.0, 0.0) // east
* });
* pointPrimitives.add({
* color : Cesium.Color.GREEN,
* position : new Cesium.Cartesian3(0.0, 1000000.0, 0.0) // north
* });
* pointPrimitives.add({
* color : Cesium.Color.CYAN,
* position : new Cesium.Cartesian3(0.0, 0.0, 1000000.0) // up
* });
*
* @see Transforms.eastNorthUpToFixedFrame
*/
2025-03-04 03:03:53 +08:00
this.modelMatrix = Matrix4.clone(options.modelMatrix ?? Matrix4.IDENTITY);
2015-04-08 05:36:08 +08:00
this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY);
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
/**
* This property is for debugging only; it is not for production use nor is it optimized.
* <p>
* Draws the bounding sphere for each draw command in the primitive.
2020-04-17 08:31:36 +08:00
* </p>
*
* @type {boolean}
2015-04-08 05:36:08 +08:00
*
* @default false
2015-04-08 05:36:08 +08:00
*/
2025-03-04 03:03:53 +08:00
this.debugShowBoundingVolume = options.debugShowBoundingVolume ?? false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
/**
* The point blending option. The default is used for rendering both opaque and translucent points.
* However, if either all of the points are completely opaque or all are completely translucent,
* setting the technique to BlendOption.OPAQUE or BlendOption.TRANSLUCENT can improve
* performance by up to 2x.
* @type {BlendOption}
* @default BlendOption.OPAQUE_AND_TRANSLUCENT
*/
2025-03-04 03:03:53 +08:00
this.blendOption = options.blendOption ?? BlendOption.OPAQUE_AND_TRANSLUCENT;
this._blendOption = undefined;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
this._mode = SceneMode.SCENE3D;
this._maxTotalPointSize = 1;
2020-04-17 08:31:36 +08:00
// The buffer usage for each attribute is determined based on the usage of the attribute over time.
this._buffersUsage = [
BufferUsage.STATIC_DRAW, // SHOW_INDEX
BufferUsage.STATIC_DRAW, // POSITION_INDEX
BufferUsage.STATIC_DRAW, // COLOR_INDEX
BufferUsage.STATIC_DRAW, // OUTLINE_COLOR_INDEX
2018-04-18 21:17:22 +08:00
BufferUsage.STATIC_DRAW, // OUTLINE_WIDTH_INDEX
BufferUsage.STATIC_DRAW, // PIXEL_SIZE_INDEX
BufferUsage.STATIC_DRAW, // SCALE_BY_DISTANCE_INDEX
BufferUsage.STATIC_DRAW, // TRANSLUCENCY_BY_DISTANCE_INDEX
BufferUsage.STATIC_DRAW, // DISTANCE_DISPLAY_CONDITION_INDEX
2020-04-17 08:31:36 +08:00
];
const that = this;
this._uniforms = {
u_maxTotalPointSize: function () {
return that._maxTotalPointSize;
2020-04-17 08:31:36 +08:00
},
};
}
2015-04-08 05:36:08 +08:00
Object.defineProperties(PointPrimitiveCollection.prototype, {
/**
* Returns the number of points in this collection. This is commonly used with
* {@link PointPrimitiveCollection#get} to iterate over all the points
* in the collection.
* @memberof PointPrimitiveCollection.prototype
* @type {number}
*/
length: {
get: function () {
removePointPrimitives(this);
return this._pointPrimitives.length;
2020-04-17 08:31:36 +08:00
},
},
});
2020-04-17 08:31:36 +08:00
2015-04-28 22:17:44 +08:00
function destroyPointPrimitives(pointPrimitives) {
const length = pointPrimitives.length;
for (let i = 0; i < length; ++i) {
if (pointPrimitives[i]) {
pointPrimitives[i]._destroy();
}
2020-04-17 08:31:36 +08:00
}
}
/**
* Creates and adds a point with the specified initial properties to the collection.
* The added point is returned so it can be modified or removed from the collection later.
2020-04-17 08:31:36 +08:00
*
* @param {object}[options] A template describing the point's properties as shown in Example 1.
* @returns {PointPrimitive} The point that was added to the collection.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @performance Calling <code>add</code> is expected constant time. However, the collection's vertex buffer
* is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For
* best performance, add as many pointPrimitives as possible before calling <code>update</code>.
2020-04-17 08:31:36 +08:00
*
* @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
2020-04-17 08:31:36 +08:00
*
*
2015-04-08 05:36:08 +08:00
* @example
* // Example 1: Add a point, specifying all the default values.
* const p = pointPrimitives.add({
2015-04-08 05:36:08 +08:00
* show : true,
* position : Cesium.Cartesian3.ZERO,
* pixelSize : 10.0,
2015-04-08 05:36:08 +08:00
* color : Cesium.Color.WHITE,
* outlineColor : Cesium.Color.TRANSPARENT,
* outlineWidth : 0.0,
2015-04-08 05:36:08 +08:00
* id : undefined
2020-04-17 08:31:36 +08:00
* });
*
2015-04-08 05:36:08 +08:00
* @example
* // Example 2: Specify only the point's cartographic position.
* const p = pointPrimitives.add({
* position : Cesium.Cartesian3.fromDegrees(longitude, latitude, height)
2020-04-17 08:31:36 +08:00
* });
*
* @see PointPrimitiveCollection#remove
* @see PointPrimitiveCollection#removeAll
2020-04-17 08:31:36 +08:00
*/
PointPrimitiveCollection.prototype.add = function (options) {
const p = new PointPrimitive(options, this);
2015-04-08 05:36:08 +08:00
p._index = this._pointPrimitives.length;
2020-04-17 08:31:36 +08:00
this._pointPrimitives.push(p);
this._createVertexArray = true;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
return p;
2020-04-17 08:31:36 +08:00
};
/**
* Removes a point from the collection.
2020-04-17 08:31:36 +08:00
*
* @param {PointPrimitive} pointPrimitive The point to remove.
* @returns {boolean} <code>true</code> if the point was removed; <code>false</code> if the point was not found in the collection.
2020-04-17 08:31:36 +08:00
*
* @performance Calling <code>remove</code> is expected constant time. However, the collection's vertex buffer
* is rewritten - an <code>O(n)</code> operation that also incurs CPU to GPU overhead. For
* best performance, remove as many points as possible before calling <code>update</code>.
* If you intend to temporarily hide a point, it is usually more efficient to call
* {@link PointPrimitive#show} instead of removing and re-adding the point.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
2020-04-17 08:31:36 +08:00
*
*
2015-04-08 05:36:08 +08:00
* @example
* const p = pointPrimitives.add(...);
* pointPrimitives.remove(p); // Returns true
2020-04-17 08:31:36 +08:00
*
* @see PointPrimitiveCollection#add
* @see PointPrimitiveCollection#removeAll
* @see PointPrimitive#show
2020-04-17 08:31:36 +08:00
*/
2015-04-08 05:36:08 +08:00
PointPrimitiveCollection.prototype.remove = function (pointPrimitive) {
if (this.contains(pointPrimitive)) {
this._pointPrimitives[pointPrimitive._index] = null; // Removed later
this._pointPrimitivesRemoved = true;
this._createVertexArray = true;
pointPrimitive._destroy();
return true;
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
return false;
2020-04-17 08:31:36 +08:00
};
/**
* Removes all points from the collection.
2020-04-17 08:31:36 +08:00
*
* @performance <code>O(n)</code>. It is more efficient to remove all the points
2015-04-08 05:36:08 +08:00
* from a collection and then add new ones than to create a new collection entirely.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
2020-04-17 08:31:36 +08:00
*
*
2015-04-08 05:36:08 +08:00
* @example
* pointPrimitives.add(...);
* pointPrimitives.add(...);
* pointPrimitives.removeAll();
2020-04-17 08:31:36 +08:00
*
* @see PointPrimitiveCollection#add
* @see PointPrimitiveCollection#remove
2020-04-17 08:31:36 +08:00
*/
2015-04-08 05:36:08 +08:00
PointPrimitiveCollection.prototype.removeAll = function () {
2015-04-28 22:17:44 +08:00
destroyPointPrimitives(this._pointPrimitives);
2015-04-08 05:36:08 +08:00
this._pointPrimitives = [];
2015-04-28 22:17:44 +08:00
this._pointPrimitivesToUpdate = [];
this._pointPrimitivesToUpdateIndex = 0;
2015-04-08 05:36:08 +08:00
this._pointPrimitivesRemoved = false;
2020-04-17 08:31:36 +08:00
2015-04-28 22:17:44 +08:00
this._createVertexArray = true;
2020-04-17 08:31:36 +08:00
};
2015-04-28 22:17:44 +08:00
function removePointPrimitives(pointPrimitiveCollection) {
2015-04-08 05:36:08 +08:00
if (pointPrimitiveCollection._pointPrimitivesRemoved) {
pointPrimitiveCollection._pointPrimitivesRemoved = false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const newPointPrimitives = [];
const pointPrimitives = pointPrimitiveCollection._pointPrimitives;
2015-04-28 22:17:44 +08:00
const length = pointPrimitives.length;
for (let i = 0, j = 0; i < length; ++i) {
const pointPrimitive = pointPrimitives[i];
if (pointPrimitive) {
pointPrimitive._index = j++;
newPointPrimitives.push(pointPrimitive);
}
}
pointPrimitiveCollection._pointPrimitives = newPointPrimitives;
2020-04-17 08:31:36 +08:00
}
}
PointPrimitiveCollection.prototype._updatePointPrimitive = function (
2015-04-08 05:36:08 +08:00
pointPrimitive,
propertyChanged,
2020-04-17 08:31:36 +08:00
) {
if (!pointPrimitive._dirty) {
this._pointPrimitivesToUpdate[this._pointPrimitivesToUpdateIndex++] =
2015-04-08 05:36:08 +08:00
pointPrimitive;
2020-04-17 08:31:36 +08:00
}
++this._propertiesChanged[propertyChanged];
2020-04-17 08:31:36 +08:00
};
/**
* Check whether this collection contains a given point.
2019-08-27 10:00:33 +08:00
*
* @param {PointPrimitive} [pointPrimitive] The point to check for.
* @returns {boolean} true if this collection contains the point, false otherwise.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @see PointPrimitiveCollection#get
2020-04-17 08:31:36 +08:00
*/
2015-04-08 05:36:08 +08:00
PointPrimitiveCollection.prototype.contains = function (pointPrimitive) {
2020-04-17 08:31:36 +08:00
return (
2015-04-08 05:36:08 +08:00
defined(pointPrimitive) && pointPrimitive._pointPrimitiveCollection === this
2020-04-17 08:31:36 +08:00
);
};
/**
2015-04-08 05:36:08 +08:00
* Returns the point in the collection at the specified index. Indices are zero-based
* and increase as points are added. Removing a point shifts all points after
* it to the left, changing their indices. This function is commonly used with
* {@link PointPrimitiveCollection#length} to iterate over all the points
* in the collection.
2020-04-17 08:31:36 +08:00
*
* @param {number} index The zero-based index of the point.
2015-04-08 05:36:08 +08:00
* @returns {PointPrimitive} The point at the specified index.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @performance Expected constant time. If points were removed from the collection and
* {@link PointPrimitiveCollection#update} was not called, an implicit <code>O(n)</code>
2015-04-08 05:36:08 +08:00
* operation is performed.
*
* @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
*
*
* @example
* // Toggle the show property of every point in the collection
* const len = pointPrimitives.length;
* for (let i = 0; i < len; ++i) {
* const p = pointPrimitives.get(i);
2015-04-08 05:36:08 +08:00
* p.show = !p.show;
* }
2016-02-09 02:23:57 +08:00
*
* @see PointPrimitiveCollection#length
2015-04-08 05:36:08 +08:00
*/
2019-08-27 10:00:33 +08:00
PointPrimitiveCollection.prototype.get = function (index) {
//>>includeStart('debug', pragmas.debug);
2015-04-08 05:36:08 +08:00
if (!defined(index)) {
2019-08-27 10:00:33 +08:00
throw new DeveloperError("index is required.");
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
//>>includeEnd('debug');
2020-04-17 08:31:36 +08:00
2019-08-27 10:00:33 +08:00
removePointPrimitives(this);
2015-04-08 05:36:08 +08:00
return this._pointPrimitives[index];
};
2020-04-17 08:31:36 +08:00
PointPrimitiveCollection.prototype.computeNewBuffersUsage = function () {
const buffersUsage = this._buffersUsage;
2015-04-08 05:36:08 +08:00
let usageChanged = false;
2020-04-17 08:31:36 +08:00
const properties = this._propertiesChanged;
for (let k = 0; k < NUMBER_OF_PROPERTIES; ++k) {
const newUsage =
properties[k] === 0 ? BufferUsage.STATIC_DRAW : BufferUsage.STREAM_DRAW;
usageChanged = usageChanged || buffersUsage[k] !== newUsage;
2015-04-08 05:36:08 +08:00
buffersUsage[k] = newUsage;
}
2020-04-17 08:31:36 +08:00
return usageChanged;
2020-04-17 08:31:36 +08:00
};
2015-04-08 05:36:08 +08:00
function createVAF(context, numberOfPointPrimitives, buffersUsage) {
return new VertexArrayFacade(
context,
2020-04-17 08:31:36 +08:00
[
{
2015-04-08 05:36:08 +08:00
index: attributeLocations.positionHighAndSize,
componentsPerAttribute: 4,
componentDatatype: ComponentDatatype.FLOAT,
usage: buffersUsage[POSITION_INDEX],
2020-04-17 08:31:36 +08:00
},
{
index: attributeLocations.positionLowAndShow,
componentsPerAttribute: 4,
componentDatatype: ComponentDatatype.FLOAT,
usage: buffersUsage[POSITION_INDEX],
2020-04-17 08:31:36 +08:00
},
{
index: attributeLocations.compressedAttribute0,
2015-04-08 05:36:08 +08:00
componentsPerAttribute: 4,
componentDatatype: ComponentDatatype.FLOAT,
usage: buffersUsage[COLOR_INDEX],
2020-04-17 08:31:36 +08:00
},
{
index: attributeLocations.compressedAttribute1,
2015-04-08 05:36:08 +08:00
componentsPerAttribute: 4,
componentDatatype: ComponentDatatype.FLOAT,
usage: buffersUsage[TRANSLUCENCY_BY_DISTANCE_INDEX],
2020-04-17 08:31:36 +08:00
},
{
index: attributeLocations.scaleByDistance,
componentsPerAttribute: 4,
componentDatatype: ComponentDatatype.FLOAT,
usage: buffersUsage[SCALE_BY_DISTANCE_INDEX],
2015-04-08 05:36:08 +08:00
},
{
index:
attributeLocations.distanceDisplayConditionAndDisableDepthAndSplitDirection,
componentsPerAttribute: 4,
2015-04-08 05:36:08 +08:00
componentDatatype: ComponentDatatype.FLOAT,
usage: buffersUsage[DISTANCE_DISPLAY_CONDITION_INDEX],
2020-04-17 08:31:36 +08:00
},
],
numberOfPointPrimitives,
); // 1 vertex per pointPrimitive
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
///////////////////////////////////////////////////////////////////////////
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
// PERFORMANCE_IDEA: Save memory if a property is the same for all pointPrimitives, use a latched attribute state,
// instead of storing it in a vertex buffer.
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const writePositionScratch = new EncodedCartesian3();
2020-04-17 08:31:36 +08:00
function writePositionSizeAndOutline(
2015-04-08 05:36:08 +08:00
pointPrimitiveCollection,
2020-04-17 08:31:36 +08:00
context,
2015-04-08 05:36:08 +08:00
vafWriters,
pointPrimitive,
2020-04-17 08:31:36 +08:00
) {
2015-04-08 05:36:08 +08:00
const i = pointPrimitive._index;
const position = pointPrimitive._getActualPosition();
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
if (pointPrimitiveCollection._mode === SceneMode.SCENE3D) {
BoundingSphere.expand(
pointPrimitiveCollection._baseVolume,
position,
pointPrimitiveCollection._baseVolume,
2020-04-17 08:31:36 +08:00
);
2015-04-08 05:36:08 +08:00
pointPrimitiveCollection._boundingVolumeDirty = true;
}
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
EncodedCartesian3.fromCartesian(position, writePositionScratch);
const pixelSize = pointPrimitive.pixelSize;
const outlineWidth = pointPrimitive.outlineWidth;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
pointPrimitiveCollection._maxPixelSize = Math.max(
pointPrimitiveCollection._maxPixelSize,
pixelSize + outlineWidth,
2020-04-17 08:31:36 +08:00
);
const positionHighWriter = vafWriters[attributeLocations.positionHighAndSize];
2015-04-08 05:36:08 +08:00
const high = writePositionScratch.high;
positionHighWriter(i, high.x, high.y, high.z, pixelSize);
2020-04-17 08:31:36 +08:00
const positionLowWriter =
vafWriters[attributeLocations.positionLowAndOutline];
2015-04-08 05:36:08 +08:00
const low = writePositionScratch.low;
positionLowWriter(i, low.x, low.y, low.z, outlineWidth);
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
const LEFT_SHIFT16 = 65536.0; // 2^16
const LEFT_SHIFT8 = 256.0; // 2^8
2020-04-17 08:31:36 +08:00
function writeCompressedAttrib0(
pointPrimitiveCollection,
2015-04-08 05:36:08 +08:00
context,
vafWriters,
pointPrimitive,
) {
const i = pointPrimitive._index;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const color = pointPrimitive.color;
const pickColor = pointPrimitive.getPickId(context).color;
const outlineColor = pointPrimitive.outlineColor;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
let red = Color.floatToByte(color.red);
let green = Color.floatToByte(color.green);
let blue = Color.floatToByte(color.blue);
const compressed0 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
red = Color.floatToByte(outlineColor.red);
green = Color.floatToByte(outlineColor.green);
blue = Color.floatToByte(outlineColor.blue);
const compressed1 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
red = Color.floatToByte(pickColor.red);
green = Color.floatToByte(pickColor.green);
blue = Color.floatToByte(pickColor.blue);
const compressed2 = red * LEFT_SHIFT16 + green * LEFT_SHIFT8 + blue;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const compressed3 =
Color.floatToByte(color.alpha) * LEFT_SHIFT16 +
Color.floatToByte(outlineColor.alpha) * LEFT_SHIFT8 +
Color.floatToByte(pickColor.alpha);
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const writer = vafWriters[attributeLocations.compressedAttribute0];
writer(i, compressed0, compressed1, compressed2, compressed3);
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
function writeCompressedAttrib1(
pointPrimitiveCollection,
context,
vafWriters,
pointPrimitive,
) {
const i = pointPrimitive._index;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
let near = 0.0;
let nearValue = 1.0;
let far = 1.0;
let farValue = 1.0;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const translucency = pointPrimitive.translucencyByDistance;
if (defined(translucency)) {
near = translucency.near;
nearValue = translucency.nearValue;
far = translucency.far;
farValue = translucency.farValue;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
if (nearValue !== 1.0 || farValue !== 1.0) {
// translucency by distance calculation in shader need not be enabled
// until a pointPrimitive with near and far !== 1.0 is found
pointPrimitiveCollection._shaderTranslucencyByDistance = true;
}
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
let show = pointPrimitive.show && pointPrimitive.clusterShow;
2020-04-17 08:31:36 +08:00
// If the color alphas are zero, do not show this pointPrimitive. This lets us avoid providing
2015-04-08 05:36:08 +08:00
// color during the pick pass and also eliminates a discard in the fragment shader.
2020-04-17 08:31:36 +08:00
if (
2015-04-08 05:36:08 +08:00
pointPrimitive.color.alpha === 0.0 &&
pointPrimitive.outlineColor.alpha === 0.0
) {
show = false;
}
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
nearValue = CesiumMath.clamp(nearValue, 0.0, 1.0);
nearValue = nearValue === 1.0 ? 255.0 : (nearValue * 255.0) | 0;
2015-04-08 05:36:08 +08:00
const compressed0 = (show ? 1.0 : 0.0) * LEFT_SHIFT8 + nearValue;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
farValue = CesiumMath.clamp(farValue, 0.0, 1.0);
farValue = farValue === 1.0 ? 255.0 : (farValue * 255.0) | 0;
const compressed1 = farValue;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const writer = vafWriters[attributeLocations.compressedAttribute1];
writer(i, compressed0, compressed1, near, far);
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
function writeScaleByDistance(
pointPrimitiveCollection,
context,
vafWriters,
pointPrimitive,
) {
const i = pointPrimitive._index;
const writer = vafWriters[attributeLocations.scaleByDistance];
let near = 0.0;
2015-04-08 05:36:08 +08:00
let nearValue = 1.0;
let far = 1.0;
let farValue = 1.0;
2022-01-22 00:26:25 +08:00
2015-04-08 05:36:08 +08:00
const scale = pointPrimitive.scaleByDistance;
if (defined(scale)) {
2015-04-08 05:36:08 +08:00
near = scale.near;
nearValue = scale.nearValue;
far = scale.far;
farValue = scale.farValue;
2020-04-17 08:31:36 +08:00
if (nearValue !== 1.0 || farValue !== 1.0) {
// scale by distance calculation in shader need not be enabled
2015-04-08 05:36:08 +08:00
// until a pointPrimitive with near and far !== 1.0 is found
pointPrimitiveCollection._shaderScaleByDistance = true;
}
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
writer(i, near, nearValue, far, farValue);
2020-04-17 08:31:36 +08:00
}
function writeDistanceDisplayConditionAndDepthDisableAndSplitDirection(
pointPrimitiveCollection,
context,
vafWriters,
pointPrimitive,
) {
2015-04-08 05:36:08 +08:00
const i = pointPrimitive._index;
const writer =
vafWriters[
attributeLocations
.distanceDisplayConditionAndDisableDepthAndSplitDirection
];
2015-04-08 05:36:08 +08:00
let near = 0.0;
let far = Number.MAX_VALUE;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const distanceDisplayCondition = pointPrimitive.distanceDisplayCondition;
if (defined(distanceDisplayCondition)) {
near = distanceDisplayCondition.near;
far = distanceDisplayCondition.far;
2020-04-17 08:31:36 +08:00
near *= near;
far *= far;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
pointPrimitiveCollection._shaderDistanceDisplayCondition = true;
}
2020-04-17 08:31:36 +08:00
let disableDepthTestDistance = pointPrimitive.disableDepthTestDistance;
disableDepthTestDistance *= disableDepthTestDistance;
if (disableDepthTestDistance > 0.0) {
pointPrimitiveCollection._shaderDisableDepthDistance = true;
if (disableDepthTestDistance === Number.POSITIVE_INFINITY) {
2015-04-08 05:36:08 +08:00
disableDepthTestDistance = -1.0;
}
2020-04-17 08:31:36 +08:00
}
let direction = 0.0;
const split = pointPrimitive.splitDirection;
if (defined(split)) {
direction = split;
}
writer(i, near, far, disableDepthTestDistance, direction);
}
2015-04-08 05:36:08 +08:00
function writePointPrimitive(
pointPrimitiveCollection,
context,
vafWriters,
2015-10-24 07:20:40 +08:00
pointPrimitive,
2015-04-08 05:36:08 +08:00
) {
writePositionSizeAndOutline(
2015-04-08 05:36:08 +08:00
pointPrimitiveCollection,
2020-04-17 08:31:36 +08:00
context,
2015-04-08 05:36:08 +08:00
vafWriters,
2015-10-24 07:20:40 +08:00
pointPrimitive,
2020-04-17 08:31:36 +08:00
);
2015-04-08 05:36:08 +08:00
writeCompressedAttrib0(
pointPrimitiveCollection,
context,
vafWriters,
pointPrimitive,
);
writeCompressedAttrib1(
pointPrimitiveCollection,
2020-04-17 08:31:36 +08:00
context,
2015-04-08 05:36:08 +08:00
vafWriters,
pointPrimitive,
);
writeScaleByDistance(
pointPrimitiveCollection,
2020-04-17 08:31:36 +08:00
context,
2015-04-08 05:36:08 +08:00
vafWriters,
pointPrimitive,
2020-04-17 08:31:36 +08:00
);
writeDistanceDisplayConditionAndDepthDisableAndSplitDirection(
pointPrimitiveCollection,
context,
vafWriters,
pointPrimitive,
);
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
function recomputeActualPositions(
pointPrimitiveCollection,
pointPrimitives,
length,
frameState,
modelMatrix,
recomputeBoundingVolume,
2020-04-17 08:31:36 +08:00
) {
2015-04-08 05:36:08 +08:00
let boundingVolume;
if (frameState.mode === SceneMode.SCENE3D) {
boundingVolume = pointPrimitiveCollection._baseVolume;
pointPrimitiveCollection._boundingVolumeDirty = true;
} else {
boundingVolume = pointPrimitiveCollection._baseVolume2D;
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
const positions = [];
for (let i = 0; i < length; ++i) {
const pointPrimitive = pointPrimitives[i];
const position = pointPrimitive.position;
const actualPosition = PointPrimitive._computeActualPosition(
position,
frameState,
modelMatrix,
2020-04-17 08:31:36 +08:00
);
2015-04-08 05:36:08 +08:00
if (defined(actualPosition)) {
pointPrimitive._setActualPosition(actualPosition);
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
if (recomputeBoundingVolume) {
positions.push(actualPosition);
} else {
BoundingSphere.expand(boundingVolume, actualPosition, boundingVolume);
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
}
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
if (recomputeBoundingVolume) {
BoundingSphere.fromPoints(positions, boundingVolume);
2020-04-17 08:31:36 +08:00
}
}
2015-04-08 05:36:08 +08:00
function updateMode(pointPrimitiveCollection, frameState) {
const mode = frameState.mode;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const pointPrimitives = pointPrimitiveCollection._pointPrimitives;
const pointPrimitivesToUpdate =
pointPrimitiveCollection._pointPrimitivesToUpdate;
const modelMatrix = pointPrimitiveCollection._modelMatrix;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
if (
pointPrimitiveCollection._createVertexArray ||
pointPrimitiveCollection._mode !== mode ||
(mode !== SceneMode.SCENE3D &&
!Matrix4.equals(modelMatrix, pointPrimitiveCollection.modelMatrix))
2020-04-17 08:31:36 +08:00
) {
2015-04-08 05:36:08 +08:00
pointPrimitiveCollection._mode = mode;
Matrix4.clone(pointPrimitiveCollection.modelMatrix, modelMatrix);
pointPrimitiveCollection._createVertexArray = true;
2020-04-17 08:31:36 +08:00
if (
mode === SceneMode.SCENE3D ||
mode === SceneMode.SCENE2D ||
mode === SceneMode.COLUMBUS_VIEW
) {
recomputeActualPositions(
pointPrimitiveCollection,
pointPrimitives,
pointPrimitives.length,
2015-04-08 05:36:08 +08:00
frameState,
modelMatrix,
true,
);
}
} else if (mode === SceneMode.MORPHING) {
recomputeActualPositions(
pointPrimitiveCollection,
pointPrimitives,
pointPrimitives.length,
frameState,
modelMatrix,
2020-04-17 08:31:36 +08:00
true,
);
2015-04-08 05:36:08 +08:00
} else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) {
recomputeActualPositions(
pointPrimitiveCollection,
pointPrimitivesToUpdate,
pointPrimitiveCollection._pointPrimitivesToUpdateIndex,
2015-10-24 07:20:40 +08:00
frameState,
2015-04-08 05:36:08 +08:00
modelMatrix,
false,
2020-04-17 08:31:36 +08:00
);
}
}
2015-04-08 05:36:08 +08:00
function updateBoundingVolume(collection, frameState, boundingVolume) {
const pixelSize = frameState.camera.getPixelSize(
2015-10-24 07:20:40 +08:00
boundingVolume,
2015-04-08 05:36:08 +08:00
frameState.context.drawingBufferWidth,
frameState.context.drawingBufferHeight,
2020-04-17 08:31:36 +08:00
);
const size = pixelSize * collection._maxPixelSize;
2015-04-08 05:36:08 +08:00
boundingVolume.radius += size;
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
const scratchWriterArray = [];
2020-04-17 08:31:36 +08:00
/**
2015-04-08 05:36:08 +08:00
* @private
*/
PointPrimitiveCollection.prototype.update = function (frameState) {
2015-04-11 03:25:30 +08:00
removePointPrimitives(this);
2020-04-17 08:31:36 +08:00
2021-01-06 06:37:34 +08:00
if (!this.show) {
return;
}
2015-04-08 05:36:08 +08:00
this._maxTotalPointSize = ContextLimits.maximumAliasedPointSize;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
updateMode(this, frameState);
2020-04-17 08:31:36 +08:00
2015-04-28 22:17:44 +08:00
const pointPrimitives = this._pointPrimitives;
const pointPrimitivesLength = pointPrimitives.length;
2015-04-08 05:36:08 +08:00
const pointPrimitivesToUpdate = this._pointPrimitivesToUpdate;
const pointPrimitivesToUpdateLength = this._pointPrimitivesToUpdateIndex;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const properties = this._propertiesChanged;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const createVertexArray = this._createVertexArray;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
let vafWriters;
const context = frameState.context;
const pass = frameState.passes;
const picking = pass.pick;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
// PERFORMANCE_IDEA: Round robin multiple buffers.
if (createVertexArray || (!picking && this.computeNewBuffersUsage())) {
this._createVertexArray = false;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
for (let k = 0; k < NUMBER_OF_PROPERTIES; ++k) {
properties[k] = 0;
}
this._vaf = this._vaf && this._vaf.destroy();
if (pointPrimitivesLength > 0) {
// PERFORMANCE_IDEA: Instead of creating a new one, resize like std::vector.
this._vaf = createVAF(context, pointPrimitivesLength, this._buffersUsage);
vafWriters = this._vaf.writers;
// Rewrite entire buffer if pointPrimitives were added or removed.
for (let i = 0; i < pointPrimitivesLength; ++i) {
const pointPrimitive = this._pointPrimitives[i];
pointPrimitive._dirty = false; // In case it needed an update.
2015-04-08 05:36:08 +08:00
writePointPrimitive(this, context, vafWriters, pointPrimitive);
2020-04-17 08:31:36 +08:00
}
this._vaf.commit();
}
2015-04-08 05:36:08 +08:00
this._pointPrimitivesToUpdateIndex = 0;
} else if (pointPrimitivesToUpdateLength > 0) {
// PointPrimitives were modified, but none were added or removed.
const writers = scratchWriterArray;
writers.length = 0;
2020-04-17 08:31:36 +08:00
if (
properties[POSITION_INDEX] ||
2017-06-17 00:05:18 +08:00
properties[OUTLINE_WIDTH_INDEX] ||
properties[PIXEL_SIZE_INDEX]
2020-04-17 08:31:36 +08:00
) {
writers.push(writePositionSizeAndOutline);
2015-04-08 05:36:08 +08:00
}
if (properties[COLOR_INDEX] || properties[OUTLINE_COLOR_INDEX]) {
writers.push(writeCompressedAttrib0);
}
if (properties[SHOW_INDEX] || properties[TRANSLUCENCY_BY_DISTANCE_INDEX]) {
writers.push(writeCompressedAttrib1);
}
2015-10-24 07:20:40 +08:00
if (properties[SCALE_BY_DISTANCE_INDEX]) {
writers.push(writeScaleByDistance);
2015-04-08 05:36:08 +08:00
}
2020-04-17 08:31:36 +08:00
if (
2015-04-08 05:36:08 +08:00
properties[DISTANCE_DISPLAY_CONDITION_INDEX] ||
properties[DISABLE_DEPTH_DISTANCE_INDEX] ||
properties[SPLIT_DIRECTION_INDEX]
2017-06-17 00:05:18 +08:00
) {
writers.push(
writeDistanceDisplayConditionAndDepthDisableAndSplitDirection,
);
}
2017-06-17 00:05:18 +08:00
const numWriters = writers.length;
2015-04-08 05:36:08 +08:00
2017-06-17 00:05:18 +08:00
vafWriters = this._vaf.writers;
if (pointPrimitivesToUpdateLength / pointPrimitivesLength > 0.1) {
// If more than 10% of pointPrimitive change, rewrite the entire buffer.
2015-04-08 05:36:08 +08:00
// PERFORMANCE_IDEA: I totally made up 10% :).
for (let m = 0; m < pointPrimitivesToUpdateLength; ++m) {
const b = pointPrimitivesToUpdate[m];
b._dirty = false;
for (let n = 0; n < numWriters; ++n) {
writers[n](this, context, vafWriters, b);
}
2020-04-17 08:31:36 +08:00
}
this._vaf.commit();
} else {
for (let h = 0; h < pointPrimitivesToUpdateLength; ++h) {
const bb = pointPrimitivesToUpdate[h];
bb._dirty = false;
2020-04-17 08:31:36 +08:00
for (let o = 0; o < numWriters; ++o) {
writers[o](this, context, vafWriters, bb);
}
2017-06-17 00:05:18 +08:00
this._vaf.subCommit(bb._index, 1);
2020-04-17 08:31:36 +08:00
}
2017-06-17 00:05:18 +08:00
this._vaf.endSubCommits();
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
2017-04-01 05:46:23 +08:00
this._pointPrimitivesToUpdateIndex = 0;
2020-04-17 08:31:36 +08:00
}
2017-04-01 05:46:23 +08:00
// If the number of total pointPrimitives ever shrinks considerably
// Truncate pointPrimitivesToUpdate so that we free memory that we're
// not going to be using.
if (pointPrimitivesToUpdateLength > pointPrimitivesLength * 1.5) {
pointPrimitivesToUpdate.length = pointPrimitivesLength;
}
2020-04-17 08:31:36 +08:00
if (!defined(this._vaf) || !defined(this._vaf.va)) {
return;
}
2020-04-17 08:31:36 +08:00
if (this._boundingVolumeDirty) {
this._boundingVolumeDirty = false;
BoundingSphere.transform(
this._baseVolume,
this.modelMatrix,
this._baseVolumeWC,
2020-04-17 08:31:36 +08:00
);
}
let boundingVolume;
let modelMatrix = Matrix4.IDENTITY;
if (frameState.mode === SceneMode.SCENE3D) {
modelMatrix = this.modelMatrix;
boundingVolume = BoundingSphere.clone(
this._baseVolumeWC,
2015-04-08 05:36:08 +08:00
this._boundingVolume,
2020-04-17 08:31:36 +08:00
);
} else {
boundingVolume = BoundingSphere.clone(
this._baseVolume2D,
this._boundingVolume,
2020-04-17 08:31:36 +08:00
);
}
updateBoundingVolume(this, frameState, boundingVolume);
2020-04-17 08:31:36 +08:00
const blendOptionChanged = this._blendOption !== this.blendOption;
this._blendOption = this.blendOption;
2020-04-17 08:31:36 +08:00
if (blendOptionChanged) {
2020-04-17 08:31:36 +08:00
if (
this._blendOption === BlendOption.OPAQUE ||
this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT
2020-04-17 08:31:36 +08:00
) {
this._rsOpaque = RenderState.fromCache({
depthTest: {
enabled: true,
func: WebGLConstants.LEQUAL,
2020-04-17 08:31:36 +08:00
},
depthMask: true,
});
2020-04-17 08:31:36 +08:00
} else {
this._rsOpaque = undefined;
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
2020-04-17 08:31:36 +08:00
if (
2015-04-08 05:36:08 +08:00
this._blendOption === BlendOption.TRANSLUCENT ||
this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT
2020-04-17 08:31:36 +08:00
) {
this._rsTranslucent = RenderState.fromCache({
depthTest: {
enabled: true,
func: WebGLConstants.LEQUAL,
2020-04-17 08:31:36 +08:00
},
depthMask: false,
blending: BlendingState.ALPHA_BLEND,
});
} else {
this._rsTranslucent = undefined;
2020-04-17 08:31:36 +08:00
}
}
this._shaderDisableDepthDistance =
this._shaderDisableDepthDistance ||
frameState.minimumDisableDepthTestDistance !== 0.0;
let vs;
2020-04-17 08:31:36 +08:00
let fs;
if (
blendOptionChanged ||
(this._shaderScaleByDistance && !this._compiledShaderScaleByDistance) ||
(this._shaderTranslucencyByDistance &&
!this._compiledShaderTranslucencyByDistance) ||
(this._shaderDistanceDisplayCondition &&
!this._compiledShaderDistanceDisplayCondition) ||
this._shaderDisableDepthDistance !==
this._compiledShaderDisableDepthDistance
2020-04-17 08:31:36 +08:00
) {
vs = new ShaderSource({
sources: [PointPrimitiveCollectionVS],
2020-04-17 08:31:36 +08:00
});
if (this._shaderScaleByDistance) {
vs.defines.push("EYE_DISTANCE_SCALING");
2020-04-17 08:31:36 +08:00
}
if (this._shaderTranslucencyByDistance) {
vs.defines.push("EYE_DISTANCE_TRANSLUCENCY");
2020-04-17 08:31:36 +08:00
}
if (this._shaderDistanceDisplayCondition) {
vs.defines.push("DISTANCE_DISPLAY_CONDITION");
2020-04-17 08:31:36 +08:00
}
if (this._shaderDisableDepthDistance) {
vs.defines.push("DISABLE_DEPTH_DISTANCE");
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
if (this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT) {
fs = new ShaderSource({
2015-04-08 05:36:08 +08:00
defines: ["OPAQUE"],
sources: [PointPrimitiveCollectionFS],
});
this._sp = ShaderProgram.replaceCache({
context: context,
shaderProgram: this._sp,
vertexShaderSource: vs,
fragmentShaderSource: fs,
attributeLocations: attributeLocations,
2020-04-17 08:31:36 +08:00
});
fs = new ShaderSource({
defines: ["TRANSLUCENT"],
sources: [PointPrimitiveCollectionFS],
2020-04-17 08:31:36 +08:00
});
this._spTranslucent = ShaderProgram.replaceCache({
context: context,
shaderProgram: this._spTranslucent,
vertexShaderSource: vs,
fragmentShaderSource: fs,
attributeLocations: attributeLocations,
2020-04-17 08:31:36 +08:00
});
2015-04-08 05:36:08 +08:00
}
if (this._blendOption === BlendOption.OPAQUE) {
fs = new ShaderSource({
sources: [PointPrimitiveCollectionFS],
});
this._sp = ShaderProgram.replaceCache({
context: context,
shaderProgram: this._sp,
vertexShaderSource: vs,
fragmentShaderSource: fs,
attributeLocations: attributeLocations,
});
2020-04-17 08:31:36 +08:00
}
if (this._blendOption === BlendOption.TRANSLUCENT) {
2015-04-08 05:36:08 +08:00
fs = new ShaderSource({
sources: [PointPrimitiveCollectionFS],
});
this._spTranslucent = ShaderProgram.replaceCache({
context: context,
shaderProgram: this._spTranslucent,
vertexShaderSource: vs,
2015-04-08 05:36:08 +08:00
fragmentShaderSource: fs,
attributeLocations: attributeLocations,
});
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
this._compiledShaderScaleByDistance = this._shaderScaleByDistance;
this._compiledShaderTranslucencyByDistance =
this._shaderTranslucencyByDistance;
this._compiledShaderDistanceDisplayCondition =
this._shaderDistanceDisplayCondition;
this._compiledShaderDisableDepthDistance = this._shaderDisableDepthDistance;
}
2020-04-17 08:31:36 +08:00
let va;
2015-04-08 05:36:08 +08:00
let vaLength;
let command;
2020-04-17 08:31:36 +08:00
let j;
2015-04-08 05:36:08 +08:00
const commandList = frameState.commandList;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
if (pass.render || picking) {
const colorList = this._colorCommands;
2020-04-17 08:31:36 +08:00
const opaque = this._blendOption === BlendOption.OPAQUE;
2015-04-08 05:36:08 +08:00
const opaqueAndTranslucent =
this._blendOption === BlendOption.OPAQUE_AND_TRANSLUCENT;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
va = this._vaf.va;
vaLength = va.length;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
colorList.length = vaLength;
const totalLength = opaqueAndTranslucent ? vaLength * 2 : vaLength;
for (j = 0; j < totalLength; ++j) {
const opaqueCommand = opaque || (opaqueAndTranslucent && j % 2 === 0);
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
command = colorList[j];
if (!defined(command)) {
command = colorList[j] = new DrawCommand();
2020-04-17 08:31:36 +08:00
}
2015-04-08 05:36:08 +08:00
command.primitiveType = PrimitiveType.POINTS;
command.pass =
opaqueCommand || !opaqueAndTranslucent ? Pass.OPAQUE : Pass.TRANSLUCENT;
command.owner = this;
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
const index = opaqueAndTranslucent ? Math.floor(j / 2.0) : j;
command.boundingVolume = boundingVolume;
command.modelMatrix = modelMatrix;
command.shaderProgram = opaqueCommand ? this._sp : this._spTranslucent;
command.uniformMap = this._uniforms;
command.vertexArray = va[index].va;
command.renderState = opaqueCommand
? this._rsOpaque
: this._rsTranslucent;
command.debugShowBoundingVolume = this.debugShowBoundingVolume;
command.pickId = "v_pickColor";
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
commandList.push(command);
2020-04-17 08:31:36 +08:00
}
}
};
/**
2015-04-08 05:36:08 +08:00
* Returns true if this object was destroyed; otherwise, false.
* <br /><br />
* If this object was destroyed, it should not be used; calling any function other than
* <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
2020-04-17 08:31:36 +08:00
*
* @returns {boolean} <code>true</code> if this object was destroyed; otherwise, <code>false</code>.
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @see PointPrimitiveCollection#destroy
2020-04-17 08:31:36 +08:00
*/
2015-04-08 05:36:08 +08:00
PointPrimitiveCollection.prototype.isDestroyed = function () {
return false;
2020-04-17 08:31:36 +08:00
};
/**
2015-04-08 05:36:08 +08:00
* Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
* release of WebGL resources, instead of relying on the garbage collector to destroy this object.
* <br /><br />
* Once an object is destroyed, it should not be used; calling any function other than
* <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
* assign the return value (<code>undefined</code>) to the object as done in the example.
*
* @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
*
2020-04-17 08:31:36 +08:00
*
2015-04-08 05:36:08 +08:00
* @example
* pointPrimitives = pointPrimitives && pointPrimitives.destroy();
2016-02-09 02:23:57 +08:00
*
* @see PointPrimitiveCollection#isDestroyed
2015-04-08 05:36:08 +08:00
*/
PointPrimitiveCollection.prototype.destroy = function () {
this._sp = this._sp && this._sp.destroy();
this._spTranslucent = this._spTranslucent && this._spTranslucent.destroy();
2015-04-08 05:36:08 +08:00
this._spPick = this._spPick && this._spPick.destroy();
this._vaf = this._vaf && this._vaf.destroy();
2015-04-28 22:17:44 +08:00
destroyPointPrimitives(this._pointPrimitives);
2020-04-17 08:31:36 +08:00
2015-04-08 05:36:08 +08:00
return destroyObject(this);
};
Migrate Cesium to ES6 Modules See https://github.com/AnalyticalGraphicsInc/cesium/pull/8224 for details. eslint There are a handful of new .eslintrc.json files, mostly to identify the files that are still AMD modules (Sandcastle/Workers). These are needed because you can't change the parser type with a comment directive (since the parser is the thing reading the file). We can finally detect unusued modules! So those have all been cleaned up as well. requirejs -> rollup & clean-css requirejs, almond, and karma-requirejs have all been removed. We now use rollup for building and minifying (via uglify) JS code and clean-css for css. These changes are fairly straight-forward and just involve calling rollup instead of requirejs in the build process. Overall build time is significantly faster. CI is ~11 minutes compared to ~17 in master. Running makeZipFile on my machine takes 69 seconds compared to 112 seconds in master. There's probably plenty of room for additional optimization here too. We wrote an published a small npm module, rollup-plugin-strip-pragma, for stripping the requirejs pragmas we use out of the release builds. This is maintained in the Tools/rollup-plugin-strip-pragma directory. As for what we produce. The built version of Cesium is now a UMD module. So it should work anywhere that hasn't made the jump to ES6 yet. For users that were already using the "legacy" combined/minified approach, nothing changes. One awesome thing about roll-up is that it compiles all of the workers at once and automatically detects shared codes and generates separate bundles under the hood. This means the size of our worker modules shrink dramatically and Cesium itself will load them much faster. The total minified/gzipped size of all workers in master is 2.6 MB compared to 225 KB in this branch! This should be most noticeable on demos like Geometry & Appearances which load lots of workers for the various geometry typs. roll-up is also used to build Cesium Viewer, which is now an ES6 app. We use clean-css via gulp and it is also a straightforward change from requirejs that requires no special mention. Workers While the spec allows for ES6 Web Workers, no browser actually supports them yet. That means we needed a way to get our workers into non-ES6 form. Thankfully, roll-up can generate AMD modules, which means we now have a build step to compile our Worker source code back into AMD and use the existing TaskProcessor to load and execute them. This build step is part of the standard build task and is called createWorkers. During development, these "built" workers are un-optimized so you can still debug them and read the code. Since there is a build step, that means if you are changing code that affects a worker, you need to re-run build, or you can use the build-watch task to do it automatically. The ES6 versions of Worker code has moved into Source/WorkersES6 and we build the workers into their "old home" of Source/Workers. cesiumWorkerBootstrapper and transferTypedArrayTest which were already non-AMD ES5 scripts remain living in the Workers directory. Surprisingly little was changed about TaskProcessor or the worker system in general, especially considering that I thought this would be one of the major hurdles. ThirdParty A lot of our ThirdParty either already had a hand-written wrapper for AMD (which I updated to ES6) or had UMD which created problems when importing the same code in both Node and the browser. I basically had to update the wrapper of every third-party library to fix these problems. In some cases I updated the library version itself (Autolinker, topojson). Nothing to be too concerned about, but future clean-up would be using npm versions of these libraries and auto-generating the wrappers as needed so we don't hand-edit things. Sandcastle Sandcastle is eternal and manages to live another day in it's ancient requirejs/dojo 1.x form. Sandcastle now automatically uses the ES6 version of Cesium if it is available and fallsback to the ES5 unminified version if it is now. The built version of Sandcastle always uses CesiumUnminified, just like master. This means Sandcastle still works in IE11 if you run the combine step first (or use the relase zip) Removed Cesium usage from Sandcastle proper, since it wasn't really needed Generate a VERSION propertyin the gallery index since Cesium is no longer being included. Remove requirejs from Sandcastle bucket Update bucket to use the built version of Cesium if it is available by fallbackto the ES6 version during development. Standalone.html was also updated There's a bit of room for further clean-up here, but I think this gets us into master. I did not rename bucket-requirejs.html because I'm pretty sure it would break previously shared demos. We can put in some backwards compatible code later on if we want. (But I'd rather just see a full Sandcastle rewrite). Specs Specs are now all ES6, except for TestWorkers, which remain standard JS worker modules. This means you can no longer run the unbuilt unit tests in IE11. No changes for Chrome and Firefox. Since the specs use ES6 modules and built Cesium is an ES5 UMD, I added a build-specs build step which generates a combined ES5 version of the specs which rely on Cesium as a global variable. We then inject these files into jasmine instead of the standard specs and everything works exactly as it did before. SpecRunner.html has been updated to inject the correct version of the script depending on the build/release query parameters. The Specs must always use Cesium by importing Source/Cesium.js, this is so we can replace it with the built Cesium as describe above. There's a bunch of room for clean-up here, such as unifying our two copies of jasmine into a single helper file, but I didn't want to start doing that clean-up as part of this already overly big PR. The important thing is that we can still test the built version and still test on IE/Edge as needed. I also found and fixed two bugs that were causing failing unit tests, one in BingMapsImageryProviderSpec.js (which was overwriting createImage andnot setting it back) and ShadowVolumeAppearance.js (which had a module level caching bug). I think these may have been the cause of random CI failures in master as well, but only time will tell. For coverage, we had to switch to karma-coverage-istanbul-instrumenter for native ES6 support, but that's it. Finally, I updated appveryor to build Cesium and run the built tests under IE. We still don't fail the build for IE, but we should probably fix that if we want to keep it going. NodeJS When NODE_ENV is production, we now require in the minified CesiumJS directly, which works great because it's now a UMD module. Otherwise, we use the excellant esmpackage to load individual modules, it was a fairly straightforward swap from our old requirejs usage. We could probably drop esm too if we don't care about debugging or if we provie source maps at some point.
2019-10-03 23:51:23 +08:00
export default PointPrimitiveCollection;