├── .gitignore ├── plugin ├── version.properties ├── icon.png └── plugin.xml ├── apps ├── duplex.bin ├── static.js ├── tests.html ├── static.html ├── minimal.html ├── address.js ├── dev.html ├── interactive.html ├── api.html ├── minimal.js └── credentials.js ├── img ├── black_arrow.png ├── blue_arrow.png ├── application_home.png ├── black_arrow_down.png └── blue_arrow_down.png ├── docs ├── classdiagram.png └── index.html ├── viewer ├── cesium │ ├── ThirdParty │ │ ├── draco_decoder.wasm │ │ ├── GltfPipeline │ │ │ ├── hasExtension.js │ │ │ ├── addExtensionsUsed.js │ │ │ ├── numberOfComponentsForType.js │ │ │ ├── removeExtensionsRequired.js │ │ │ ├── addToArray.js │ │ │ ├── addExtensionsRequired.js │ │ │ ├── addBuffer.js │ │ │ ├── removeExtensionsUsed.js │ │ │ ├── getAccessorByteStride.js │ │ │ ├── addPipelineExtras.js │ │ │ ├── removePipelineExtras.js │ │ │ ├── readAccessorPacked.js │ │ │ └── updateAccessorComponentTypes.js │ │ └── quickselect.js │ └── Core │ │ ├── isBitSet.js │ │ ├── GeometryType.js │ │ ├── TileEdge.js │ │ ├── appendForwardSlash.js │ │ ├── GeometryOffsetAttribute.js │ │ ├── getMagic.js │ │ ├── defined.js │ │ ├── ReferenceFrame.js │ │ ├── HeightmapEncoding.js │ │ ├── TerrainQuantization.js │ │ ├── isBlobUri.js │ │ ├── isDataUri.js │ │ ├── Proxy.js │ │ ├── GeocodeType.js │ │ ├── ArcType.js │ │ ├── Iau2006XysSample.js │ │ ├── Interval.js │ │ ├── loadAndExecuteScript.js │ │ ├── RequestType.js │ │ ├── isLeapYear.js │ │ ├── KeyboardEventModifier.js │ │ ├── ExtrapolationType.js │ │ ├── GeometryFactory.js │ │ ├── createGuid.js │ │ ├── webGLConstantToGlslType.js │ │ ├── DefaultProxy.js │ │ ├── formatError.js │ │ ├── defaultValue.js │ │ ├── getTimestamp.js │ │ ├── WindingOrder.js │ │ ├── wrapFunction.js │ │ ├── TimeStandard.js │ │ ├── isCrossOriginUrl.js │ │ ├── LeapSecond.js │ │ ├── Visibility.js │ │ ├── clone.js │ │ ├── PolygonHierarchy.js │ │ ├── Intersect.js │ │ ├── GeocoderService.js │ │ ├── ClockStep.js │ │ ├── getFilenameFromUri.js │ │ ├── RequestState.js │ │ ├── CornerType.js │ │ ├── ClockRange.js │ │ ├── subdivideArray.js │ │ ├── getExtensionFromUri.js │ │ ├── pointInsideTriangle.js │ │ ├── arraySlice.js │ │ ├── parseResponseHeaders.js │ │ ├── Packable.js │ │ ├── getBaseUri.js │ │ ├── getImagePixels.js │ │ ├── getAbsoluteUri.js │ │ ├── IauOrientationParameters.js │ │ ├── Iso8601.js │ │ ├── arrayFill.js │ │ ├── CylinderGeometryLibrary.js │ │ ├── EarthOrientationParametersSample.js │ │ ├── cancelAnimationFrame.js │ │ ├── loadImageFromTypedArray.js │ │ ├── createWorldTerrain.js │ │ ├── objectToQuery.js │ │ ├── RuntimeError.js │ │ ├── queryToObject.js │ │ ├── PackableForInterpolation.js │ │ ├── destroyObject.js │ │ ├── Ion.js │ │ ├── deprecationWarning.js │ │ ├── TimeConstants.js │ │ ├── RequestErrorEvent.js │ │ ├── oneTimeWarning.js │ │ ├── CartographicGeocoderService.js │ │ ├── DeveloperError.js │ │ ├── HeadingPitchRange.js │ │ ├── IonGeocoderService.js │ │ ├── binarySearch.js │ │ ├── MapProjection.js │ │ ├── GeometryAttributes.js │ │ ├── EventHelper.js │ │ ├── GregorianDate.js │ │ ├── combine.js │ │ ├── TranslationRotationScale.js │ │ ├── LagrangePolynomialApproximation.js │ │ ├── PrimitiveType.js │ │ ├── CompressedTextureBuffer.js │ │ ├── ScreenSpaceEventType.js │ │ ├── requestAnimationFrame.js │ │ ├── Ray.js │ │ ├── DoublyLinkedList.js │ │ ├── LinearApproximation.js │ │ ├── RectangleCollisionChecker.js │ │ └── decodeGoogleEarthEnterpriseData.js ├── glmatrix │ ├── index.js │ └── common.js ├── buffermanagerpercolor.js ├── frustumplane.js ├── eventhandler.js ├── lineboxgeometry.js ├── treemodel.js ├── sectionplaneset.js ├── bufferset.js ├── treeview.js ├── perspective.js ├── bufferhelper.js ├── buffermanagertransparencyonly.js ├── projecttreemodel.js ├── bimservergeometryloader.js ├── animatedvec3.js ├── freezableset.js ├── executor.js ├── buffersetpool.js ├── lighting.js ├── frustum.js └── projection.js ├── .esdoc.json ├── css ├── tests.css ├── dev.css ├── index.css ├── interactive.css ├── apiref.css └── apps.css ├── .project ├── Gruntfile.js ├── LICENSE ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /plugin/version.properties: -------------------------------------------------------------------------------- 1 | build.date=${timestamp} -------------------------------------------------------------------------------- /apps/duplex.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/apps/duplex.bin -------------------------------------------------------------------------------- /plugin/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/plugin/icon.png -------------------------------------------------------------------------------- /img/black_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/img/black_arrow.png -------------------------------------------------------------------------------- /img/blue_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/img/blue_arrow.png -------------------------------------------------------------------------------- /docs/classdiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/docs/classdiagram.png -------------------------------------------------------------------------------- /img/application_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/img/application_home.png -------------------------------------------------------------------------------- /img/black_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/img/black_arrow_down.png -------------------------------------------------------------------------------- /img/blue_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/img/blue_arrow_down.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | You are viewing a non-built version of BIMsurfer 3, the API docs need to be generated so there is nothing here. -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/draco_decoder.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensourceBIM/BIMsurfer/HEAD/viewer/cesium/ThirdParty/draco_decoder.wasm -------------------------------------------------------------------------------- /.esdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": "./viewer", 3 | "destination": "./docs", 4 | "excludes": ["cesium"], 5 | "plugins": [{"name": "esdoc-standard-plugin"}] 6 | } 7 | -------------------------------------------------------------------------------- /viewer/cesium/Core/isBitSet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @private 3 | */ 4 | function isBitSet(bits, mask) { 5 | return (bits & mask) !== 0; 6 | } 7 | export default isBitSet; 8 | -------------------------------------------------------------------------------- /css/tests.css: -------------------------------------------------------------------------------- 1 | #tests { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 4 | } 5 | 6 | .viewer { 7 | border: 1px solid black; 8 | margin: 5px; 9 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/GeometryType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @private 3 | */ 4 | var GeometryType = { 5 | NONE: 0, 6 | TRIANGLES: 1, 7 | LINES: 2, 8 | POLYLINES: 3, 9 | }; 10 | export default Object.freeze(GeometryType); 11 | -------------------------------------------------------------------------------- /plugin/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | bimsurfer3 5 | BIMsurfer 3 6 | BIMsurfer 3 7 | 8 | -------------------------------------------------------------------------------- /viewer/cesium/Core/TileEdge.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @private 3 | */ 4 | var TileEdge = { 5 | WEST: 0, 6 | NORTH: 1, 7 | EAST: 2, 8 | SOUTH: 3, 9 | NORTHWEST: 4, 10 | NORTHEAST: 5, 11 | SOUTHWEST: 6, 12 | SOUTHEAST: 7, 13 | }; 14 | export default TileEdge; 15 | -------------------------------------------------------------------------------- /viewer/cesium/Core/appendForwardSlash.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @private 3 | */ 4 | function appendForwardSlash(url) { 5 | if (url.length === 0 || url[url.length - 1] !== "/") { 6 | url = url + "/"; 7 | } 8 | return url; 9 | } 10 | export default appendForwardSlash; 11 | -------------------------------------------------------------------------------- /viewer/cesium/Core/GeometryOffsetAttribute.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents which vertices should have a value of `true` for the `applyOffset` attribute 3 | * @private 4 | */ 5 | var GeometryOffsetAttribute = { 6 | NONE: 0, 7 | TOP: 1, 8 | ALL: 2, 9 | }; 10 | export default Object.freeze(GeometryOffsetAttribute); 11 | -------------------------------------------------------------------------------- /apps/static.js: -------------------------------------------------------------------------------- 1 | import {BimServerViewer} from "../viewer/bimserverviewer.js" 2 | 3 | export function displayStaticBuffer(domNode, bufferPath) { 4 | var canvas = document.getElementById(domNode); 5 | let v = new BimServerViewer({quantizeVertices:false}, canvas, window.innerWidth, window.innerHeight, null); 6 | v.loadAnnotationsFromPreparedBufferUrl(bufferPath); 7 | } 8 | -------------------------------------------------------------------------------- /css/dev.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; 3 | font-size: 14px; 4 | } 5 | 6 | #projectsWrapper { 7 | overflow-y: scroll; 8 | height: 100vh; 9 | } 10 | 11 | #projects { 12 | border-radius: 5px; 13 | padding: 5px; 14 | margin: 10px; 15 | background: rgba(200, 200, 255, 0.2); 16 | width: 20%; 17 | } -------------------------------------------------------------------------------- /apps/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BIMsurfer Developer Mode 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /viewer/cesium/Core/getMagic.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | import getStringFromTypedArray from "./getStringFromTypedArray.js"; 3 | 4 | /** 5 | * @private 6 | */ 7 | function getMagic(uint8Array, byteOffset) { 8 | byteOffset = defaultValue(byteOffset, 0); 9 | return getStringFromTypedArray( 10 | uint8Array, 11 | byteOffset, 12 | Math.min(4, uint8Array.length) 13 | ); 14 | } 15 | export default getMagic; 16 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | BIMsurfer3 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.validation.validationbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.wst.jsdt.core.jsNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /viewer/cesium/Core/defined.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @function 3 | * 4 | * @param {*} value The object. 5 | * @returns {Boolean} Returns true if the object is defined, returns false otherwise. 6 | * 7 | * @example 8 | * if (Cesium.defined(positions)) { 9 | * doSomething(); 10 | * } else { 11 | * doSomethingElse(); 12 | * } 13 | */ 14 | function defined(value) { 15 | return value !== undefined && value !== null; 16 | } 17 | export default defined; 18 | -------------------------------------------------------------------------------- /viewer/cesium/Core/ReferenceFrame.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants for identifying well-known reference frames. 3 | * 4 | * @enum {Number} 5 | */ 6 | var ReferenceFrame = { 7 | /** 8 | * The fixed frame. 9 | * 10 | * @type {Number} 11 | * @constant 12 | */ 13 | FIXED: 0, 14 | 15 | /** 16 | * The inertial frame. 17 | * 18 | * @type {Number} 19 | * @constant 20 | */ 21 | INERTIAL: 1, 22 | }; 23 | export default Object.freeze(ReferenceFrame); 24 | -------------------------------------------------------------------------------- /css/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; 3 | } 4 | 5 | .wrapper { 6 | display: grid; 7 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 8 | } 9 | 10 | .mode { 11 | margin: 20px; 12 | } 13 | 14 | .viewer { 15 | width: 320px; 16 | height: 240px; 17 | } 18 | 19 | .hidden { 20 | display: none 21 | } 22 | 23 | .mode { 24 | background: #DDDDDD; 25 | padding: 10px; 26 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/HeightmapEncoding.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The encoding that is used for a heightmap 3 | * 4 | * @enum {Number} 5 | */ 6 | var HeightmapEncoding = { 7 | /** 8 | * No encoding 9 | * 10 | * @type {Number} 11 | * @constant 12 | */ 13 | NONE: 0, 14 | 15 | /** 16 | * LERC encoding 17 | * 18 | * @type {Number} 19 | * @constant 20 | * 21 | * @see {@link https://github.com/Esri/lerc|The LERC specification} 22 | */ 23 | LERC: 1, 24 | }; 25 | export default Object.freeze(HeightmapEncoding); 26 | -------------------------------------------------------------------------------- /viewer/glmatrix/index.js: -------------------------------------------------------------------------------- 1 | import * as glMatrix from "./common.js"; 2 | import * as mat2 from "./mat2.js"; 3 | import * as mat2d from "./mat2d.js"; 4 | import * as mat3 from "./mat3.js"; 5 | import * as mat4 from "./mat4.js"; 6 | import * as quat from "./quat.js"; 7 | import * as quat2 from "./quat2.js"; 8 | import * as vec2 from "./vec2.js"; 9 | import * as vec3 from "./vec3.js"; 10 | import * as vec4 from "./vec4.js"; 11 | 12 | export { 13 | glMatrix, 14 | mat2, mat2d, mat3, mat4, 15 | quat, quat2, 16 | vec2, vec3, vec4, 17 | }; 18 | -------------------------------------------------------------------------------- /apps/static.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BIMsurfer Minimial Demo 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.initConfig({ 3 | browserify: { 4 | development: { 5 | src: [ 6 | "./viewer/**/*.js", 7 | ], 8 | dest: './dist/js/bimsurfer3.js', 9 | options: { 10 | browserifyOptions: { debug: true }, 11 | transform: [["babelify", { "presets": ["@babel/preset-env"] }]] 12 | } 13 | } 14 | } 15 | }); 16 | grunt.loadNpmTasks('grunt-browserify'); 17 | }; 18 | -------------------------------------------------------------------------------- /viewer/cesium/Core/TerrainQuantization.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This enumerated type is used to determine how the vertices of the terrain mesh are compressed. 3 | * 4 | * @enum {Number} 5 | * 6 | * @private 7 | */ 8 | var TerrainQuantization = { 9 | /** 10 | * The vertices are not compressed. 11 | * 12 | * @type {Number} 13 | * @constant 14 | */ 15 | NONE: 0, 16 | 17 | /** 18 | * The vertices are compressed to 12 bits. 19 | * 20 | * @type {Number} 21 | * @constant 22 | */ 23 | BITS12: 1, 24 | }; 25 | export default Object.freeze(TerrainQuantization); 26 | -------------------------------------------------------------------------------- /apps/minimal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BIMsurfer Minimial Demo 6 | 7 | 8 | 9 | 10 |
11 | See JavaScript Console for errors 12 | 13 |
14 |
15 |
16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /viewer/cesium/Core/isBlobUri.js: -------------------------------------------------------------------------------- 1 | import Check from "./Check.js"; 2 | 3 | var blobUriRegex = /^blob:/i; 4 | 5 | /** 6 | * Determines if the specified uri is a blob uri. 7 | * 8 | * @function isBlobUri 9 | * 10 | * @param {String} uri The uri to test. 11 | * @returns {Boolean} true when the uri is a blob uri; otherwise, false. 12 | * 13 | * @private 14 | */ 15 | function isBlobUri(uri) { 16 | //>>includeStart('debug', pragmas.debug); 17 | Check.typeOf.string("uri", uri); 18 | //>>includeEnd('debug'); 19 | 20 | return blobUriRegex.test(uri); 21 | } 22 | export default isBlobUri; 23 | -------------------------------------------------------------------------------- /viewer/cesium/Core/isDataUri.js: -------------------------------------------------------------------------------- 1 | import Check from "./Check.js"; 2 | 3 | var dataUriRegex = /^data:/i; 4 | 5 | /** 6 | * Determines if the specified uri is a data uri. 7 | * 8 | * @function isDataUri 9 | * 10 | * @param {String} uri The uri to test. 11 | * @returns {Boolean} true when the uri is a data uri; otherwise, false. 12 | * 13 | * @private 14 | */ 15 | function isDataUri(uri) { 16 | //>>includeStart('debug', pragmas.debug); 17 | Check.typeOf.string("uri", uri); 18 | //>>includeEnd('debug'); 19 | 20 | return dataUriRegex.test(uri); 21 | } 22 | export default isDataUri; 23 | -------------------------------------------------------------------------------- /viewer/cesium/Core/Proxy.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "./DeveloperError.js"; 2 | 3 | /** 4 | * Base class for proxying requested made by {@link Resource}. 5 | * 6 | * @alias Proxy 7 | * @constructor 8 | * 9 | * @see DefaultProxy 10 | */ 11 | function Proxy() { 12 | DeveloperError.throwInstantiationError(); 13 | } 14 | 15 | /** 16 | * Get the final URL to use to request a given resource. 17 | * 18 | * @param {String} resource The resource to request. 19 | * @returns {String} proxied resource 20 | * @function 21 | */ 22 | Proxy.prototype.getURL = DeveloperError.throwInstantiationError; 23 | 24 | export default Proxy; 25 | -------------------------------------------------------------------------------- /viewer/cesium/Core/GeocodeType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The type of geocoding to be performed by a {@link GeocoderService}. 3 | * @enum {Number} 4 | * @see Geocoder 5 | */ 6 | var GeocodeType = { 7 | /** 8 | * Perform a search where the input is considered complete. 9 | * 10 | * @type {Number} 11 | * @constant 12 | */ 13 | SEARCH: 0, 14 | 15 | /** 16 | * Perform an auto-complete using partial input, typically 17 | * reserved for providing possible results as a user is typing. 18 | * 19 | * @type {Number} 20 | * @constant 21 | */ 22 | AUTOCOMPLETE: 1, 23 | }; 24 | export default Object.freeze(GeocodeType); 25 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/hasExtension.js: -------------------------------------------------------------------------------- 1 | import defined from '../../Core/defined.js' 2 | 3 | /** 4 | * Checks whether the glTF has the given extension. 5 | * 6 | * @param {Object} gltf A javascript object containing a glTF asset. 7 | * @param {String} extension The name of the extension. 8 | * @returns {Boolean} Whether the glTF has the given extension. 9 | * 10 | * @private 11 | */ 12 | function hasExtension(gltf, extension) { 13 | return defined(gltf.extensionsUsed) && (gltf.extensionsUsed.indexOf(extension) >= 0); 14 | } 15 | 16 | export default hasExtension; 17 | -------------------------------------------------------------------------------- /viewer/cesium/Core/ArcType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ArcType defines the path that should be taken connecting vertices. 3 | * 4 | * @enum {Number} 5 | */ 6 | var ArcType = { 7 | /** 8 | * Straight line that does not conform to the surface of the ellipsoid. 9 | * 10 | * @type {Number} 11 | * @constant 12 | */ 13 | NONE: 0, 14 | 15 | /** 16 | * Follow geodesic path. 17 | * 18 | * @type {Number} 19 | * @constant 20 | */ 21 | GEODESIC: 1, 22 | 23 | /** 24 | * Follow rhumb or loxodrome path. 25 | * 26 | * @type {Number} 27 | * @constant 28 | */ 29 | RHUMB: 2, 30 | }; 31 | export default Object.freeze(ArcType); 32 | -------------------------------------------------------------------------------- /viewer/cesium/Core/Iau2006XysSample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * An IAU 2006 XYS value sampled at a particular time. 3 | * 4 | * @alias Iau2006XysSample 5 | * @constructor 6 | * 7 | * @param {Number} x The X value. 8 | * @param {Number} y The Y value. 9 | * @param {Number} s The S value. 10 | * 11 | * @private 12 | */ 13 | function Iau2006XysSample(x, y, s) { 14 | /** 15 | * The X value. 16 | * @type {Number} 17 | */ 18 | this.x = x; 19 | 20 | /** 21 | * The Y value. 22 | * @type {Number} 23 | */ 24 | this.y = y; 25 | 26 | /** 27 | * The S value. 28 | * @type {Number} 29 | */ 30 | this.s = s; 31 | } 32 | export default Iau2006XysSample; 33 | -------------------------------------------------------------------------------- /viewer/cesium/Core/Interval.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | 3 | /** 4 | * Represents the closed interval [start, stop]. 5 | * @alias Interval 6 | * @constructor 7 | * 8 | * @param {Number} [start=0.0] The beginning of the interval. 9 | * @param {Number} [stop=0.0] The end of the interval. 10 | */ 11 | function Interval(start, stop) { 12 | /** 13 | * The beginning of the interval. 14 | * @type {Number} 15 | * @default 0.0 16 | */ 17 | this.start = defaultValue(start, 0.0); 18 | /** 19 | * The end of the interval. 20 | * @type {Number} 21 | * @default 0.0 22 | */ 23 | this.stop = defaultValue(stop, 0.0); 24 | } 25 | export default Interval; 26 | -------------------------------------------------------------------------------- /viewer/cesium/Core/loadAndExecuteScript.js: -------------------------------------------------------------------------------- 1 | import when from "../ThirdParty/when.js"; 2 | 3 | /** 4 | * @private 5 | */ 6 | function loadAndExecuteScript(url) { 7 | var deferred = when.defer(); 8 | var script = document.createElement("script"); 9 | script.async = true; 10 | script.src = url; 11 | 12 | var head = document.getElementsByTagName("head")[0]; 13 | script.onload = function () { 14 | script.onload = undefined; 15 | head.removeChild(script); 16 | deferred.resolve(); 17 | }; 18 | script.onerror = function (e) { 19 | deferred.reject(e); 20 | }; 21 | 22 | head.appendChild(script); 23 | 24 | return deferred.promise; 25 | } 26 | export default loadAndExecuteScript; 27 | -------------------------------------------------------------------------------- /viewer/buffermanagerpercolor.js: -------------------------------------------------------------------------------- 1 | import {BufferManager} from "./buffermanager.js"; 2 | 3 | /** 4 | * Buffer manager that keeps track of one buffer per color. This buffer is used when useObjectColor is on. 5 | */ 6 | export class BufferManagerPerColor extends BufferManager { 7 | constructor(viewer, settings, renderer, bufferSetPool) { 8 | super(viewer, settings, renderer, bufferSetPool); 9 | } 10 | 11 | /* 12 | * The key here is a hash of the color 13 | * TODO: JSON.stringify is a bit slow for this, need to look for a consistent hashing algo for 4 floats... 14 | */ 15 | getKey(transparency, color, sizes) { 16 | // return color.r + color.g + color.b + color.a; 17 | return JSON.stringify(color); 18 | } 19 | } -------------------------------------------------------------------------------- /css/interactive.css: -------------------------------------------------------------------------------- 1 | body.interactive { 2 | margin: 10px; 3 | padding: 10px; 4 | height: 100%; 5 | } 6 | 7 | .serverstatus { 8 | width: 100px; 9 | padding: 5px; 10 | } 11 | 12 | #serverList { 13 | display: flex; 14 | flex-direction: row; 15 | } 16 | 17 | .server { 18 | width: 300px; 19 | } 20 | 21 | .serverstatus.up { 22 | background: green; 23 | } 24 | 25 | .serverstatus.down { 26 | background: red; 27 | } 28 | 29 | .server { 30 | background-color: #EEEEFF; 31 | padding: 10px; 32 | margin: 10px; 33 | } 34 | 35 | #tabs .tab { 36 | background-color: #EEEEEE; 37 | display: inline; 38 | cursor: pointer; 39 | } 40 | 41 | #tabs .tab.active { 42 | background-color: #FFFFFF; 43 | } 44 | 45 | .revision { 46 | cursor: pointer; 47 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/RequestType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * An enum identifying the type of request. Used for finer grained logging and priority sorting. 3 | * 4 | * @enum {Number} 5 | */ 6 | var RequestType = { 7 | /** 8 | * Terrain request. 9 | * 10 | * @type Number 11 | * @constant 12 | */ 13 | TERRAIN: 0, 14 | 15 | /** 16 | * Imagery request. 17 | * 18 | * @type Number 19 | * @constant 20 | */ 21 | IMAGERY: 1, 22 | 23 | /** 24 | * 3D Tiles request. 25 | * 26 | * @type Number 27 | * @constant 28 | */ 29 | TILES3D: 2, 30 | 31 | /** 32 | * Other request. 33 | * 34 | * @type Number 35 | * @constant 36 | */ 37 | OTHER: 3, 38 | }; 39 | export default Object.freeze(RequestType); 40 | -------------------------------------------------------------------------------- /viewer/cesium/Core/isLeapYear.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "./DeveloperError.js"; 2 | 3 | /** 4 | * Determines if a given date is a leap year. 5 | * 6 | * @function isLeapYear 7 | * 8 | * @param {Number} year The year to be tested. 9 | * @returns {Boolean} True if year is a leap year. 10 | * 11 | * @example 12 | * var leapYear = Cesium.isLeapYear(2000); // true 13 | */ 14 | function isLeapYear(year) { 15 | //>>includeStart('debug', pragmas.debug); 16 | if (year === null || isNaN(year)) { 17 | throw new DeveloperError("year is required and must be a number."); 18 | } 19 | //>>includeEnd('debug'); 20 | 21 | return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; 22 | } 23 | export default isLeapYear; 24 | -------------------------------------------------------------------------------- /apps/address.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class will return the API address for a BIMserver Client 3 | */ 4 | 5 | export class Address { 6 | static getApiAddress() { 7 | var pathname = document.location.pathname; 8 | if (pathname.length > 16 && pathname.indexOf("/apps/bimsurfer3/") != -1) { 9 | // We assume that BIMsurfer 3 is being served from a BIMserver and that this is also the BIMserver we would like to connect to 10 | const href = document.location.href; 11 | return href.substring(0, href.indexOf("/apps/bimsurfer3/")); 12 | } else { 13 | // Return a default 14 | console.log("Trying to connect to http://localhost:8082, because we don't know where to find BIMserver", document.location); 15 | return "http://localhost:8082"; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/KeyboardEventModifier.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This enumerated type is for representing keyboard modifiers. These are keys 3 | * that are held down in addition to other event types. 4 | * 5 | * @enum {Number} 6 | */ 7 | var KeyboardEventModifier = { 8 | /** 9 | * Represents the shift key being held down. 10 | * 11 | * @type {Number} 12 | * @constant 13 | */ 14 | SHIFT: 0, 15 | 16 | /** 17 | * Represents the control key being held down. 18 | * 19 | * @type {Number} 20 | * @constant 21 | */ 22 | CTRL: 1, 23 | 24 | /** 25 | * Represents the alt key being held down. 26 | * 27 | * @type {Number} 28 | * @constant 29 | */ 30 | ALT: 2, 31 | }; 32 | export default Object.freeze(KeyboardEventModifier); 33 | -------------------------------------------------------------------------------- /viewer/cesium/Core/ExtrapolationType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants to determine how an interpolated value is extrapolated 3 | * when querying outside the bounds of available data. 4 | * 5 | * @enum {Number} 6 | * 7 | * @see SampledProperty 8 | */ 9 | var ExtrapolationType = { 10 | /** 11 | * No extrapolation occurs. 12 | * 13 | * @type {Number} 14 | * @constant 15 | */ 16 | NONE: 0, 17 | 18 | /** 19 | * The first or last value is used when outside the range of sample data. 20 | * 21 | * @type {Number} 22 | * @constant 23 | */ 24 | HOLD: 1, 25 | 26 | /** 27 | * The value is extrapolated. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | EXTRAPOLATE: 2, 33 | }; 34 | export default Object.freeze(ExtrapolationType); 35 | -------------------------------------------------------------------------------- /viewer/cesium/Core/GeometryFactory.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "../Core/DeveloperError.js"; 2 | 3 | /** 4 | * Base class for all geometry creation utility classes that can be passed to {@link GeometryInstance} 5 | * for asynchronous geometry creation. 6 | * 7 | * @constructor 8 | * @class 9 | * @abstract 10 | */ 11 | function GeometryFactory() { 12 | DeveloperError.throwInstantiationError(); 13 | } 14 | 15 | /** 16 | * Returns a geometry. 17 | * 18 | * @param {GeometryFactory} geometryFactory A description of the circle. 19 | * @returns {Geometry|undefined} The computed vertices and indices. 20 | */ 21 | GeometryFactory.createGeometry = function (geometryFactory) { 22 | DeveloperError.throwInstantiationError(); 23 | }; 24 | 25 | export default GeometryFactory; 26 | -------------------------------------------------------------------------------- /viewer/cesium/Core/createGuid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creates a Globally unique identifier (GUID) string. A GUID is 128 bits long, and can guarantee uniqueness across space and time. 3 | * 4 | * @function 5 | * 6 | * @returns {String} 7 | * 8 | * 9 | * @example 10 | * this.guid = Cesium.createGuid(); 11 | * 12 | * @see {@link http://www.ietf.org/rfc/rfc4122.txt|RFC 4122 A Universally Unique IDentifier (UUID) URN Namespace} 13 | */ 14 | function createGuid() { 15 | // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript 16 | return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) { 17 | var r = (Math.random() * 16) | 0; 18 | var v = c === "x" ? r : (r & 0x3) | 0x8; 19 | return v.toString(16); 20 | }); 21 | } 22 | export default createGuid; 23 | -------------------------------------------------------------------------------- /viewer/cesium/Core/webGLConstantToGlslType.js: -------------------------------------------------------------------------------- 1 | import WebGLConstants from "./WebGLConstants.js"; 2 | 3 | function webGLConstantToGlslType(webGLValue) { 4 | switch (webGLValue) { 5 | case WebGLConstants.FLOAT: 6 | return "float"; 7 | case WebGLConstants.FLOAT_VEC2: 8 | return "vec2"; 9 | case WebGLConstants.FLOAT_VEC3: 10 | return "vec3"; 11 | case WebGLConstants.FLOAT_VEC4: 12 | return "vec4"; 13 | case WebGLConstants.FLOAT_MAT2: 14 | return "mat2"; 15 | case WebGLConstants.FLOAT_MAT3: 16 | return "mat3"; 17 | case WebGLConstants.FLOAT_MAT4: 18 | return "mat4"; 19 | case WebGLConstants.SAMPLER_2D: 20 | return "sampler2D"; 21 | case WebGLConstants.BOOL: 22 | return "bool"; 23 | } 24 | } 25 | export default webGLConstantToGlslType; 26 | -------------------------------------------------------------------------------- /viewer/cesium/Core/DefaultProxy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple proxy that appends the desired resource as the sole query parameter 3 | * to the given proxy URL. 4 | * 5 | * @alias DefaultProxy 6 | * @constructor 7 | * @extends {Proxy} 8 | * 9 | * @param {String} proxy The proxy URL that will be used to requests all resources. 10 | */ 11 | function DefaultProxy(proxy) { 12 | this.proxy = proxy; 13 | } 14 | 15 | /** 16 | * Get the final URL to use to request a given resource. 17 | * 18 | * @param {String} resource The resource to request. 19 | * @returns {String} proxied resource 20 | */ 21 | DefaultProxy.prototype.getURL = function (resource) { 22 | var prefix = this.proxy.indexOf("?") === -1 ? "?" : ""; 23 | return this.proxy + prefix + encodeURIComponent(resource); 24 | }; 25 | 26 | export default DefaultProxy; 27 | -------------------------------------------------------------------------------- /viewer/cesium/Core/formatError.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | /** 4 | * Formats an error object into a String. If available, uses name, message, and stack 5 | * properties, otherwise, falls back on toString(). 6 | * 7 | * @function 8 | * 9 | * @param {*} object The item to find in the array. 10 | * @returns {String} A string containing the formatted error. 11 | */ 12 | function formatError(object) { 13 | var result; 14 | 15 | var name = object.name; 16 | var message = object.message; 17 | if (defined(name) && defined(message)) { 18 | result = name + ": " + message; 19 | } else { 20 | result = object.toString(); 21 | } 22 | 23 | var stack = object.stack; 24 | if (defined(stack)) { 25 | result += "\n" + stack; 26 | } 27 | 28 | return result; 29 | } 30 | export default formatError; 31 | -------------------------------------------------------------------------------- /viewer/cesium/Core/defaultValue.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the first parameter if not undefined, otherwise the second parameter. 3 | * Useful for setting a default value for a parameter. 4 | * 5 | * @function 6 | * 7 | * @param {*} a 8 | * @param {*} b 9 | * @returns {*} Returns the first parameter if not undefined, otherwise the second parameter. 10 | * 11 | * @example 12 | * param = Cesium.defaultValue(param, 'default'); 13 | */ 14 | function defaultValue(a, b) { 15 | if (a !== undefined && a !== null) { 16 | return a; 17 | } 18 | return b; 19 | } 20 | 21 | /** 22 | * A frozen empty object that can be used as the default value for options passed as 23 | * an object literal. 24 | * @type {Object} 25 | * @memberof defaultValue 26 | */ 27 | defaultValue.EMPTY_OBJECT = Object.freeze({}); 28 | 29 | export default defaultValue; 30 | -------------------------------------------------------------------------------- /viewer/cesium/Core/getTimestamp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gets a timestamp that can be used in measuring the time between events. Timestamps 3 | * are expressed in milliseconds, but it is not specified what the milliseconds are 4 | * measured from. This function uses performance.now() if it is available, or Date.now() 5 | * otherwise. 6 | * 7 | * @function getTimestamp 8 | * 9 | * @returns {Number} The timestamp in milliseconds since some unspecified reference time. 10 | */ 11 | var getTimestamp; 12 | 13 | if ( 14 | typeof performance !== "undefined" && 15 | typeof performance.now === "function" && 16 | isFinite(performance.now()) 17 | ) { 18 | getTimestamp = function () { 19 | return performance.now(); 20 | }; 21 | } else { 22 | getTimestamp = function () { 23 | return Date.now(); 24 | }; 25 | } 26 | export default getTimestamp; 27 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/addExtensionsUsed.js: -------------------------------------------------------------------------------- 1 | import addToArray from './addToArray.js' 2 | import defined from '../../Core/defined.js' 3 | 4 | /** 5 | * Adds an extension to gltf.extensionsUsed if it does not already exist. 6 | * Initializes extensionsUsed if it is not defined. 7 | * 8 | * @param {Object} gltf A javascript object containing a glTF asset. 9 | * @param {String} extension The extension to add. 10 | * 11 | * @private 12 | */ 13 | function addExtensionsUsed(gltf, extension) { 14 | var extensionsUsed = gltf.extensionsUsed; 15 | if (!defined(extensionsUsed)) { 16 | extensionsUsed = []; 17 | gltf.extensionsUsed = extensionsUsed; 18 | } 19 | addToArray(extensionsUsed, extension, true); 20 | } 21 | 22 | export default addExtensionsUsed; 23 | -------------------------------------------------------------------------------- /viewer/cesium/Core/WindingOrder.js: -------------------------------------------------------------------------------- 1 | import WebGLConstants from "./WebGLConstants.js"; 2 | 3 | /** 4 | * Winding order defines the order of vertices for a triangle to be considered front-facing. 5 | * 6 | * @enum {Number} 7 | */ 8 | var WindingOrder = { 9 | /** 10 | * Vertices are in clockwise order. 11 | * 12 | * @type {Number} 13 | * @constant 14 | */ 15 | CLOCKWISE: WebGLConstants.CW, 16 | 17 | /** 18 | * Vertices are in counter-clockwise order. 19 | * 20 | * @type {Number} 21 | * @constant 22 | */ 23 | COUNTER_CLOCKWISE: WebGLConstants.CCW, 24 | }; 25 | 26 | /** 27 | * @private 28 | */ 29 | WindingOrder.validate = function (windingOrder) { 30 | return ( 31 | windingOrder === WindingOrder.CLOCKWISE || 32 | windingOrder === WindingOrder.COUNTER_CLOCKWISE 33 | ); 34 | }; 35 | 36 | export default Object.freeze(WindingOrder); 37 | -------------------------------------------------------------------------------- /viewer/frustumplane.js: -------------------------------------------------------------------------------- 1 | import * as vec3 from "./glmatrix/vec3.js"; 2 | 3 | /** 4 | * @ignore 5 | */ 6 | export class FrustumPlane { 7 | 8 | constructor(nx = 0, ny = 0, nz = 1, offset = 1.0) { 9 | 10 | this.normal = vec3.create(); 11 | this.testVertex = vec3.create(); 12 | this.offset = 0; 13 | 14 | this.init(nx, ny, nz, offset); 15 | } 16 | 17 | init(nx = 0, ny = 0, nz = 1, offset = 1.0) { 18 | 19 | var s = 1.0 / Math.sqrt(nx * nx + ny * ny + nz * nz); 20 | 21 | this.normal[0] = nx * s; 22 | this.normal[1] = ny * s; 23 | this.normal[2] = nz * s; 24 | 25 | this.offset = offset * s; 26 | 27 | this.testVertex[0] = this.normal[0] >= 0.0 ? 1 : 0; 28 | this.testVertex[1] = this.normal[1] >= 0.0 ? 1 : 0; 29 | this.testVertex[2] = this.normal[2] >= 0.0 ? 1 : 0; 30 | } 31 | } -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/numberOfComponentsForType.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | /** 4 | * Utility function for retrieving the number of components in a given type. 5 | * 6 | * @param {String} type glTF type 7 | * @returns {Number} The number of components in that type. 8 | * 9 | * @private 10 | */ 11 | function numberOfComponentsForType(type) { 12 | switch (type) { 13 | case 'SCALAR': 14 | return 1; 15 | case 'VEC2': 16 | return 2; 17 | case 'VEC3': 18 | return 3; 19 | case 'VEC4': 20 | case 'MAT2': 21 | return 4; 22 | case 'MAT3': 23 | return 9; 24 | case 'MAT4': 25 | return 16; 26 | } 27 | } 28 | 29 | export default numberOfComponentsForType; 30 | -------------------------------------------------------------------------------- /viewer/cesium/Core/wrapFunction.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "./DeveloperError.js"; 2 | 3 | /** 4 | * Wraps a function on the provided objects with another function called in the 5 | * object's context so that the new function is always called immediately 6 | * before the old one. 7 | * 8 | * @private 9 | */ 10 | function wrapFunction(obj, oldFunction, newFunction) { 11 | //>>includeStart('debug', pragmas.debug); 12 | if (typeof oldFunction !== "function") { 13 | throw new DeveloperError("oldFunction is required to be a function."); 14 | } 15 | 16 | if (typeof newFunction !== "function") { 17 | throw new DeveloperError("oldFunction is required to be a function."); 18 | } 19 | //>>includeEnd('debug'); 20 | 21 | return function () { 22 | newFunction.apply(obj, arguments); 23 | oldFunction.apply(obj, arguments); 24 | }; 25 | } 26 | export default wrapFunction; 27 | -------------------------------------------------------------------------------- /viewer/cesium/Core/TimeStandard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Provides the type of time standards which JulianDate can take as input. 3 | * 4 | * @enum {Number} 5 | * 6 | * @see JulianDate 7 | */ 8 | var TimeStandard = { 9 | /** 10 | * Represents the coordinated Universal Time (UTC) time standard. 11 | * 12 | * UTC is related to TAI according to the relationship 13 | * UTC = TAI - deltaT where deltaT is the number of leap 14 | * seconds which have been introduced as of the time in TAI. 15 | * 16 | * @type {Number} 17 | * @constant 18 | */ 19 | UTC: 0, 20 | 21 | /** 22 | * Represents the International Atomic Time (TAI) time standard. 23 | * TAI is the principal time standard to which the other time standards are related. 24 | * 25 | * @type {Number} 26 | * @constant 27 | */ 28 | TAI: 1, 29 | }; 30 | export default Object.freeze(TimeStandard); 31 | -------------------------------------------------------------------------------- /viewer/cesium/Core/isCrossOriginUrl.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | var a; 4 | 5 | /** 6 | * Given a URL, determine whether that URL is considered cross-origin to the current page. 7 | * 8 | * @private 9 | */ 10 | function isCrossOriginUrl(url) { 11 | if (!defined(a)) { 12 | a = document.createElement("a"); 13 | } 14 | 15 | // copy window location into the anchor to get consistent results 16 | // when the port is default for the protocol (e.g. 80 for HTTP) 17 | a.href = window.location.href; 18 | 19 | // host includes both hostname and port if the port is not standard 20 | var host = a.host; 21 | var protocol = a.protocol; 22 | 23 | a.href = url; 24 | // IE only absolutizes href on get, not set 25 | // eslint-disable-next-line no-self-assign 26 | a.href = a.href; 27 | 28 | return protocol !== a.protocol || host !== a.host; 29 | } 30 | export default isCrossOriginUrl; 31 | -------------------------------------------------------------------------------- /viewer/cesium/Core/LeapSecond.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Describes a single leap second, which is constructed from a {@link JulianDate} and a 3 | * numerical offset representing the number of seconds TAI is ahead of the UTC time standard. 4 | * @alias LeapSecond 5 | * @constructor 6 | * 7 | * @param {JulianDate} [date] A Julian date representing the time of the leap second. 8 | * @param {Number} [offset] The cumulative number of seconds that TAI is ahead of UTC at the provided date. 9 | */ 10 | function LeapSecond(date, offset) { 11 | /** 12 | * Gets or sets the date at which this leap second occurs. 13 | * @type {JulianDate} 14 | */ 15 | this.julianDate = date; 16 | 17 | /** 18 | * Gets or sets the cumulative number of seconds between the UTC and TAI time standards at the time 19 | * of this leap second. 20 | * @type {Number} 21 | */ 22 | this.offset = offset; 23 | } 24 | export default LeapSecond; 25 | -------------------------------------------------------------------------------- /viewer/cesium/Core/Visibility.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This enumerated type is used in determining to what extent an object, the occludee, 3 | * is visible during horizon culling. An occluder may fully block an occludee, in which case 4 | * it has no visibility, may partially block an occludee from view, or may not block it at all, 5 | * leading to full visibility. 6 | * 7 | * @enum {Number} 8 | */ 9 | var Visibility = { 10 | /** 11 | * Represents that no part of an object is visible. 12 | * 13 | * @type {Number} 14 | * @constant 15 | */ 16 | NONE: -1, 17 | 18 | /** 19 | * Represents that part, but not all, of an object is visible 20 | * 21 | * @type {Number} 22 | * @constant 23 | */ 24 | PARTIAL: 0, 25 | 26 | /** 27 | * Represents that an object is visible in its entirety. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | FULL: 1, 33 | }; 34 | export default Object.freeze(Visibility); 35 | -------------------------------------------------------------------------------- /viewer/cesium/Core/clone.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | 3 | /** 4 | * Clones an object, returning a new object containing the same properties. 5 | * 6 | * @function 7 | * 8 | * @param {Object} object The object to clone. 9 | * @param {Boolean} [deep=false] If true, all properties will be deep cloned recursively. 10 | * @returns {Object} The cloned object. 11 | */ 12 | function clone(object, deep) { 13 | if (object === null || typeof object !== "object") { 14 | return object; 15 | } 16 | 17 | deep = defaultValue(deep, false); 18 | 19 | var result = new object.constructor(); 20 | for (var propertyName in object) { 21 | if (object.hasOwnProperty(propertyName)) { 22 | var value = object[propertyName]; 23 | if (deep) { 24 | value = clone(value, deep); 25 | } 26 | result[propertyName] = value; 27 | } 28 | } 29 | 30 | return result; 31 | } 32 | export default clone; 33 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/removeExtensionsRequired.js: -------------------------------------------------------------------------------- 1 | import defined from '../../Core/defined.js' 2 | 3 | /** 4 | * Removes an extension from gltf.extensionsRequired if it is present. 5 | * 6 | * @param {Object} gltf A javascript object containing a glTF asset. 7 | * @param {String} extension The extension to remove. 8 | * 9 | * @private 10 | */ 11 | function removeExtensionsRequired(gltf, extension) { 12 | var extensionsRequired = gltf.extensionsRequired; 13 | if (defined(extensionsRequired)) { 14 | var index = extensionsRequired.indexOf(extension); 15 | if (index >= 0) { 16 | extensionsRequired.splice(index, 1); 17 | } 18 | if (extensionsRequired.length === 0) { 19 | delete gltf.extensionsRequired; 20 | } 21 | } 22 | } 23 | 24 | export default removeExtensionsRequired; 25 | -------------------------------------------------------------------------------- /viewer/cesium/Core/PolygonHierarchy.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | /** 4 | * An hierarchy of linear rings which define a polygon and its holes. 5 | * The holes themselves may also have holes which nest inner polygons. 6 | * @alias PolygonHierarchy 7 | * @constructor 8 | * 9 | * @param {Cartesian3[]} [positions] A linear ring defining the outer boundary of the polygon or hole. 10 | * @param {PolygonHierarchy[]} [holes] An array of polygon hierarchies defining holes in the polygon. 11 | */ 12 | function PolygonHierarchy(positions, holes) { 13 | /** 14 | * A linear ring defining the outer boundary of the polygon or hole. 15 | * @type {Cartesian3[]} 16 | */ 17 | this.positions = defined(positions) ? positions : []; 18 | 19 | /** 20 | * An array of polygon hierarchies defining holes in the polygon. 21 | * @type {PolygonHierarchy[]} 22 | */ 23 | this.holes = defined(holes) ? holes : []; 24 | } 25 | export default PolygonHierarchy; 26 | -------------------------------------------------------------------------------- /viewer/cesium/Core/Intersect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This enumerated type is used in determining where, relative to the frustum, an 3 | * object is located. The object can either be fully contained within the frustum (INSIDE), 4 | * partially inside the frustum and partially outside (INTERSECTING), or somewhere entirely 5 | * outside of the frustum's 6 planes (OUTSIDE). 6 | * 7 | * @enum {Number} 8 | */ 9 | var Intersect = { 10 | /** 11 | * Represents that an object is not contained within the frustum. 12 | * 13 | * @type {Number} 14 | * @constant 15 | */ 16 | OUTSIDE: -1, 17 | 18 | /** 19 | * Represents that an object intersects one of the frustum's planes. 20 | * 21 | * @type {Number} 22 | * @constant 23 | */ 24 | INTERSECTING: 0, 25 | 26 | /** 27 | * Represents that an object is fully within the frustum. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | INSIDE: 1, 33 | }; 34 | export default Object.freeze(Intersect); 35 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/addToArray.js: -------------------------------------------------------------------------------- 1 | import defaultValue from '../../Core/defaultValue.js' 2 | 3 | /** 4 | * Adds an element to an array and returns the element's index. 5 | * 6 | * @param {Array} array The array to add to. 7 | * @param {Object} element The element to add. 8 | * @param {Boolean} [checkDuplicates=false] When true, if a duplicate element is found its index is returned and element is not added to the array. 9 | * 10 | * @private 11 | */ 12 | function addToArray(array, element, checkDuplicates) { 13 | checkDuplicates = defaultValue(checkDuplicates, false); 14 | if (checkDuplicates) { 15 | var index = array.indexOf(element); 16 | if (index > -1) { 17 | return index; 18 | } 19 | } 20 | 21 | array.push(element); 22 | return array.length - 1; 23 | } 24 | 25 | export default addToArray; 26 | -------------------------------------------------------------------------------- /viewer/eventhandler.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ignore 3 | */ 4 | export class EventHandler { 5 | constructor() { 6 | this.handlers = {}; 7 | } 8 | 9 | on(evt, handler) { 10 | (this.handlers[evt] || (this.handlers[evt] = [])).push(handler); 11 | } 12 | 13 | off(evt, handler) { 14 | var h = this.handlers[evt]; 15 | var found = false; 16 | if (typeof(h) !== 'undefined') { 17 | var i = h.indexOf(handler); 18 | if (i >= -1) { 19 | h.splice(i, 1); 20 | found = true; 21 | } 22 | } 23 | if (!found) { 24 | throw new Error("Handler not found"); 25 | } 26 | } 27 | 28 | fire(evt, ...args) { 29 | // console.log(evt, args); 30 | var h = this.handlers[evt]; 31 | if (!h) { 32 | return; 33 | } 34 | for (var i = 0; i < h.length; ++i) { 35 | h[i].apply(this, args); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/addExtensionsRequired.js: -------------------------------------------------------------------------------- 1 | import addExtensionsUsed from './addExtensionsUsed.js' 2 | import addToArray from './addToArray.js' 3 | import defined from '../../Core/defined.js' 4 | 5 | /** 6 | * Adds an extension to gltf.extensionsRequired if it does not already exist. 7 | * Initializes extensionsRequired if it is not defined. 8 | * 9 | * @param {Object} gltf A javascript object containing a glTF asset. 10 | * @param {String} extension The extension to add. 11 | * 12 | * @private 13 | */ 14 | function addExtensionsRequired(gltf, extension) { 15 | var extensionsRequired = gltf.extensionsRequired; 16 | if (!defined(extensionsRequired)) { 17 | extensionsRequired = []; 18 | gltf.extensionsRequired = extensionsRequired; 19 | } 20 | addToArray(extensionsRequired, extension, true); 21 | addExtensionsUsed(gltf, extension); 22 | } 23 | 24 | export default addExtensionsRequired; 25 | -------------------------------------------------------------------------------- /viewer/cesium/Core/GeocoderService.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "./DeveloperError.js"; 2 | 3 | /** 4 | * @typedef {Object} GeocoderService.Result 5 | * @property {String} displayName The display name for a location 6 | * @property {Rectangle|Cartesian3} destination The bounding box for a location 7 | */ 8 | 9 | /** 10 | * Provides geocoding through an external service. This type describes an interface and 11 | * is not intended to be used. 12 | * @alias GeocoderService 13 | * @constructor 14 | * 15 | * @see BingMapsGeocoderService 16 | * @see PeliasGeocoderService 17 | * @see OpenCageGeocoderService 18 | */ 19 | function GeocoderService() {} 20 | 21 | /** 22 | * @function 23 | * 24 | * @param {String} query The query to be sent to the geocoder service 25 | * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. 26 | * @returns {Promise} 27 | */ 28 | GeocoderService.prototype.geocode = DeveloperError.throwInstantiationError; 29 | export default GeocoderService; 30 | -------------------------------------------------------------------------------- /viewer/cesium/Core/ClockStep.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants to determine how much time advances with each call 3 | * to {@link Clock#tick}. 4 | * 5 | * @enum {Number} 6 | * 7 | * @see Clock 8 | * @see ClockRange 9 | */ 10 | var ClockStep = { 11 | /** 12 | * {@link Clock#tick} advances the current time by a fixed step, 13 | * which is the number of seconds specified by {@link Clock#multiplier}. 14 | * 15 | * @type {Number} 16 | * @constant 17 | */ 18 | TICK_DEPENDENT: 0, 19 | 20 | /** 21 | * {@link Clock#tick} advances the current time by the amount of system 22 | * time elapsed since the previous call multiplied by {@link Clock#multiplier}. 23 | * 24 | * @type {Number} 25 | * @constant 26 | */ 27 | SYSTEM_CLOCK_MULTIPLIER: 1, 28 | 29 | /** 30 | * {@link Clock#tick} sets the clock to the current system time; 31 | * ignoring all other settings. 32 | * 33 | * @type {Number} 34 | * @constant 35 | */ 36 | SYSTEM_CLOCK: 2, 37 | }; 38 | export default Object.freeze(ClockStep); 39 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/addBuffer.js: -------------------------------------------------------------------------------- 1 | import addToArray from './addToArray.js' 2 | 3 | /** 4 | * Adds buffer to gltf. 5 | * 6 | * @param {Object} gltf A javascript object containing a glTF asset. 7 | * @param {Buffer} buffer A Buffer object which will be added to gltf.buffers. 8 | * @returns {Number} The bufferView id of the newly added bufferView. 9 | * 10 | * @private 11 | */ 12 | function addBuffer(gltf, buffer) { 13 | var newBuffer = { 14 | byteLength: buffer.length, 15 | extras: { 16 | _pipeline: { 17 | source: buffer 18 | } 19 | } 20 | }; 21 | var bufferId = addToArray(gltf.buffers, newBuffer); 22 | var bufferView = { 23 | buffer: bufferId, 24 | byteOffset: 0, 25 | byteLength: buffer.length 26 | }; 27 | return addToArray(gltf.bufferViews, bufferView); 28 | } 29 | 30 | export default addBuffer; 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 TNO 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/removeExtensionsUsed.js: -------------------------------------------------------------------------------- 1 | import removeExtensionsRequired from './removeExtensionsRequired.js' 2 | import defined from '../../Core/defined.js' 3 | 4 | /** 5 | * Removes an extension from gltf.extensionsUsed and gltf.extensionsRequired if it is present. 6 | * 7 | * @param {Object} gltf A javascript object containing a glTF asset. 8 | * @param {String} extension The extension to remove. 9 | * 10 | * @private 11 | */ 12 | function removeExtensionsUsed(gltf, extension) { 13 | var extensionsUsed = gltf.extensionsUsed; 14 | if (defined(extensionsUsed)) { 15 | var index = extensionsUsed.indexOf(extension); 16 | if (index >= 0) { 17 | extensionsUsed.splice(index, 1); 18 | } 19 | removeExtensionsRequired(gltf, extension); 20 | if (extensionsUsed.length === 0) { 21 | delete gltf.extensionsUsed; 22 | } 23 | } 24 | } 25 | 26 | export default removeExtensionsUsed; 27 | -------------------------------------------------------------------------------- /viewer/cesium/Core/getFilenameFromUri.js: -------------------------------------------------------------------------------- 1 | import Uri from "../ThirdParty/Uri.js"; 2 | import defined from "./defined.js"; 3 | import DeveloperError from "./DeveloperError.js"; 4 | 5 | /** 6 | * Given a URI, returns the last segment of the URI, removing any path or query information. 7 | * @function getFilenameFromUri 8 | * 9 | * @param {String} uri The Uri. 10 | * @returns {String} The last segment of the Uri. 11 | * 12 | * @example 13 | * //fileName will be"simple.czml"; 14 | * var fileName = Cesium.getFilenameFromUri('/Gallery/simple.czml?value=true&example=false'); 15 | */ 16 | function getFilenameFromUri(uri) { 17 | //>>includeStart('debug', pragmas.debug); 18 | if (!defined(uri)) { 19 | throw new DeveloperError("uri is required."); 20 | } 21 | //>>includeEnd('debug'); 22 | 23 | var uriObject = new Uri(uri); 24 | uriObject.normalize(); 25 | var path = uriObject.path; 26 | var index = path.lastIndexOf("/"); 27 | if (index !== -1) { 28 | path = path.substr(index + 1); 29 | } 30 | return path; 31 | } 32 | export default getFilenameFromUri; 33 | -------------------------------------------------------------------------------- /viewer/cesium/Core/RequestState.js: -------------------------------------------------------------------------------- 1 | /** 2 | * State of the request. 3 | * 4 | * @enum {Number} 5 | */ 6 | var RequestState = { 7 | /** 8 | * Initial unissued state. 9 | * 10 | * @type Number 11 | * @constant 12 | */ 13 | UNISSUED: 0, 14 | 15 | /** 16 | * Issued but not yet active. Will become active when open slots are available. 17 | * 18 | * @type Number 19 | * @constant 20 | */ 21 | ISSUED: 1, 22 | 23 | /** 24 | * Actual http request has been sent. 25 | * 26 | * @type Number 27 | * @constant 28 | */ 29 | ACTIVE: 2, 30 | 31 | /** 32 | * Request completed successfully. 33 | * 34 | * @type Number 35 | * @constant 36 | */ 37 | RECEIVED: 3, 38 | 39 | /** 40 | * Request was cancelled, either explicitly or automatically because of low priority. 41 | * 42 | * @type Number 43 | * @constant 44 | */ 45 | CANCELLED: 4, 46 | 47 | /** 48 | * Request failed. 49 | * 50 | * @type Number 51 | * @constant 52 | */ 53 | FAILED: 5, 54 | }; 55 | export default Object.freeze(RequestState); 56 | -------------------------------------------------------------------------------- /viewer/cesium/Core/CornerType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Style options for corners. 3 | * 4 | * @demo The {@link https://sandcastle.cesium.com/index.html?src=Corridor.html&label=Geometries|Corridor Demo} 5 | * demonstrates the three corner types, as used by {@link CorridorGraphics}. 6 | * 7 | * @enum {Number} 8 | */ 9 | var CornerType = { 10 | /** 11 | * 12 | * 13 | * Corner has a smooth edge. 14 | * @type {Number} 15 | * @constant 16 | */ 17 | ROUNDED: 0, 18 | 19 | /** 20 | * 21 | * 22 | * Corner point is the intersection of adjacent edges. 23 | * @type {Number} 24 | * @constant 25 | */ 26 | MITERED: 1, 27 | 28 | /** 29 | * 30 | * 31 | * Corner is clipped. 32 | * @type {Number} 33 | * @constant 34 | */ 35 | BEVELED: 2, 36 | }; 37 | export default Object.freeze(CornerType); 38 | -------------------------------------------------------------------------------- /viewer/cesium/Core/ClockRange.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants used by {@link Clock#tick} to determine behavior 3 | * when {@link Clock#startTime} or {@link Clock#stopTime} is reached. 4 | * 5 | * @enum {Number} 6 | * 7 | * @see Clock 8 | * @see ClockStep 9 | */ 10 | var ClockRange = { 11 | /** 12 | * {@link Clock#tick} will always advances the clock in its current direction. 13 | * 14 | * @type {Number} 15 | * @constant 16 | */ 17 | UNBOUNDED: 0, 18 | 19 | /** 20 | * When {@link Clock#startTime} or {@link Clock#stopTime} is reached, 21 | * {@link Clock#tick} will not advance {@link Clock#currentTime} any further. 22 | * 23 | * @type {Number} 24 | * @constant 25 | */ 26 | CLAMPED: 1, 27 | 28 | /** 29 | * When {@link Clock#stopTime} is reached, {@link Clock#tick} will advance 30 | * {@link Clock#currentTime} to the opposite end of the interval. When 31 | * time is moving backwards, {@link Clock#tick} will not advance past 32 | * {@link Clock#startTime} 33 | * 34 | * @type {Number} 35 | * @constant 36 | */ 37 | LOOP_STOP: 2, 38 | }; 39 | export default Object.freeze(ClockRange); 40 | -------------------------------------------------------------------------------- /viewer/lineboxgeometry.js: -------------------------------------------------------------------------------- 1 | import {FatLineRenderer} from "./fatlinerenderer.js"; 2 | 3 | /** 4 | * Simple (reusable) class to draw a linebox 5 | * 6 | * @class LineBoxGeometry 7 | * @extends {FatLineRenderer} 8 | */ 9 | export class LineBoxGeometry extends FatLineRenderer { 10 | constructor(viewer, gl) { 11 | super(viewer, gl, {quantize: false}); 12 | this.gl = gl; 13 | 14 | this.init(12); 15 | 16 | var a = [-0.5, 0.5, -0.5]; 17 | var b = [0.5, 0.5, -0.5]; 18 | var c = [0.5, -0.5, -0.5]; 19 | var d = [-0.5, -0.5, -0.5]; 20 | var e = [-0.5, 0.5, 0.5]; 21 | var f = [0.5, 0.5, 0.5]; 22 | var g = [0.5, -0.5, 0.5]; 23 | var h = [-0.5, -0.5, 0.5]; 24 | 25 | this.pushVertices(a, b); 26 | this.pushVertices(b, c); 27 | this.pushVertices(c, d); 28 | this.pushVertices(d, a); 29 | 30 | this.pushVertices(e, f); 31 | this.pushVertices(f, g); 32 | this.pushVertices(g, h); 33 | this.pushVertices(h, e); 34 | 35 | this.pushVertices(a, e); 36 | this.pushVertices(b, f); 37 | this.pushVertices(c, g); 38 | this.pushVertices(d, h); 39 | 40 | this.finalize(); 41 | } 42 | } -------------------------------------------------------------------------------- /css/apiref.css: -------------------------------------------------------------------------------- 1 | textarea, pre { 2 | padding: 10px 0; 3 | border: none; 4 | border-top: solid 1px #ddd; 5 | width: 100%; 6 | display: block; 7 | overflow: hidden; 8 | } 9 | 10 | pre { 11 | background: white; 12 | overflow: hidden; 13 | white-space: pre-wrap; 14 | border-top: none; 15 | } 16 | 17 | #apirefContainerContainer { 18 | height: 100%; 19 | } 20 | 21 | #apirefContainer button { 22 | width: 100px; 23 | } 24 | 25 | #apirefContainer { 26 | overflow-x: hidden; 27 | overflow-y: scroll; 28 | padding: 20px; 29 | box-sizing: border-box; 30 | border-left: solid 1px #ddd; 31 | height:100%; 32 | } 33 | 34 | #apirefContainer h2, 35 | #apirefContainer h3 { 36 | padding: 0; 37 | margin: 0; 38 | } 39 | 40 | #apirefContainer h3 { 41 | padding-top: 10px; 42 | } 43 | 44 | canvas, .error { 45 | width: 50%; 46 | height: 100%; 47 | float: left; 48 | } 49 | 50 | .error { 51 | display: flex; 52 | justify-content: center; 53 | align-items: center; 54 | } 55 | 56 | .error span { 57 | display: inline-block; 58 | padding: 10px; 59 | border: solid 1px #ddd; 60 | } 61 | -------------------------------------------------------------------------------- /viewer/cesium/Core/subdivideArray.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import DeveloperError from "./DeveloperError.js"; 3 | 4 | /** 5 | * Subdivides an array into a number of smaller, equal sized arrays. 6 | * 7 | * @function subdivideArray 8 | * 9 | * @param {Array} array The array to divide. 10 | * @param {Number} numberOfArrays The number of arrays to divide the provided array into. 11 | * 12 | * @exception {DeveloperError} numberOfArrays must be greater than 0. 13 | */ 14 | function subdivideArray(array, numberOfArrays) { 15 | //>>includeStart('debug', pragmas.debug); 16 | if (!defined(array)) { 17 | throw new DeveloperError("array is required."); 18 | } 19 | 20 | if (!defined(numberOfArrays) || numberOfArrays < 1) { 21 | throw new DeveloperError("numberOfArrays must be greater than 0."); 22 | } 23 | //>>includeEnd('debug'); 24 | 25 | var result = []; 26 | var len = array.length; 27 | var i = 0; 28 | while (i < len) { 29 | var size = Math.ceil((len - i) / numberOfArrays--); 30 | result.push(array.slice(i, i + size)); 31 | i += size; 32 | } 33 | return result; 34 | } 35 | export default subdivideArray; 36 | -------------------------------------------------------------------------------- /viewer/cesium/Core/getExtensionFromUri.js: -------------------------------------------------------------------------------- 1 | import Uri from "../ThirdParty/Uri.js"; 2 | import defined from "./defined.js"; 3 | import DeveloperError from "./DeveloperError.js"; 4 | 5 | /** 6 | * Given a URI, returns the extension of the URI. 7 | * @function getExtensionFromUri 8 | * 9 | * @param {String} uri The Uri. 10 | * @returns {String} The extension of the Uri. 11 | * 12 | * @example 13 | * //extension will be "czml"; 14 | * var extension = Cesium.getExtensionFromUri('/Gallery/simple.czml?value=true&example=false'); 15 | */ 16 | function getExtensionFromUri(uri) { 17 | //>>includeStart('debug', pragmas.debug); 18 | if (!defined(uri)) { 19 | throw new DeveloperError("uri is required."); 20 | } 21 | //>>includeEnd('debug'); 22 | 23 | var uriObject = new Uri(uri); 24 | uriObject.normalize(); 25 | var path = uriObject.path; 26 | var index = path.lastIndexOf("/"); 27 | if (index !== -1) { 28 | path = path.substr(index + 1); 29 | } 30 | index = path.lastIndexOf("."); 31 | if (index === -1) { 32 | path = ""; 33 | } else { 34 | path = path.substr(index + 1); 35 | } 36 | return path; 37 | } 38 | export default getExtensionFromUri; 39 | -------------------------------------------------------------------------------- /viewer/cesium/Core/pointInsideTriangle.js: -------------------------------------------------------------------------------- 1 | import barycentricCoordinates from "./barycentricCoordinates.js"; 2 | import Cartesian3 from "./Cartesian3.js"; 3 | 4 | var coords = new Cartesian3(); 5 | 6 | /** 7 | * Determines if a point is inside a triangle. 8 | * 9 | * @function pointInsideTriangle 10 | * 11 | * @param {Cartesian2|Cartesian3} point The point to test. 12 | * @param {Cartesian2|Cartesian3} p0 The first point of the triangle. 13 | * @param {Cartesian2|Cartesian3} p1 The second point of the triangle. 14 | * @param {Cartesian2|Cartesian3} p2 The third point of the triangle. 15 | * @returns {Boolean} true if the point is inside the triangle; otherwise, false. 16 | * 17 | * @example 18 | * // Returns true 19 | * var p = new Cesium.Cartesian2(0.25, 0.25); 20 | * var b = Cesium.pointInsideTriangle(p, 21 | * new Cesium.Cartesian2(0.0, 0.0), 22 | * new Cesium.Cartesian2(1.0, 0.0), 23 | * new Cesium.Cartesian2(0.0, 1.0)); 24 | */ 25 | function pointInsideTriangle(point, p0, p1, p2) { 26 | barycentricCoordinates(point, p0, p1, p2, coords); 27 | return coords.x > 0.0 && coords.y > 0.0 && coords.z > 0; 28 | } 29 | export default pointInsideTriangle; 30 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/getAccessorByteStride.js: -------------------------------------------------------------------------------- 1 | import numberOfComponentsForType from './numberOfComponentsForType.js' 2 | import ComponentDatatype from '../../Core/ComponentDatatype.js' 3 | import defined from '../../Core/defined.js' 4 | 5 | /** 6 | * Returns the byte stride of the provided accessor. 7 | * If the byteStride is 0, it is calculated based on type and componentType 8 | * 9 | * @param {Object} gltf A javascript object containing a glTF asset. 10 | * @param {Object} accessor The accessor. 11 | * @returns {Number} The byte stride of the accessor. 12 | * 13 | * @private 14 | */ 15 | function getAccessorByteStride(gltf, accessor) { 16 | var bufferViewId = accessor.bufferView; 17 | if (defined(bufferViewId)) { 18 | var bufferView = gltf.bufferViews[bufferViewId]; 19 | if (defined(bufferView.byteStride) && bufferView.byteStride > 0) { 20 | return bufferView.byteStride; 21 | } 22 | } 23 | return ComponentDatatype.getSizeInBytes(accessor.componentType) * numberOfComponentsForType(accessor.type); 24 | } 25 | 26 | export default getAccessorByteStride; 27 | -------------------------------------------------------------------------------- /viewer/treemodel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Basic tree model, used for the ProjectTree at the moment 3 | */ 4 | class TreeNode { 5 | constructor(view) { 6 | this.children = []; 7 | this.view = view; 8 | this.expanded = false; 9 | } 10 | 11 | add(label) { 12 | var newNode = new TreeNode(this.view); 13 | newNode.label = label; 14 | newNode.parent = this; 15 | this.children.push(newNode); 16 | if (this.children.length == 1) { 17 | if (!(this instanceof TreeModel)) { 18 | this.view.collapsed(this); 19 | } 20 | } 21 | return newNode; 22 | } 23 | 24 | show() { 25 | this.view.show(this); 26 | } 27 | 28 | toggle() { 29 | if (this.children.length > 0) { 30 | this.expanded = !this.expanded; 31 | if (this.expanded) { 32 | this.view.expanded(this); 33 | } else { 34 | this.view.collapsed(this); 35 | } 36 | } 37 | } 38 | 39 | click(clickFn) { 40 | if (clickFn != null) { 41 | this.clickFn = clickFn; 42 | } else { 43 | if (this.clickFn != null) { 44 | this.clickFn(this); 45 | } 46 | } 47 | } 48 | } 49 | 50 | export class TreeModel extends TreeNode { 51 | constructor(view) { 52 | super(view); 53 | } 54 | } -------------------------------------------------------------------------------- /viewer/sectionplaneset.js: -------------------------------------------------------------------------------- 1 | import * as vec3 from "./glmatrix/vec3.js"; 2 | 3 | import {SectionPlane} from "./sectionplane.js" 4 | 5 | export class SectionPlaneSet { 6 | constructor(args) { 7 | this.viewer = args.viewer; 8 | this.planes = new Array(args.n); 9 | this.buffer = new Float32Array(4 * this.planes.length); 10 | for (let i = 0; i < args.n; ++i) { 11 | this.planes[i] = new SectionPlane({viewer: this.viewer, buffer: this.buffer.subarray(i * 4, i * 4 + 4)}); 12 | this.planes[i].index = i; 13 | } 14 | this.index = 0; 15 | } 16 | 17 | tempRestore() { 18 | this.planes.forEach(s => s.tempRestore()); 19 | } 20 | 21 | tempDisable() { 22 | this.planes.forEach(s => s.tempDisable()); 23 | } 24 | 25 | disable() { 26 | this.planes.forEach(s => s.disable()); 27 | } 28 | 29 | firstPred(pred) { 30 | let ps = this.planes.filter(pred); 31 | return ps.length ? ps[0] : null; 32 | } 33 | 34 | firstDisabledOrParallelTo(norm) { 35 | return this.firstPred(p => { return p.isDisabled || vec3.dot(p.values, norm) > 0.999; }); 36 | } 37 | 38 | firstDisabled(norm) { 39 | return this.firstPred(p => { return p.isDisabled; }); 40 | } 41 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/arraySlice.js: -------------------------------------------------------------------------------- 1 | import Check from "./Check.js"; 2 | import defined from "./defined.js"; 3 | import FeatureDetection from "./FeatureDetection.js"; 4 | 5 | /** 6 | * Create a shallow copy of an array from begin to end. 7 | * 8 | * @param {Array} array The array to fill. 9 | * @param {Number} [begin=0] The index to start at. 10 | * @param {Number} [end=array.length] The index to end at which is not included. 11 | * 12 | * @returns {Array} The resulting array. 13 | * @private 14 | */ 15 | function arraySlice(array, begin, end) { 16 | //>>includeStart('debug', pragmas.debug); 17 | Check.defined("array", array); 18 | if (defined(begin)) { 19 | Check.typeOf.number("begin", begin); 20 | } 21 | if (defined(end)) { 22 | Check.typeOf.number("end", end); 23 | } 24 | //>>includeEnd('debug'); 25 | 26 | if (typeof array.slice === "function") { 27 | return array.slice(begin, end); 28 | } 29 | 30 | var copy = Array.prototype.slice.call(array, begin, end); 31 | var typedArrayTypes = FeatureDetection.typedArrayTypes; 32 | var length = typedArrayTypes.length; 33 | for (var i = 0; i < length; ++i) { 34 | if (array instanceof typedArrayTypes[i]) { 35 | copy = new typedArrayTypes[i](copy); 36 | break; 37 | } 38 | } 39 | 40 | return copy; 41 | } 42 | export default arraySlice; 43 | -------------------------------------------------------------------------------- /viewer/cesium/Core/parseResponseHeaders.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Parses the result of XMLHttpRequest's getAllResponseHeaders() method into 3 | * a dictionary. 4 | * 5 | * @function parseResponseHeaders 6 | * 7 | * @param {String} headerString The header string returned by getAllResponseHeaders(). The format is 8 | * described here: http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method 9 | * @returns {Object} A dictionary of key/value pairs, where each key is the name of a header and the corresponding value 10 | * is that header's value. 11 | * 12 | * @private 13 | */ 14 | function parseResponseHeaders(headerString) { 15 | var headers = {}; 16 | 17 | if (!headerString) { 18 | return headers; 19 | } 20 | 21 | var headerPairs = headerString.split("\u000d\u000a"); 22 | 23 | for (var i = 0; i < headerPairs.length; ++i) { 24 | var headerPair = headerPairs[i]; 25 | // Can't use split() here because it does the wrong thing 26 | // if the header value has the string ": " in it. 27 | var index = headerPair.indexOf("\u003a\u0020"); 28 | if (index > 0) { 29 | var key = headerPair.substring(0, index); 30 | var val = headerPair.substring(index + 2); 31 | headers[key] = val; 32 | } 33 | } 34 | 35 | return headers; 36 | } 37 | export default parseResponseHeaders; 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bimsurfer3", 3 | "groupId": "org.opensourcebim", 4 | "artifactId": "bimsurfer3", 5 | "organization": "OpenSource BIM", 6 | "version": "0.0.1", 7 | "description": "BIMsurferV3", 8 | "author": { 9 | "name": "Ruben de Laat", 10 | "email": "ruben@logic-labs.nl" 11 | }, 12 | "scripts": {}, 13 | "files": [ 14 | "js" 15 | ], 16 | "main": "index.html", 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/TNOBIM/BIMSurfer" 20 | }, 21 | "bugs": { 22 | "url": "https://github.com/TNOBIM/BIMSurfer/issues" 23 | }, 24 | "keywords": [], 25 | "dependencies": { 26 | "bimserverapi": "*", 27 | "xhr2": "*" 28 | }, 29 | "devDependencies": { 30 | "@babel/core": "^7.10.1", 31 | "@babel/preset-env": "^7.10.1", 32 | "babelify": "^10.0.0", 33 | "grunt": "^1.1.0", 34 | "grunt-browserify": "^5.3.0", 35 | "grunt-cli": "^1.3.2", 36 | "grunt-contrib-clean": "*", 37 | "grunt-contrib-concat": "*", 38 | "grunt-contrib-copy": "*", 39 | "grunt-contrib-cssmin": "*", 40 | "grunt-contrib-jshint": "*", 41 | "grunt-contrib-nodeunit": "*", 42 | "grunt-contrib-uglify": "*", 43 | "grunt-zip": "*" 44 | }, 45 | "preferGlobal": true, 46 | "private": false, 47 | "analyze": true, 48 | "license": "MIT", 49 | "readmeFilename": "README.md" 50 | } 51 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/addPipelineExtras.js: -------------------------------------------------------------------------------- 1 | import ForEach from './ForEach.js' 2 | import defined from '../../Core/defined.js' 3 | 4 | /** 5 | * Adds extras._pipeline to each object that can have extras in the glTF asset. 6 | * This stage runs before updateVersion and handles both glTF 1.0 and glTF 2.0 assets. 7 | * 8 | * @param {Object} gltf A javascript object containing a glTF asset. 9 | * @returns {Object} The glTF asset with the added pipeline extras. 10 | * 11 | * @private 12 | */ 13 | function addPipelineExtras(gltf) { 14 | ForEach.shader(gltf, function(shader) { 15 | addExtras(shader); 16 | }); 17 | ForEach.buffer(gltf, function(buffer) { 18 | addExtras(buffer); 19 | }); 20 | ForEach.image(gltf, function (image) { 21 | addExtras(image); 22 | ForEach.compressedImage(image, function(compressedImage) { 23 | addExtras(compressedImage); 24 | }); 25 | }); 26 | 27 | addExtras(gltf); 28 | 29 | return gltf; 30 | } 31 | 32 | function addExtras(object) { 33 | object.extras = defined(object.extras) ? object.extras : {}; 34 | object.extras._pipeline = defined(object.extras._pipeline) ? object.extras._pipeline : {}; 35 | } 36 | 37 | export default addPipelineExtras; 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BIMSurfer v3 beta 2 | 3 | The all new BIM Surfer. Completly rebuild from scratch. This version only works with WebGL 2.0 4 | It introduces 3D tiles and is focussed on high performance. 5 | 6 | There is no official release yet, but feel free to contribute, test and evaluate this version. 7 | 8 | # Introduction 9 | 10 | BIMSurfer is a WebGL-based IFC model viewer for BIMServer. 11 | 12 | ## Versions 13 | 14 | Over time there have been various versions of BIMsurfer. You are now looking at the v3 version of BIMSurfer. 15 | 16 | |BIMSufer|Model loader|Technologies used| 17 | |---|---|---| 18 | |v1|BIMServer|XeoEngine| 19 | |v2|IfcOpenShell/glTF, BIMServer|ThreeJS, xeogl, SVG| 20 | |v3|BIMServer|Custom webgl2| 21 | 22 | Visit BIMSurfer2 here https://github.com/AECgeeks/BIMsurfer2/ 23 | 24 | ### Selecting which version of BIMSurfer to use 25 | 26 | Usage of v1 is not recommended in new projects, because of the dependency on outdated libraries and lack of a stable API. Choose v3 for highest performance, but note that is webgl2 only, which is not universally supported (54% at the time of writing [source](https://webglstats.com/webgl2)). v2 can be used solely on static files generated by IfcOpenShell and is entirely built around open standards such as glTF. v3 has an interesting set of additional features such as partial support for 3D Tiles, measurements and up to 6 section planes. 27 | -------------------------------------------------------------------------------- /viewer/cesium/Core/Packable.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "./DeveloperError.js"; 2 | 3 | /** 4 | * Static interface for types which can store their values as packed 5 | * elements in an array. These methods and properties are expected to be 6 | * defined on a constructor function. 7 | * 8 | * @interface Packable 9 | * 10 | * @see PackableForInterpolation 11 | */ 12 | var Packable = { 13 | /** 14 | * The number of elements used to pack the object into an array. 15 | * @type {Number} 16 | */ 17 | packedLength: undefined, 18 | 19 | /** 20 | * Stores the provided instance into the provided array. 21 | * @function 22 | * 23 | * @param {*} value The value to pack. 24 | * @param {Number[]} array The array to pack into. 25 | * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements. 26 | */ 27 | pack: DeveloperError.throwInstantiationError, 28 | 29 | /** 30 | * Retrieves an instance from a packed array. 31 | * @function 32 | * 33 | * @param {Number[]} array The packed array. 34 | * @param {Number} [startingIndex=0] The starting index of the element to be unpacked. 35 | * @param {Object} [result] The object into which to store the result. 36 | * @returns {Object} The modified result parameter or a new Object instance if one was not provided. 37 | */ 38 | unpack: DeveloperError.throwInstantiationError, 39 | }; 40 | export default Packable; 41 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/removePipelineExtras.js: -------------------------------------------------------------------------------- 1 | import ForEach from './ForEach.js' 2 | import defined from '../../Core/defined.js' 3 | 4 | /** 5 | * Iterate through the objects within the glTF and delete their pipeline extras object. 6 | * 7 | * @param {Object} gltf A javascript object containing a glTF asset. 8 | * @returns {Object} glTF with no pipeline extras. 9 | * 10 | * @private 11 | */ 12 | function removePipelineExtras(gltf) { 13 | ForEach.shader(gltf, function(shader) { 14 | removeExtras(shader); 15 | }); 16 | ForEach.buffer(gltf, function(buffer) { 17 | removeExtras(buffer); 18 | }); 19 | ForEach.image(gltf, function (image) { 20 | removeExtras(image); 21 | ForEach.compressedImage(image, function(compressedImage) { 22 | removeExtras(compressedImage); 23 | }); 24 | }); 25 | 26 | removeExtras(gltf); 27 | 28 | return gltf; 29 | } 30 | 31 | function removeExtras(object) { 32 | if (!defined(object.extras)) { 33 | return; 34 | } 35 | 36 | if (defined(object.extras._pipeline)) { 37 | delete object.extras._pipeline; 38 | } 39 | 40 | if (Object.keys(object.extras).length === 0) { 41 | delete object.extras; 42 | } 43 | } 44 | 45 | export default removePipelineExtras; 46 | -------------------------------------------------------------------------------- /viewer/cesium/Core/getBaseUri.js: -------------------------------------------------------------------------------- 1 | import Uri from "../ThirdParty/Uri.js"; 2 | import defined from "./defined.js"; 3 | import DeveloperError from "./DeveloperError.js"; 4 | 5 | /** 6 | * Given a URI, returns the base path of the URI. 7 | * @function 8 | * 9 | * @param {String} uri The Uri. 10 | * @param {Boolean} [includeQuery = false] Whether or not to include the query string and fragment form the uri 11 | * @returns {String} The base path of the Uri. 12 | * 13 | * @example 14 | * // basePath will be "/Gallery/"; 15 | * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false'); 16 | * 17 | * // basePath will be "/Gallery/?value=true&example=false"; 18 | * var basePath = Cesium.getBaseUri('/Gallery/simple.czml?value=true&example=false', true); 19 | */ 20 | function getBaseUri(uri, includeQuery) { 21 | //>>includeStart('debug', pragmas.debug); 22 | if (!defined(uri)) { 23 | throw new DeveloperError("uri is required."); 24 | } 25 | //>>includeEnd('debug'); 26 | 27 | var basePath = ""; 28 | var i = uri.lastIndexOf("/"); 29 | if (i !== -1) { 30 | basePath = uri.substring(0, i + 1); 31 | } 32 | 33 | if (!includeQuery) { 34 | return basePath; 35 | } 36 | 37 | uri = new Uri(uri); 38 | if (defined(uri.query)) { 39 | basePath += "?" + uri.query; 40 | } 41 | if (defined(uri.fragment)) { 42 | basePath += "#" + uri.fragment; 43 | } 44 | 45 | return basePath; 46 | } 47 | export default getBaseUri; 48 | -------------------------------------------------------------------------------- /viewer/bufferset.js: -------------------------------------------------------------------------------- 1 | import {AbstractBufferSet} from "./abstractbufferset.js"; 2 | import {AvlTree} from "./collections/avltree.js"; 3 | 4 | /** 5 | * @ignore 6 | */ 7 | export class BufferSet extends AbstractBufferSet { 8 | 9 | constructor(viewer, settings, hasTransparency, color, sizes) { 10 | super(viewer, false); 11 | 12 | this.settings = settings; 13 | this.positions = settings.quantizeVertices ? new Int16Array(sizes.vertices) : new Float32Array(sizes.vertices); 14 | this.positionsIndex = 0; 15 | this.normals = settings.quantizeNormals ? new Int8Array(sizes.normals) : new Float32Array(sizes.normals); 16 | this.normalsIndex = 0; 17 | this.pickColors = new Uint8Array(sizes.pickColors * 4); 18 | this.pickColorsIndex = 0; 19 | this.indices = new Uint32Array(sizes.indices), // The optimal buffer size is most definitely above the Uint16 threshold, so always use Uint32Array 20 | this.lineIndices = new Uint32Array(sizes.lineIndices), // The optimal buffer size is most definitely above the Uint16 threshold, so always use Uint32Array 21 | this.indicesIndex = 0; 22 | this.lineIndicesIndex = 0; 23 | this.nrIndices = 0; 24 | this.nrLineIndices = 0; 25 | this.hasTransparency = hasTransparency; 26 | this.color = color; 27 | this.bytes = 0; 28 | 29 | this.uniqueIdToIndex = new AvlTree(viewer.inverseUniqueIdCompareFunction); 30 | }; 31 | } -------------------------------------------------------------------------------- /viewer/treeview.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A basic tree view. Used for the ProjectTree at the moment. 3 | */ 4 | export class TreeView { 5 | constructor(rootElement) { 6 | this.rootElement = rootElement; 7 | } 8 | 9 | show(node) { 10 | var projectNode = document.createElement("div"); 11 | 12 | var subDiv = document.createElement("div"); 13 | node.img = document.createElement("img"); 14 | node.img.classList.add("arrow"); 15 | node.img.addEventListener("click", (event) => { 16 | node.toggle(); 17 | }); 18 | projectNode.appendChild(node.img); 19 | 20 | node.element = projectNode; 21 | var a = document.createElement("a"); 22 | projectNode.appendChild(a); 23 | a.addEventListener("click", (event) => { 24 | event.preventDefault(); 25 | node.click(); 26 | }) 27 | a.innerHTML = node.label; 28 | if (node.parent == null) { 29 | this.rootElement.appendChild(projectNode); 30 | } else { 31 | node.parent.subDiv.appendChild(projectNode); 32 | } 33 | 34 | subDiv.style["margin-left"] = "20px"; 35 | projectNode.appendChild(subDiv); 36 | node.subDiv = subDiv; 37 | node.subDiv.hidden = true; 38 | } 39 | 40 | expanded(node) { 41 | node.img.classList.remove("arrowclosed"); 42 | node.img.classList.add("arrowopen"); 43 | node.subDiv.hidden = false; 44 | } 45 | 46 | collapsed(node) { 47 | node.img.classList.remove("arrowopen"); 48 | node.img.classList.add("arrowclosed"); 49 | node.subDiv.hidden = true; 50 | } 51 | } -------------------------------------------------------------------------------- /viewer/perspective.js: -------------------------------------------------------------------------------- 1 | import * as mat4 from "./glmatrix/mat4.js"; 2 | import * as vec3 from "./glmatrix/vec3.js"; 3 | 4 | import {Projection} from "./projection.js"; 5 | 6 | /** 7 | * Configures perspective projection mode for the camera. 8 | * Perspective projection is represented as a viewing frustum, given as six planes, along with a field of view (FOV) angle. 9 | */ 10 | export class Perspective extends Projection { 11 | 12 | constructor(viewer) { 13 | super(viewer); 14 | 15 | this._fov = 45; 16 | this._near = 0.01; 17 | this._far = 100; 18 | } 19 | 20 | build() { 21 | super.build(); 22 | var aspect = this.viewer.width / this.viewer.height; 23 | mat4.perspective(this._projMatrix, this._fov * Math.PI / 180.0, aspect, this._near, this._far); 24 | mat4.invert(this._projMatrixInverted, this._projMatrix); 25 | } 26 | 27 | /** 28 | Sets the frustum's vertical field of view,} from bottom to top of view, in degrees. Default is 45. 29 | 30 | @param {Number} fov Field of view angle, in degrees. 31 | */ 32 | set fov(fov) { 33 | fov = fov || 45; 34 | fov = Math.min(fov, 120); 35 | this._fov = fov; 36 | this._setDirty(); 37 | } 38 | 39 | /** 40 | Gets the frustum's vertical field of view,} from bottom to top of view, in degrees. 41 | 42 | @return {Number} Field of view angle, in degrees. 43 | */ 44 | get fov() { 45 | return this._fov; 46 | } 47 | } -------------------------------------------------------------------------------- /viewer/bufferhelper.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a utility class, it contains a few methods that convert bytes to triangles and the other way around, these are estimations because the amount of reuse is not known 3 | */ 4 | 5 | /** 6 | * @ignore 7 | */ 8 | export class BufferHelper { 9 | static trianglesToBytes(settings, nrPrimitives) { 10 | var reusedVerticesFactor = 0.5; 11 | var estimatedNonReusedByteSize = 0; 12 | if (!settings.useObjectColors) { 13 | estimatedNonReusedByteSize += nrPrimitives * 3 * 4; 14 | } 15 | estimatedNonReusedByteSize += nrPrimitives * 3 * (settings.useSmallIndicesIfPossible ? 2 : 4); // indices 16 | estimatedNonReusedByteSize += reusedVerticesFactor * nrPrimitives * 3 * 4 * (settings.quantizeVertices ? 2 : 4); // vertices 17 | estimatedNonReusedByteSize += reusedVerticesFactor * nrPrimitives * 3 * 4 * (settings.quantizeNormals ? 1 : 4); // normals 18 | 19 | return estimatedNonReusedByteSize; 20 | } 21 | 22 | static bytesToTriangles(settings, bytes) { 23 | var reusedVerticesFactor = 0.8; 24 | var triangles = 0; 25 | if (!settings.useObjectColors) { 26 | triangles += bytes / 12; 27 | } 28 | triangles += bytes / (3 * (settings.useSmallIndicesIfPossible ? 2 : 4)); // indices 29 | triangles += bytes / (reusedVerticesFactor * 3 * 4 * (settings.quantizeVertices ? 2 : 4)); // vertices 30 | triangles += bytes / (reusedVerticesFactor * 3 * 4 * (settings.quantizeNormals ? 1 : 4)); // normals 31 | 32 | return triangles; 33 | } 34 | } -------------------------------------------------------------------------------- /apps/dev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BIMsurfer Developer Mode 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /viewer/cesium/Core/getImagePixels.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | var context2DsByWidthAndHeight = {}; 4 | 5 | /** 6 | * Extract a pixel array from a loaded image. Draws the image 7 | * into a canvas so it can read the pixels back. 8 | * 9 | * @function getImagePixels 10 | * 11 | * @param {HTMLImageElement} image The image to extract pixels from. 12 | * @param {Number} width The width of the image. If not defined, then image.width is assigned. 13 | * @param {Number} height The height of the image. If not defined, then image.height is assigned. 14 | * @returns {ImageData} The pixels of the image. 15 | */ 16 | function getImagePixels(image, width, height) { 17 | if (!defined(width)) { 18 | width = image.width; 19 | } 20 | if (!defined(height)) { 21 | height = image.height; 22 | } 23 | 24 | var context2DsByHeight = context2DsByWidthAndHeight[width]; 25 | if (!defined(context2DsByHeight)) { 26 | context2DsByHeight = {}; 27 | context2DsByWidthAndHeight[width] = context2DsByHeight; 28 | } 29 | 30 | var context2d = context2DsByHeight[height]; 31 | if (!defined(context2d)) { 32 | var canvas = document.createElement("canvas"); 33 | canvas.width = width; 34 | canvas.height = height; 35 | context2d = canvas.getContext("2d"); 36 | context2d.globalCompositeOperation = "copy"; 37 | context2DsByHeight[height] = context2d; 38 | } 39 | 40 | context2d.drawImage(image, 0, 0, width, height); 41 | return context2d.getImageData(0, 0, width, height).data; 42 | } 43 | export default getImagePixels; 44 | -------------------------------------------------------------------------------- /viewer/glmatrix/common.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Common utilities 3 | * @module glMatrix 4 | */ 5 | 6 | // Configuration Constants 7 | export const EPSILON = 0.000001; 8 | export let ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array; 9 | export const RANDOM = Math.random; 10 | 11 | /** 12 | * Sets the type of array used when creating new vectors and matrices 13 | * 14 | * @param {Float32ArrayConstructor | ArrayConstructor} type Array type, such as Float32Array or Array 15 | */ 16 | export function setMatrixArrayType(type) { 17 | ARRAY_TYPE = type; 18 | } 19 | 20 | const degree = Math.PI / 180; 21 | 22 | /** 23 | * Convert Degree To Radian 24 | * 25 | * @param {Number} a Angle in Degrees 26 | */ 27 | export function toRadian(a) { 28 | return a * degree; 29 | } 30 | 31 | /** 32 | * Tests whether or not the arguments have approximately the same value, within an absolute 33 | * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less 34 | * than or equal to 1.0, and a relative tolerance is used for larger values) 35 | * 36 | * @param {Number} a The first number to test. 37 | * @param {Number} b The second number to test. 38 | * @returns {Boolean} True if the numbers are approximately equal, false otherwise. 39 | */ 40 | export function equals(a, b) { 41 | return Math.abs(a - b) <= EPSILON*Math.max(1.0, Math.abs(a), Math.abs(b)); 42 | } 43 | 44 | if (!Math.hypot) Math.hypot = function() { 45 | var y = 0, i = arguments.length; 46 | while (i--) y += arguments[i] * arguments[i]; 47 | return Math.sqrt(y); 48 | }; 49 | -------------------------------------------------------------------------------- /viewer/cesium/Core/getAbsoluteUri.js: -------------------------------------------------------------------------------- 1 | import Uri from "../ThirdParty/Uri.js"; 2 | import defaultValue from "./defaultValue.js"; 3 | import defined from "./defined.js"; 4 | import DeveloperError from "./DeveloperError.js"; 5 | 6 | /** 7 | * Given a relative Uri and a base Uri, returns the absolute Uri of the relative Uri. 8 | * @function 9 | * 10 | * @param {String} relative The relative Uri. 11 | * @param {String} [base] The base Uri. 12 | * @returns {String} The absolute Uri of the given relative Uri. 13 | * 14 | * @example 15 | * //absolute Uri will be "https://test.com/awesome.png"; 16 | * var absoluteUri = Cesium.getAbsoluteUri('awesome.png', 'https://test.com'); 17 | */ 18 | function getAbsoluteUri(relative, base) { 19 | var documentObject; 20 | if (typeof document !== "undefined") { 21 | documentObject = document; 22 | } 23 | 24 | return getAbsoluteUri._implementation(relative, base, documentObject); 25 | } 26 | 27 | getAbsoluteUri._implementation = function (relative, base, documentObject) { 28 | //>>includeStart('debug', pragmas.debug); 29 | if (!defined(relative)) { 30 | throw new DeveloperError("relative uri is required."); 31 | } 32 | //>>includeEnd('debug'); 33 | 34 | if (!defined(base)) { 35 | if (typeof documentObject === "undefined") { 36 | return relative; 37 | } 38 | base = defaultValue(documentObject.baseURI, documentObject.location.href); 39 | } 40 | 41 | var baseUri = new Uri(base); 42 | var relativeUri = new Uri(relative); 43 | return relativeUri.resolve(baseUri).toString(); 44 | }; 45 | export default getAbsoluteUri; 46 | -------------------------------------------------------------------------------- /viewer/cesium/Core/IauOrientationParameters.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A structure containing the orientation data computed at a particular time. The data 3 | * represents the direction of the pole of rotation and the rotation about that pole. 4 | *

5 | * These parameters correspond to the parameters in the Report from the IAU/IAG Working Group 6 | * except that they are expressed in radians. 7 | *

8 | * 9 | * @namespace IauOrientationParameters 10 | * 11 | * @private 12 | */ 13 | function IauOrientationParameters( 14 | rightAscension, 15 | declination, 16 | rotation, 17 | rotationRate 18 | ) { 19 | /** 20 | * The right ascension of the north pole of the body with respect to 21 | * the International Celestial Reference Frame, in radians. 22 | * @type {Number} 23 | * 24 | * @private 25 | */ 26 | this.rightAscension = rightAscension; 27 | 28 | /** 29 | * The declination of the north pole of the body with respect to 30 | * the International Celestial Reference Frame, in radians. 31 | * @type {Number} 32 | * 33 | * @private 34 | */ 35 | this.declination = declination; 36 | 37 | /** 38 | * The rotation about the north pole used to align a set of axes with 39 | * the meridian defined by the IAU report, in radians. 40 | * @type {Number} 41 | * 42 | * @private 43 | */ 44 | this.rotation = rotation; 45 | 46 | /** 47 | * The instantaneous rotation rate about the north pole, in radians per second. 48 | * @type {Number} 49 | * 50 | * @private 51 | */ 52 | this.rotationRate = rotationRate; 53 | } 54 | export default IauOrientationParameters; 55 | -------------------------------------------------------------------------------- /viewer/cesium/Core/Iso8601.js: -------------------------------------------------------------------------------- 1 | import JulianDate from "./JulianDate.js"; 2 | import TimeInterval from "./TimeInterval.js"; 3 | 4 | var MINIMUM_VALUE = Object.freeze( 5 | JulianDate.fromIso8601("0000-01-01T00:00:00Z") 6 | ); 7 | var MAXIMUM_VALUE = Object.freeze( 8 | JulianDate.fromIso8601("9999-12-31T24:00:00Z") 9 | ); 10 | var MAXIMUM_INTERVAL = Object.freeze( 11 | new TimeInterval({ 12 | start: MINIMUM_VALUE, 13 | stop: MAXIMUM_VALUE, 14 | }) 15 | ); 16 | 17 | /** 18 | * Constants related to ISO8601 support. 19 | * 20 | * @namespace 21 | * 22 | * @see {@link http://en.wikipedia.org/wiki/ISO_8601|ISO 8601 on Wikipedia} 23 | * @see JulianDate 24 | * @see TimeInterval 25 | */ 26 | var Iso8601 = { 27 | /** 28 | * A {@link JulianDate} representing the earliest time representable by an ISO8601 date. 29 | * This is equivalent to the date string '0000-01-01T00:00:00Z' 30 | * 31 | * @type {JulianDate} 32 | * @constant 33 | */ 34 | MINIMUM_VALUE: MINIMUM_VALUE, 35 | 36 | /** 37 | * A {@link JulianDate} representing the latest time representable by an ISO8601 date. 38 | * This is equivalent to the date string '9999-12-31T24:00:00Z' 39 | * 40 | * @type {JulianDate} 41 | * @constant 42 | */ 43 | MAXIMUM_VALUE: MAXIMUM_VALUE, 44 | 45 | /** 46 | * A {@link TimeInterval} representing the largest interval representable by an ISO8601 interval. 47 | * This is equivalent to the interval string '0000-01-01T00:00:00Z/9999-12-31T24:00:00Z' 48 | * 49 | * @type {JulianDate} 50 | * @constant 51 | */ 52 | MAXIMUM_INTERVAL: MAXIMUM_INTERVAL, 53 | }; 54 | export default Iso8601; 55 | -------------------------------------------------------------------------------- /viewer/cesium/Core/arrayFill.js: -------------------------------------------------------------------------------- 1 | import Check from "./Check.js"; 2 | import defaultValue from "./defaultValue.js"; 3 | import defined from "./defined.js"; 4 | 5 | /** 6 | * Fill an array or a portion of an array with a given value. 7 | * 8 | * @param {Array} array The array to fill. 9 | * @param {*} value The value to fill the array with. 10 | * @param {Number} [start=0] The index to start filling at. 11 | * @param {Number} [end=array.length] The index to end stop at. 12 | * 13 | * @returns {Array} The resulting array. 14 | * @private 15 | */ 16 | function arrayFill(array, value, start, end) { 17 | //>>includeStart('debug', pragmas.debug); 18 | Check.defined("array", array); 19 | Check.defined("value", value); 20 | if (defined(start)) { 21 | Check.typeOf.number("start", start); 22 | } 23 | if (defined(end)) { 24 | Check.typeOf.number("end", end); 25 | } 26 | //>>includeEnd('debug'); 27 | 28 | if (typeof array.fill === "function") { 29 | return array.fill(value, start, end); 30 | } 31 | 32 | var length = array.length >>> 0; 33 | var relativeStart = defaultValue(start, 0); 34 | // If negative, find wrap around position 35 | var k = 36 | relativeStart < 0 37 | ? Math.max(length + relativeStart, 0) 38 | : Math.min(relativeStart, length); 39 | var relativeEnd = defaultValue(end, length); 40 | // If negative, find wrap around position 41 | var last = 42 | relativeEnd < 0 43 | ? Math.max(length + relativeEnd, 0) 44 | : Math.min(relativeEnd, length); 45 | 46 | // Fill array accordingly 47 | while (k < last) { 48 | array[k] = value; 49 | k++; 50 | } 51 | return array; 52 | } 53 | export default arrayFill; 54 | -------------------------------------------------------------------------------- /viewer/buffermanagertransparencyonly.js: -------------------------------------------------------------------------------- 1 | import {BufferManager} from "./buffermanager.js"; 2 | 3 | /** 4 | * A buffer manager that keeps track of only 2 buffers, one opaque and one with transparent data. 5 | * The buffers in this class use an additional buffer to store vertex-colors. 6 | */ 7 | export class BufferManagerTransparencyOnly extends BufferManager { 8 | constructor(viewer, settings, renderer, bufferSetPool) { 9 | super(viewer, settings, renderer, bufferSetPool); 10 | } 11 | 12 | /* 13 | * This implementation uses only the transparency for the key, since transparency is a boolean, there are only two slots. 14 | */ 15 | getKey(transparency, color, sizes) { 16 | return transparency; 17 | } 18 | 19 | shouldFlush(sizes, buffer) { 20 | if (super.shouldFlush(sizes, buffer)) { 21 | return true; 22 | } 23 | return sizes.colors + (buffer != null ? buffer.colorsIndex : 0) > this.MAX_BUFFER_SIZE * this.colorBufferFactor; 24 | } 25 | 26 | getDefaultByteSize() { 27 | return super.getDefaultByteSize() + this.defaultSizes.colors * (this.settings.quantizeColors ? 1 : 4); 28 | } 29 | 30 | /* 31 | * In addition to a default buffer, also add a color buffer 32 | */ 33 | createBufferSet(transparency, color, sizes) { 34 | var buffer = super.createBufferSet(transparency, color, sizes); 35 | buffer.colors = this.settings.quantizeColors ? new Uint8Array(sizes.colors) : new Float32Array(sizes.colors); 36 | buffer.colorsIndex = 0; 37 | return buffer; 38 | } 39 | 40 | /* 41 | * Additionally reset the color buffer 42 | */ 43 | resetBuffer(buffer) { 44 | super.resetBuffer(buffer); 45 | buffer.colorsIndex = 0; 46 | } 47 | } -------------------------------------------------------------------------------- /apps/interactive.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BIMsurfer Interactive Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
Server
14 |
Login
15 |
Project
16 |
Revision
17 |
Viewer
18 |
19 |
20 |

Select BIMserver

21 |
22 |
23 | Address: 24 | 25 |
26 |
27 |

OR connect to one of the following common addresses

28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 |
36 |
37 |
38 |
39 | 40 |
41 |
42 |
43 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /viewer/cesium/Core/CylinderGeometryLibrary.js: -------------------------------------------------------------------------------- 1 | import CesiumMath from "./Math.js"; 2 | 3 | /** 4 | * @private 5 | */ 6 | var CylinderGeometryLibrary = {}; 7 | 8 | /** 9 | * @private 10 | */ 11 | CylinderGeometryLibrary.computePositions = function ( 12 | length, 13 | topRadius, 14 | bottomRadius, 15 | slices, 16 | fill 17 | ) { 18 | var topZ = length * 0.5; 19 | var bottomZ = -topZ; 20 | 21 | var twoSlice = slices + slices; 22 | var size = fill ? 2 * twoSlice : twoSlice; 23 | var positions = new Float64Array(size * 3); 24 | var i; 25 | var index = 0; 26 | var tbIndex = 0; 27 | var bottomOffset = fill ? twoSlice * 3 : 0; 28 | var topOffset = fill ? (twoSlice + slices) * 3 : slices * 3; 29 | 30 | for (i = 0; i < slices; i++) { 31 | var angle = (i / slices) * CesiumMath.TWO_PI; 32 | var x = Math.cos(angle); 33 | var y = Math.sin(angle); 34 | var bottomX = x * bottomRadius; 35 | var bottomY = y * bottomRadius; 36 | var topX = x * topRadius; 37 | var topY = y * topRadius; 38 | 39 | positions[tbIndex + bottomOffset] = bottomX; 40 | positions[tbIndex + bottomOffset + 1] = bottomY; 41 | positions[tbIndex + bottomOffset + 2] = bottomZ; 42 | 43 | positions[tbIndex + topOffset] = topX; 44 | positions[tbIndex + topOffset + 1] = topY; 45 | positions[tbIndex + topOffset + 2] = topZ; 46 | tbIndex += 3; 47 | if (fill) { 48 | positions[index++] = bottomX; 49 | positions[index++] = bottomY; 50 | positions[index++] = bottomZ; 51 | positions[index++] = topX; 52 | positions[index++] = topY; 53 | positions[index++] = topZ; 54 | } 55 | } 56 | 57 | return positions; 58 | }; 59 | export default CylinderGeometryLibrary; 60 | -------------------------------------------------------------------------------- /viewer/cesium/Core/EarthOrientationParametersSample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A set of Earth Orientation Parameters (EOP) sampled at a time. 3 | * 4 | * @alias EarthOrientationParametersSample 5 | * @constructor 6 | * 7 | * @param {Number} xPoleWander The pole wander about the X axis, in radians. 8 | * @param {Number} yPoleWander The pole wander about the Y axis, in radians. 9 | * @param {Number} xPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. 10 | * @param {Number} yPoleOffset The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. 11 | * @param {Number} ut1MinusUtc The difference in time standards, UT1 - UTC, in seconds. 12 | * 13 | * @private 14 | */ 15 | function EarthOrientationParametersSample( 16 | xPoleWander, 17 | yPoleWander, 18 | xPoleOffset, 19 | yPoleOffset, 20 | ut1MinusUtc 21 | ) { 22 | /** 23 | * The pole wander about the X axis, in radians. 24 | * @type {Number} 25 | */ 26 | this.xPoleWander = xPoleWander; 27 | 28 | /** 29 | * The pole wander about the Y axis, in radians. 30 | * @type {Number} 31 | */ 32 | this.yPoleWander = yPoleWander; 33 | 34 | /** 35 | * The offset to the Celestial Intermediate Pole (CIP) about the X axis, in radians. 36 | * @type {Number} 37 | */ 38 | this.xPoleOffset = xPoleOffset; 39 | 40 | /** 41 | * The offset to the Celestial Intermediate Pole (CIP) about the Y axis, in radians. 42 | * @type {Number} 43 | */ 44 | this.yPoleOffset = yPoleOffset; 45 | 46 | /** 47 | * The difference in time standards, UT1 - UTC, in seconds. 48 | * @type {Number} 49 | */ 50 | this.ut1MinusUtc = ut1MinusUtc; 51 | } 52 | export default EarthOrientationParametersSample; 53 | -------------------------------------------------------------------------------- /viewer/cesium/Core/cancelAnimationFrame.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | var implementation; 4 | if (typeof cancelAnimationFrame !== "undefined") { 5 | implementation = cancelAnimationFrame; 6 | } 7 | 8 | (function () { 9 | // look for vendor prefixed function 10 | if (!defined(implementation) && typeof window !== "undefined") { 11 | var vendors = ["webkit", "moz", "ms", "o"]; 12 | var i = 0; 13 | var len = vendors.length; 14 | while (i < len && !defined(implementation)) { 15 | implementation = window[vendors[i] + "CancelAnimationFrame"]; 16 | if (!defined(implementation)) { 17 | implementation = window[vendors[i] + "CancelRequestAnimationFrame"]; 18 | } 19 | ++i; 20 | } 21 | } 22 | 23 | // otherwise, assume requestAnimationFrame is based on setTimeout, so use clearTimeout 24 | if (!defined(implementation)) { 25 | implementation = clearTimeout; 26 | } 27 | })(); 28 | 29 | /** 30 | * A browser-independent function to cancel an animation frame requested using {@link requestAnimationFrame}. 31 | * 32 | * @function cancelAnimationFrame 33 | * 34 | * @param {Number} requestID The value returned by {@link requestAnimationFrame}. 35 | * 36 | * @see {@link http://www.w3.org/TR/animation-timing/#the-WindowAnimationTiming-interface|The WindowAnimationTiming interface} 37 | */ 38 | function cancelAnimationFramePolyfill(requestID) { 39 | // we need this extra wrapper function because the native cancelAnimationFrame 40 | // functions must be invoked on the global scope (window), which is not the case 41 | // if invoked as Cesium.cancelAnimationFrame(requestID) 42 | implementation(requestID); 43 | } 44 | export default cancelAnimationFramePolyfill; 45 | -------------------------------------------------------------------------------- /viewer/cesium/Core/loadImageFromTypedArray.js: -------------------------------------------------------------------------------- 1 | import when from "../ThirdParty/when.js"; 2 | import Check from "./Check.js"; 3 | import defaultValue from "./defaultValue.js"; 4 | import defined from "./defined.js"; 5 | import Resource from "./Resource.js"; 6 | 7 | /** 8 | * @private 9 | */ 10 | function loadImageFromTypedArray(options) { 11 | var uint8Array = options.uint8Array; 12 | var format = options.format; 13 | var request = options.request; 14 | var flipY = defaultValue(options.flipY, false); 15 | //>>includeStart('debug', pragmas.debug); 16 | Check.typeOf.object("uint8Array", uint8Array); 17 | Check.typeOf.string("format", format); 18 | //>>includeEnd('debug'); 19 | 20 | var blob = new Blob([uint8Array], { 21 | type: format, 22 | }); 23 | 24 | var blobUrl; 25 | return Resource.supportsImageBitmapOptions() 26 | .then(function (result) { 27 | if (result) { 28 | return when( 29 | Resource.createImageBitmapFromBlob(blob, { 30 | flipY: flipY, 31 | premultiplyAlpha: false, 32 | }) 33 | ); 34 | } 35 | 36 | blobUrl = window.URL.createObjectURL(blob); 37 | var resource = new Resource({ 38 | url: blobUrl, 39 | request: request, 40 | }); 41 | 42 | return resource.fetchImage({ 43 | flipY: flipY, 44 | }); 45 | }) 46 | .then(function (result) { 47 | if (defined(blobUrl)) { 48 | window.URL.revokeObjectURL(blobUrl); 49 | } 50 | return result; 51 | }) 52 | .otherwise(function (error) { 53 | if (defined(blobUrl)) { 54 | window.URL.revokeObjectURL(blobUrl); 55 | } 56 | return when.reject(error); 57 | }); 58 | } 59 | export default loadImageFromTypedArray; 60 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/quickselect.js: -------------------------------------------------------------------------------- 1 | 2 | function quickselect(arr, k, left, right, compare) { 3 | quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare); 4 | }; 5 | 6 | function quickselectStep(arr, k, left, right, compare) { 7 | 8 | while (right > left) { 9 | if (right - left > 600) { 10 | var n = right - left + 1; 11 | var m = k - left + 1; 12 | var z = Math.log(n); 13 | var s = 0.5 * Math.exp(2 * z / 3); 14 | var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1); 15 | var newLeft = Math.max(left, Math.floor(k - m * s / n + sd)); 16 | var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd)); 17 | quickselectStep(arr, k, newLeft, newRight, compare); 18 | } 19 | 20 | var t = arr[k]; 21 | var i = left; 22 | var j = right; 23 | 24 | swap(arr, left, k); 25 | if (compare(arr[right], t) > 0) swap(arr, left, right); 26 | 27 | while (i < j) { 28 | swap(arr, i, j); 29 | i++; 30 | j--; 31 | while (compare(arr[i], t) < 0) i++; 32 | while (compare(arr[j], t) > 0) j--; 33 | } 34 | 35 | if (compare(arr[left], t) === 0) swap(arr, left, j); 36 | else { 37 | j++; 38 | swap(arr, j, right); 39 | } 40 | 41 | if (j <= k) left = j + 1; 42 | if (k <= j) right = j - 1; 43 | } 44 | } 45 | 46 | function swap(arr, i, j) { 47 | var tmp = arr[i]; 48 | arr[i] = arr[j]; 49 | arr[j] = tmp; 50 | } 51 | 52 | function defaultCompare(a, b) { 53 | return a < b ? -1 : a > b ? 1 : 0; 54 | } 55 | 56 | export default quickselect; 57 | -------------------------------------------------------------------------------- /viewer/cesium/Core/createWorldTerrain.js: -------------------------------------------------------------------------------- 1 | import CesiumTerrainProvider from "./CesiumTerrainProvider.js"; 2 | import defaultValue from "./defaultValue.js"; 3 | import IonResource from "./IonResource.js"; 4 | 5 | /** 6 | * Creates a {@link CesiumTerrainProvider} instance for the {@link https://cesium.com/content/#cesium-world-terrain|Cesium World Terrain}. 7 | * 8 | * @function 9 | * 10 | * @param {Object} [options] Object with the following properties: 11 | * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server if available. 12 | * @param {Boolean} [options.requestWaterMask=false] Flag that indicates if the client should request per tile water masks from the server if available. 13 | * @returns {CesiumTerrainProvider} 14 | * 15 | * @see Ion 16 | * 17 | * @example 18 | * // Create Cesium World Terrain with default settings 19 | * var viewer = new Cesium.Viewer('cesiumContainer', { 20 | * terrainProvider : Cesium.createWorldTerrain(); 21 | * }); 22 | * 23 | * @example 24 | * // Create Cesium World Terrain with water and normals. 25 | * var viewer = new Cesium.Viewer('cesiumContainer', { 26 | * terrainProvider : Cesium.createWorldTerrain({ 27 | * requestWaterMask : true, 28 | * requestVertexNormals : true 29 | * }); 30 | * }); 31 | * 32 | */ 33 | function createWorldTerrain(options) { 34 | options = defaultValue(options, defaultValue.EMPTY_OBJECT); 35 | 36 | return new CesiumTerrainProvider({ 37 | url: IonResource.fromAssetId(1), 38 | requestVertexNormals: defaultValue(options.requestVertexNormals, false), 39 | requestWaterMask: defaultValue(options.requestWaterMask, false), 40 | }); 41 | } 42 | export default createWorldTerrain; 43 | -------------------------------------------------------------------------------- /viewer/cesium/Core/objectToQuery.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import DeveloperError from "./DeveloperError.js"; 3 | 4 | /** 5 | * Converts an object representing a set of name/value pairs into a query string, 6 | * with names and values encoded properly for use in a URL. Values that are arrays 7 | * will produce multiple values with the same name. 8 | * @function objectToQuery 9 | * 10 | * @param {Object} obj The object containing data to encode. 11 | * @returns {String} An encoded query string. 12 | * 13 | * 14 | * @example 15 | * var str = Cesium.objectToQuery({ 16 | * key1 : 'some value', 17 | * key2 : 'a/b', 18 | * key3 : ['x', 'y'] 19 | * }); 20 | * 21 | * @see queryToObject 22 | * // str will be: 23 | * // 'key1=some%20value&key2=a%2Fb&key3=x&key3=y' 24 | */ 25 | function objectToQuery(obj) { 26 | //>>includeStart('debug', pragmas.debug); 27 | if (!defined(obj)) { 28 | throw new DeveloperError("obj is required."); 29 | } 30 | //>>includeEnd('debug'); 31 | 32 | var result = ""; 33 | for (var propName in obj) { 34 | if (obj.hasOwnProperty(propName)) { 35 | var value = obj[propName]; 36 | 37 | var part = encodeURIComponent(propName) + "="; 38 | if (Array.isArray(value)) { 39 | for (var i = 0, len = value.length; i < len; ++i) { 40 | result += part + encodeURIComponent(value[i]) + "&"; 41 | } 42 | } else { 43 | result += part + encodeURIComponent(value) + "&"; 44 | } 45 | } 46 | } 47 | 48 | // trim last & 49 | result = result.slice(0, -1); 50 | 51 | // This function used to replace %20 with + which is more compact and readable. 52 | // However, some servers didn't properly handle + as a space. 53 | // https://github.com/CesiumGS/cesium/issues/2192 54 | 55 | return result; 56 | } 57 | export default objectToQuery; 58 | -------------------------------------------------------------------------------- /viewer/projecttreemodel.js: -------------------------------------------------------------------------------- 1 | import {TreeModel} from "./treemodel.js"; 2 | 3 | /** 4 | * A quick and dirty tree model, this is used in both the dev.js and interactive.js apps 5 | */ 6 | export class ProjectTreeModel extends TreeModel{ 7 | constructor(bimServerApi, view) { 8 | super(view); 9 | this.subDiv = view.rootElement; 10 | while (this.subDiv.firstChild) { 11 | this.subDiv.removeChild(this.subDiv.firstChild); 12 | } 13 | this.bimServerApi = bimServerApi; 14 | this.poidToProject = new Map(); 15 | } 16 | 17 | load(clickFn) { 18 | return this.bimServerApi.call("ServiceInterface", "getAllProjects", { 19 | onlyTopLevel: false, 20 | onlyActive: true 21 | }, (projects) => { 22 | if (projects.length == 0) { 23 | var node = this.add("No projects"); 24 | node.show(); 25 | } 26 | for (var p of projects) { 27 | this.poidToProject.set(p.oid, p); 28 | p.subProjects = []; 29 | } 30 | for (var p of projects) { 31 | if (p.parentId != -1) { 32 | this.poidToProject.get(p.parentId).subProjects.push(p); 33 | } 34 | } 35 | for (var p of projects) { 36 | if (p.parentId == -1) { 37 | this.addProject(null, p, clickFn); 38 | } 39 | } 40 | }); 41 | } 42 | 43 | addProject(parentNode, project, clickFn) { 44 | if (project.lastRevisionId == -1 && project.subProjects.length == 0) { 45 | return; 46 | } 47 | if (parentNode == null) { 48 | var node = this.add(project.name); 49 | } else { 50 | var node = parentNode.add(project.name); 51 | } 52 | if (project.lastRevisionId != -1) { 53 | node.click(clickFn); 54 | } 55 | node.project = project; 56 | node.show(); 57 | 58 | var mainProject = this.poidToProject.get(project.oid); 59 | if (mainProject != null) { 60 | for (var subProject of mainProject.subProjects) { 61 | this.addProject(node, subProject, clickFn); 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/RuntimeError.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | /** 4 | * Constructs an exception object that is thrown due to an error that can occur at runtime, e.g., 5 | * out of memory, could not compile shader, etc. If a function may throw this 6 | * exception, the calling code should be prepared to catch it. 7 | *

8 | * On the other hand, a {@link DeveloperError} indicates an exception due 9 | * to a developer error, e.g., invalid argument, that usually indicates a bug in the 10 | * calling code. 11 | * 12 | * @alias RuntimeError 13 | * @constructor 14 | * @extends Error 15 | * 16 | * @param {String} [message] The error message for this exception. 17 | * 18 | * @see DeveloperError 19 | */ 20 | function RuntimeError(message) { 21 | /** 22 | * 'RuntimeError' indicating that this exception was thrown due to a runtime error. 23 | * @type {String} 24 | * @readonly 25 | */ 26 | this.name = "RuntimeError"; 27 | 28 | /** 29 | * The explanation for why this exception was thrown. 30 | * @type {String} 31 | * @readonly 32 | */ 33 | this.message = message; 34 | 35 | //Browsers such as IE don't have a stack property until you actually throw the error. 36 | var stack; 37 | try { 38 | throw new Error(); 39 | } catch (e) { 40 | stack = e.stack; 41 | } 42 | 43 | /** 44 | * The stack trace of this exception, if available. 45 | * @type {String} 46 | * @readonly 47 | */ 48 | this.stack = stack; 49 | } 50 | 51 | if (defined(Object.create)) { 52 | RuntimeError.prototype = Object.create(Error.prototype); 53 | RuntimeError.prototype.constructor = RuntimeError; 54 | } 55 | 56 | RuntimeError.prototype.toString = function () { 57 | var str = this.name + ": " + this.message; 58 | 59 | if (defined(this.stack)) { 60 | str += "\n" + this.stack.toString(); 61 | } 62 | 63 | return str; 64 | }; 65 | export default RuntimeError; 66 | -------------------------------------------------------------------------------- /viewer/cesium/Core/queryToObject.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import DeveloperError from "./DeveloperError.js"; 3 | 4 | /** 5 | * Parses a query string into an object, where the keys and values of the object are the 6 | * name/value pairs from the query string, decoded. If a name appears multiple times, 7 | * the value in the object will be an array of values. 8 | * @function queryToObject 9 | * 10 | * @param {String} queryString The query string. 11 | * @returns {Object} An object containing the parameters parsed from the query string. 12 | * 13 | * 14 | * @example 15 | * var obj = Cesium.queryToObject('key1=some%20value&key2=a%2Fb&key3=x&key3=y'); 16 | * // obj will be: 17 | * // { 18 | * // key1 : 'some value', 19 | * // key2 : 'a/b', 20 | * // key3 : ['x', 'y'] 21 | * // } 22 | * 23 | * @see objectToQuery 24 | */ 25 | function queryToObject(queryString) { 26 | //>>includeStart('debug', pragmas.debug); 27 | if (!defined(queryString)) { 28 | throw new DeveloperError("queryString is required."); 29 | } 30 | //>>includeEnd('debug'); 31 | 32 | var result = {}; 33 | if (queryString === "") { 34 | return result; 35 | } 36 | var parts = queryString.replace(/\+/g, "%20").split(/[&;]/); 37 | for (var i = 0, len = parts.length; i < len; ++i) { 38 | var subparts = parts[i].split("="); 39 | 40 | var name = decodeURIComponent(subparts[0]); 41 | var value = subparts[1]; 42 | if (defined(value)) { 43 | value = decodeURIComponent(value); 44 | } else { 45 | value = ""; 46 | } 47 | 48 | var resultValue = result[name]; 49 | if (typeof resultValue === "string") { 50 | // expand the single value to an array 51 | result[name] = [resultValue, value]; 52 | } else if (Array.isArray(resultValue)) { 53 | resultValue.push(value); 54 | } else { 55 | result[name] = value; 56 | } 57 | } 58 | return result; 59 | } 60 | export default queryToObject; 61 | -------------------------------------------------------------------------------- /viewer/cesium/Core/PackableForInterpolation.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "./DeveloperError.js"; 2 | 3 | /** 4 | * Static interface for {@link Packable} types which are interpolated in a 5 | * different representation than their packed value. These methods and 6 | * properties are expected to be defined on a constructor function. 7 | * 8 | * @namespace PackableForInterpolation 9 | * 10 | * @see Packable 11 | */ 12 | var PackableForInterpolation = { 13 | /** 14 | * The number of elements used to store the object into an array in its interpolatable form. 15 | * @type {Number} 16 | */ 17 | packedInterpolationLength: undefined, 18 | 19 | /** 20 | * Converts a packed array into a form suitable for interpolation. 21 | * @function 22 | * 23 | * @param {Number[]} packedArray The packed array. 24 | * @param {Number} [startingIndex=0] The index of the first element to be converted. 25 | * @param {Number} [lastIndex=packedArray.length] The index of the last element to be converted. 26 | * @param {Number[]} [result] The object into which to store the result. 27 | */ 28 | convertPackedArrayForInterpolation: DeveloperError.throwInstantiationError, 29 | 30 | /** 31 | * Retrieves an instance from a packed array converted with {@link PackableForInterpolation.convertPackedArrayForInterpolation}. 32 | * @function 33 | * 34 | * @param {Number[]} array The array previously packed for interpolation. 35 | * @param {Number[]} sourceArray The original packed array. 36 | * @param {Number} [startingIndex=0] The startingIndex used to convert the array. 37 | * @param {Number} [lastIndex=packedArray.length] The lastIndex used to convert the array. 38 | * @param {Object} [result] The object into which to store the result. 39 | * @returns {Object} The modified result parameter or a new Object instance if one was not provided. 40 | */ 41 | unpackInterpolationResult: DeveloperError.throwInstantiationError, 42 | }; 43 | export default PackableForInterpolation; 44 | -------------------------------------------------------------------------------- /apps/api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | BIMsurfer Developer Mode 7 | 8 | 9 | 10 | 12 | 13 | 14 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
55 |
56 |
57 |
58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /viewer/cesium/Core/destroyObject.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | import DeveloperError from "./DeveloperError.js"; 3 | 4 | function returnTrue() { 5 | return true; 6 | } 7 | 8 | /** 9 | * Destroys an object. Each of the object's functions, including functions in its prototype, 10 | * is replaced with a function that throws a {@link DeveloperError}, except for the object's 11 | * isDestroyed function, which is set to a function that returns true. 12 | * The object's properties are removed with delete. 13 | *

14 | * This function is used by objects that hold native resources, e.g., WebGL resources, which 15 | * need to be explicitly released. Client code calls an object's destroy function, 16 | * which then releases the native resource and calls destroyObject to put itself 17 | * in a destroyed state. 18 | * 19 | * @function 20 | * 21 | * @param {Object} object The object to destroy. 22 | * @param {String} [message] The message to include in the exception that is thrown if 23 | * a destroyed object's function is called. 24 | * 25 | * 26 | * @example 27 | * // How a texture would destroy itself. 28 | * this.destroy = function () { 29 | * _gl.deleteTexture(_texture); 30 | * return Cesium.destroyObject(this); 31 | * }; 32 | * 33 | * @see DeveloperError 34 | */ 35 | function destroyObject(object, message) { 36 | message = defaultValue( 37 | message, 38 | "This object was destroyed, i.e., destroy() was called." 39 | ); 40 | 41 | function throwOnDestroyed() { 42 | //>>includeStart('debug', pragmas.debug); 43 | throw new DeveloperError(message); 44 | //>>includeEnd('debug'); 45 | } 46 | 47 | for (var key in object) { 48 | if (typeof object[key] === "function") { 49 | object[key] = throwOnDestroyed; 50 | } 51 | } 52 | 53 | object.isDestroyed = returnTrue; 54 | 55 | return undefined; 56 | } 57 | export default destroyObject; 58 | -------------------------------------------------------------------------------- /viewer/bimservergeometryloader.js: -------------------------------------------------------------------------------- 1 | import * as mat4 from "./glmatrix/mat4.js"; 2 | import * as mat3 from "./glmatrix/mat3.js"; 3 | import * as vec3 from "./glmatrix/vec3.js"; 4 | 5 | import {GeometryLoader} from "./geometryloader.js"; 6 | import {Utils} from "./utils.js"; 7 | 8 | /** 9 | * GeometryLoader loads data from a BIMserver 10 | */ 11 | export class BimserverGeometryLoader extends GeometryLoader { 12 | 13 | constructor(loaderId, bimServerApi, renderLayer, roids, loaderSettings, vertexQuantizationMatrices, stats, settings, query, geometryCache, gpuBufferManager) { 14 | super(loaderId, renderLayer, loaderSettings, vertexQuantizationMatrices, stats, settings, geometryCache, gpuBufferManager, query.loaderSettings.prepareBuffers); 15 | 16 | this.bimServerApi = bimServerApi; 17 | this.roids = roids; 18 | this.query = query; 19 | } 20 | 21 | initiateDownload() { 22 | super.initiateDownload(); 23 | 24 | if (this.vertexQuantizationMatrices != null) { 25 | this.query.loaderSettings.vertexQuantizationMatrices = this.vertexQuantizationMatrices; 26 | } 27 | 28 | this.bimServerApi.getSerializerByPluginClassName("org.bimserver.serializers.binarygeometry.BinaryGeometryMessagingStreamingSerializerPlugin").then((serializer) => { 29 | this.bimServerApi.callWithWebsocket("ServiceInterface", "download", { 30 | roids: this.roids, 31 | query: JSON.stringify(this.query), 32 | serializerOid : serializer.oid, 33 | sync : false 34 | }).then((topicId) => { 35 | this.topicId = topicId; 36 | 37 | var msg = { 38 | topicId: this.topicId 39 | }; 40 | this.bimServerApi.setBinaryDataListener(this.topicId, (data) => { 41 | this.binaryDataListener(data); 42 | }); 43 | this.bimServerApi.downloadViaWebsocket(msg); 44 | }); 45 | }); 46 | } 47 | 48 | endOfStream() { 49 | super.endOfStream(); 50 | this.bimServerApi.clearBinaryDataListener(this.topicId); 51 | this.bimServerApi.callWithWebsocket("ServiceInterface", "cleanupLongAction", {topicId: this.topicId}); 52 | } 53 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/Ion.js: -------------------------------------------------------------------------------- 1 | import Credit from "./Credit.js"; 2 | import defined from "./defined.js"; 3 | import Resource from "./Resource.js"; 4 | 5 | var defaultTokenCredit; 6 | var defaultAccessToken = 7 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJmNTZmY2U0Ni1lMmMxLTQ1ZmMtYWIyZC1hZDk2NzE5N2UzMDciLCJpZCI6MjU5LCJpYXQiOjE2MDQzMjY0MjN9.aTMKOaHQKGyesz1A2QXE-Y5FvG19FSO7I6F3NS1T5To"; 8 | /** 9 | * Default settings for accessing the Cesium ion API. 10 | * 11 | * An ion access token is only required if you are using any ion related APIs. 12 | * A default access token is provided for evaluation purposes only. 13 | * Sign up for a free ion account and get your own access token at {@link https://cesium.com} 14 | * 15 | * @see IonResource 16 | * @see IonImageryProvider 17 | * @see IonGeocoderService 18 | * @see createWorldImagery 19 | * @see createWorldTerrain 20 | * @namespace Ion 21 | */ 22 | var Ion = {}; 23 | 24 | /** 25 | * Gets or sets the default Cesium ion access token. 26 | * 27 | * @type {String} 28 | */ 29 | Ion.defaultAccessToken = defaultAccessToken; 30 | 31 | /** 32 | * Gets or sets the default Cesium ion server. 33 | * 34 | * @type {String|Resource} 35 | * @default https://api.cesium.com 36 | */ 37 | Ion.defaultServer = new Resource({ url: "https://api.cesium.com/" }); 38 | 39 | Ion.getDefaultTokenCredit = function (providedKey) { 40 | if (providedKey !== defaultAccessToken) { 41 | return undefined; 42 | } 43 | 44 | if (!defined(defaultTokenCredit)) { 45 | var defaultTokenMessage = 46 | ' \ 47 | This application is using Cesium\'s default ion access token. Please assign Cesium.Ion.defaultAccessToken \ 48 | with an access token from your ion account before making any Cesium API calls. \ 49 | You can sign up for a free ion account at https://cesium.com.'; 50 | 51 | defaultTokenCredit = new Credit(defaultTokenMessage, true); 52 | } 53 | 54 | return defaultTokenCredit; 55 | }; 56 | export default Ion; 57 | -------------------------------------------------------------------------------- /viewer/cesium/Core/deprecationWarning.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import DeveloperError from "./DeveloperError.js"; 3 | import oneTimeWarning from "./oneTimeWarning.js"; 4 | 5 | /** 6 | * Logs a deprecation message to the console. Use this function instead of 7 | * console.log directly since this does not log duplicate messages 8 | * unless it is called from multiple workers. 9 | * 10 | * @function deprecationWarning 11 | * 12 | * @param {String} identifier The unique identifier for this deprecated API. 13 | * @param {String} message The message to log to the console. 14 | * 15 | * @example 16 | * // Deprecated function or class 17 | * function Foo() { 18 | * deprecationWarning('Foo', 'Foo was deprecated in Cesium 1.01. It will be removed in 1.03. Use newFoo instead.'); 19 | * // ... 20 | * } 21 | * 22 | * // Deprecated function 23 | * Bar.prototype.func = function() { 24 | * deprecationWarning('Bar.func', 'Bar.func() was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newFunc() instead.'); 25 | * // ... 26 | * }; 27 | * 28 | * // Deprecated property 29 | * Object.defineProperties(Bar.prototype, { 30 | * prop : { 31 | * get : function() { 32 | * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); 33 | * // ... 34 | * }, 35 | * set : function(value) { 36 | * deprecationWarning('Bar.prop', 'Bar.prop was deprecated in Cesium 1.01. It will be removed in 1.03. Use Bar.newProp instead.'); 37 | * // ... 38 | * } 39 | * } 40 | * }); 41 | * 42 | * @private 43 | */ 44 | function deprecationWarning(identifier, message) { 45 | //>>includeStart('debug', pragmas.debug); 46 | if (!defined(identifier) || !defined(message)) { 47 | throw new DeveloperError("identifier and message are required."); 48 | } 49 | //>>includeEnd('debug'); 50 | 51 | oneTimeWarning(identifier, message); 52 | } 53 | export default deprecationWarning; 54 | -------------------------------------------------------------------------------- /viewer/cesium/Core/TimeConstants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Constants for time conversions like those done by {@link JulianDate}. 3 | * 4 | * @namespace TimeConstants 5 | * 6 | * @see JulianDate 7 | * 8 | * @private 9 | */ 10 | var TimeConstants = { 11 | /** 12 | * The number of seconds in one millisecond: 0.001 13 | * @type {Number} 14 | * @constant 15 | */ 16 | SECONDS_PER_MILLISECOND: 0.001, 17 | 18 | /** 19 | * The number of seconds in one minute: 60. 20 | * @type {Number} 21 | * @constant 22 | */ 23 | SECONDS_PER_MINUTE: 60.0, 24 | 25 | /** 26 | * The number of minutes in one hour: 60. 27 | * @type {Number} 28 | * @constant 29 | */ 30 | MINUTES_PER_HOUR: 60.0, 31 | 32 | /** 33 | * The number of hours in one day: 24. 34 | * @type {Number} 35 | * @constant 36 | */ 37 | HOURS_PER_DAY: 24.0, 38 | 39 | /** 40 | * The number of seconds in one hour: 3600. 41 | * @type {Number} 42 | * @constant 43 | */ 44 | SECONDS_PER_HOUR: 3600.0, 45 | 46 | /** 47 | * The number of minutes in one day: 1440. 48 | * @type {Number} 49 | * @constant 50 | */ 51 | MINUTES_PER_DAY: 1440.0, 52 | 53 | /** 54 | * The number of seconds in one day, ignoring leap seconds: 86400. 55 | * @type {Number} 56 | * @constant 57 | */ 58 | SECONDS_PER_DAY: 86400.0, 59 | 60 | /** 61 | * The number of days in one Julian century: 36525. 62 | * @type {Number} 63 | * @constant 64 | */ 65 | DAYS_PER_JULIAN_CENTURY: 36525.0, 66 | 67 | /** 68 | * One trillionth of a second. 69 | * @type {Number} 70 | * @constant 71 | */ 72 | PICOSECOND: 0.000000001, 73 | 74 | /** 75 | * The number of days to subtract from a Julian date to determine the 76 | * modified Julian date, which gives the number of days since midnight 77 | * on November 17, 1858. 78 | * @type {Number} 79 | * @constant 80 | */ 81 | MODIFIED_JULIAN_DATE_DIFFERENCE: 2400000.5, 82 | }; 83 | export default Object.freeze(TimeConstants); 84 | -------------------------------------------------------------------------------- /viewer/cesium/Core/RequestErrorEvent.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import parseResponseHeaders from "./parseResponseHeaders.js"; 3 | 4 | /** 5 | * An event that is raised when a request encounters an error. 6 | * 7 | * @constructor 8 | * @alias RequestErrorEvent 9 | * 10 | * @param {Number} [statusCode] The HTTP error status code, such as 404. 11 | * @param {Object} [response] The response included along with the error. 12 | * @param {String|Object} [responseHeaders] The response headers, represented either as an object literal or as a 13 | * string in the format returned by XMLHttpRequest's getAllResponseHeaders() function. 14 | */ 15 | function RequestErrorEvent(statusCode, response, responseHeaders) { 16 | /** 17 | * The HTTP error status code, such as 404. If the error does not have a particular 18 | * HTTP code, this property will be undefined. 19 | * 20 | * @type {Number} 21 | */ 22 | this.statusCode = statusCode; 23 | 24 | /** 25 | * The response included along with the error. If the error does not include a response, 26 | * this property will be undefined. 27 | * 28 | * @type {Object} 29 | */ 30 | this.response = response; 31 | 32 | /** 33 | * The headers included in the response, represented as an object literal of key/value pairs. 34 | * If the error does not include any headers, this property will be undefined. 35 | * 36 | * @type {Object} 37 | */ 38 | this.responseHeaders = responseHeaders; 39 | 40 | if (typeof this.responseHeaders === "string") { 41 | this.responseHeaders = parseResponseHeaders(this.responseHeaders); 42 | } 43 | } 44 | 45 | /** 46 | * Creates a string representing this RequestErrorEvent. 47 | * @memberof RequestErrorEvent 48 | * 49 | * @returns {String} A string representing the provided RequestErrorEvent. 50 | */ 51 | RequestErrorEvent.prototype.toString = function () { 52 | var str = "Request has failed."; 53 | if (defined(this.statusCode)) { 54 | str += " Status Code: " + this.statusCode; 55 | } 56 | return str; 57 | }; 58 | export default RequestErrorEvent; 59 | -------------------------------------------------------------------------------- /viewer/animatedvec3.js: -------------------------------------------------------------------------------- 1 | import * as vec3 from "./glmatrix/vec3.js"; 2 | 3 | // @todo don't rely on Date, but on the timer from requestanimationframe 4 | 5 | export class AnimatedVec3 { 6 | 7 | constructor(x, y, z) { 8 | this.a = vec3.create(); 9 | this.b = vec3.create(); 10 | this.c = vec3.create(); 11 | this.tmp = vec3.create(); 12 | this.t0 = 0; 13 | this.t1 = 1; 14 | this.t2 = 2; 15 | 16 | this.a.set([x, y, z]); 17 | } 18 | 19 | get() { 20 | if (this.t0 === 0) { 21 | return this.a; 22 | } else { 23 | let b, t, rt; 24 | rt = (+new Date); 25 | t = (rt - this.t0) / (this.t1 - this.t0); 26 | if (t < 0) { t = 0; } 27 | if (t > 1) { 28 | t = 1; 29 | b = true; 30 | } 31 | vec3.lerp(this.tmp, this.a, this.b, t); 32 | if (b) { 33 | if (this.t2) { 34 | this.t0 = this.t1; 35 | this.t1 = this.t2; 36 | this.t2 = 0; 37 | 38 | let x = this.a; 39 | this.a = this.b; 40 | this.b = this.c; 41 | this.c = x; 42 | 43 | return this.get(); 44 | } else { 45 | this.a.set(this.tmp); 46 | this.t0 = 0; 47 | AnimatedVec3.ACTIVE_ANIMATIONS--; 48 | } 49 | } 50 | return this.tmp; 51 | } 52 | } 53 | 54 | deanimate() { 55 | if (this.t0) { 56 | let x = this.a; 57 | this.a = this.get(); 58 | this.tmp = x; 59 | this.t0 = 0; 60 | } 61 | } 62 | 63 | // Store manually in `b`. 64 | animate(dt, dt2) { 65 | this.t0 = +new Date; 66 | this.t1 = this.t0 + dt; 67 | if (dt2) { 68 | this.t2 = this.t1 + dt2; 69 | } else { 70 | this.t2 = 0; 71 | } 72 | AnimatedVec3.ACTIVE_ANIMATIONS++; 73 | } 74 | } 75 | 76 | AnimatedVec3.ACTIVE_ANIMATIONS = 0; -------------------------------------------------------------------------------- /viewer/freezableset.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The default ES6 Set() class is rather useless, as it doesn't do 3 | * proper equality comparison, no use of keys in a Map(), etc. 4 | * 5 | * This class is a wrapper around such a Set() but with a `frozen' 6 | * getter to convert to String for equality testing. 7 | * 8 | * @class FreezableSet 9 | */ 10 | export class FreezableSet { 11 | constructor(compareFunction) { 12 | this.compareFunction = compareFunction; 13 | this._originalOrderSet = new Set(); 14 | this._set = new Set(); 15 | this._update = true; 16 | this._build(); 17 | this.nonce = 0; 18 | } 19 | 20 | _build() { 21 | let a = Array.from(this._originalOrderSet); 22 | a.sort(this.compareFunction); 23 | // Store the sorted set (Sets do maintain insertion order) 24 | this._set = new Set(a); 25 | this._string = a.join(","); 26 | this.nonce++; 27 | } 28 | 29 | get frozen() { 30 | return this._string; 31 | } 32 | 33 | *[Symbol.iterator]() { 34 | yield* this._set; 35 | } 36 | 37 | get size() { 38 | // Don't know link} from Set.prototype, see if() below 39 | return this._originalOrderSet.size; 40 | } 41 | 42 | batch(fn) { 43 | return new Promise((resolve, reject) => { 44 | this._update = false; 45 | fn().then(() => { 46 | this._build(); 47 | this._update = true; 48 | resolve(); 49 | }); 50 | }); 51 | } 52 | } 53 | 54 | // Hacks to automatically copy over functions} from Set.prototype 55 | let props = Object.getOwnPropertyDescriptors(Set.prototype); 56 | Object.getOwnPropertyNames(Set.prototype).forEach((name) => { 57 | if (!props[name].get) { 58 | FreezableSet.prototype[name] = function(...args) { 59 | let r = this._originalOrderSet[name](...args); 60 | // Rebuild the string representation after every modification 61 | if (this._update && name !== 'has') { 62 | this._build(); 63 | } 64 | return r; 65 | } 66 | } 67 | }) 68 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/readAccessorPacked.js: -------------------------------------------------------------------------------- 1 | import getAccessorByteStride from './getAccessorByteStride.js' 2 | import getComponentReader from './getComponentReader.js' 3 | import numberOfComponentsForType from './numberOfComponentsForType.js' 4 | import arrayFill from '../../Core/arrayFill.js' 5 | import ComponentDatatype from '../../Core/ComponentDatatype.js' 6 | import defined from '../../Core/defined.js' 7 | 8 | /** 9 | * Returns the accessor data in a contiguous array. 10 | * 11 | * @param {Object} gltf A javascript object containing a glTF asset. 12 | * @param {Object} accessor The accessor. 13 | * @returns {Array} The accessor values in a contiguous array. 14 | * 15 | * @private 16 | */ 17 | function readAccessorPacked(gltf, accessor) { 18 | var byteStride = getAccessorByteStride(gltf, accessor); 19 | var componentTypeByteLength = ComponentDatatype.getSizeInBytes(accessor.componentType); 20 | var numberOfComponents = numberOfComponentsForType(accessor.type); 21 | var count = accessor.count; 22 | var values = new Array(numberOfComponents * count); 23 | 24 | if (!defined(accessor.bufferView)) { 25 | arrayFill(values, 0); 26 | return values; 27 | } 28 | 29 | var bufferView = gltf.bufferViews[accessor.bufferView]; 30 | var source = gltf.buffers[bufferView.buffer].extras._pipeline.source; 31 | var byteOffset = accessor.byteOffset + bufferView.byteOffset + source.byteOffset; 32 | 33 | var dataView = new DataView(source.buffer); 34 | var components = new Array(numberOfComponents); 35 | var componentReader = getComponentReader(accessor.componentType); 36 | 37 | for (var i = 0; i < count; ++i) { 38 | componentReader(dataView, byteOffset, numberOfComponents, componentTypeByteLength, components); 39 | for (var j = 0; j < numberOfComponents; ++j) { 40 | values[i * numberOfComponents + j] = components[j]; 41 | } 42 | byteOffset += byteStride; 43 | } 44 | return values; 45 | } 46 | 47 | export default readAccessorPacked; 48 | -------------------------------------------------------------------------------- /viewer/cesium/Core/oneTimeWarning.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | import defined from "./defined.js"; 3 | import DeveloperError from "./DeveloperError.js"; 4 | 5 | var warnings = {}; 6 | 7 | /** 8 | * Logs a one time message to the console. Use this function instead of 9 | * console.log directly since this does not log duplicate messages 10 | * unless it is called from multiple workers. 11 | * 12 | * @function oneTimeWarning 13 | * 14 | * @param {String} identifier The unique identifier for this warning. 15 | * @param {String} [message=identifier] The message to log to the console. 16 | * 17 | * @example 18 | * for(var i=0;i>includeStart('debug', pragmas.debug); 31 | if (!defined(identifier)) { 32 | throw new DeveloperError("identifier is required."); 33 | } 34 | //>>includeEnd('debug'); 35 | 36 | if (!defined(warnings[identifier])) { 37 | warnings[identifier] = true; 38 | console.warn(defaultValue(message, identifier)); 39 | } 40 | } 41 | 42 | oneTimeWarning.geometryOutlines = 43 | "Entity geometry outlines are unsupported on terrain. Outlines will be disabled. To enable outlines, disable geometry terrain clamping by explicitly setting height to 0."; 44 | 45 | oneTimeWarning.geometryZIndex = 46 | "Entity geometry with zIndex are unsupported when height or extrudedHeight are defined. zIndex will be ignored"; 47 | 48 | oneTimeWarning.geometryHeightReference = 49 | "Entity corridor, ellipse, polygon or rectangle with heightReference must also have a defined height. heightReference will be ignored"; 50 | oneTimeWarning.geometryExtrudedHeightReference = 51 | "Entity corridor, ellipse, polygon or rectangle with extrudedHeightReference must also have a defined extrudedHeight. extrudedHeightReference will be ignored"; 52 | export default oneTimeWarning; 53 | -------------------------------------------------------------------------------- /apps/minimal.js: -------------------------------------------------------------------------------- 1 | import {Address} from "./address.js"; 2 | import {BimServerClient} from "../../bimserverjavascriptapi/bimserverclient.js" 3 | import {BimServerViewer} from "../viewer/bimserverviewer.js" 4 | 5 | /* 6 | * This class is where the minimal demo starts. This is intended as an example you can copy-and-paste to start integrating the viewer in your own application. 7 | */ 8 | 9 | export class Minimal { 10 | 11 | constructor() { 12 | // You need to change these to something that makes sense 13 | this.demoSettings = { 14 | // Address of your BIMserver 15 | bimServerAddress: Address.getApiAddress(), 16 | // Login credentials of your BIMserver, obviously you'd never include these for production applications 17 | bimServerLogin: { 18 | username: "admin@bimserver.org", 19 | password: "admin" 20 | }, 21 | // Project ID of the project you want to load the latest revision from 22 | poid: 196609, 23 | // The settings for the viewer 24 | viewerSettings: { 25 | // Not putting anything here will just use the default settings 26 | } 27 | }; 28 | } 29 | 30 | start() { 31 | // Connect to a BIMserver 32 | this.api = new BimServerClient(this.demoSettings.bimServerAddress); 33 | // Initialize the API 34 | this.api.init(() => { 35 | // Login 36 | this.api.login(this.demoSettings.bimServerLogin.username, this.demoSettings.bimServerLogin.password, () => { 37 | // Get the project details 38 | this.api.call("ServiceInterface", "getProjectByPoid", { 39 | poid: this.demoSettings.poid 40 | }, (project) => { 41 | // Select what canvas to bind the viewer to 42 | var canvas = document.getElementById("glcanvas"); 43 | 44 | // Create a new BimServerViewer 45 | this.bimServerViewer = new BimServerViewer(this.demoSettings.viewerSettings, canvas, window.innerWidth, window.innerHeight, null); 46 | 47 | // Load the model 48 | this.bimServerViewer.loadModel(this.api, project); 49 | }, function(error) { 50 | console.error(error.message); 51 | }); 52 | }, function() { 53 | console.error("Error logging-in, probably wrong username/password"); 54 | }); 55 | }); 56 | } 57 | } 58 | 59 | new Minimal().start(); -------------------------------------------------------------------------------- /viewer/cesium/Core/CartographicGeocoderService.js: -------------------------------------------------------------------------------- 1 | import when from "../ThirdParty/when.js"; 2 | import Cartesian3 from "./Cartesian3.js"; 3 | import Check from "./Check.js"; 4 | 5 | /** 6 | * Geocodes queries containing longitude and latitude coordinates and an optional height. 7 | * Query format: `longitude latitude (height)` with longitude/latitude in degrees and height in meters. 8 | * 9 | * @alias CartographicGeocoderService 10 | * @constructor 11 | */ 12 | function CartographicGeocoderService() {} 13 | 14 | /** 15 | * @function 16 | * 17 | * @param {String} query The query to be sent to the geocoder service 18 | * @returns {Promise} 19 | */ 20 | CartographicGeocoderService.prototype.geocode = function (query) { 21 | //>>includeStart('debug', pragmas.debug); 22 | Check.typeOf.string("query", query); 23 | //>>includeEnd('debug'); 24 | 25 | var splitQuery = query.match(/[^\s,\n]+/g); 26 | if (splitQuery.length === 2 || splitQuery.length === 3) { 27 | var longitude = +splitQuery[0]; 28 | var latitude = +splitQuery[1]; 29 | var height = splitQuery.length === 3 ? +splitQuery[2] : 300.0; 30 | 31 | if (isNaN(longitude) && isNaN(latitude)) { 32 | var coordTest = /^(\d+.?\d*)([nsew])/i; 33 | for (var i = 0; i < splitQuery.length; ++i) { 34 | var splitCoord = splitQuery[i].match(coordTest); 35 | if (coordTest.test(splitQuery[i]) && splitCoord.length === 3) { 36 | if (/^[ns]/i.test(splitCoord[2])) { 37 | latitude = /^[n]/i.test(splitCoord[2]) 38 | ? +splitCoord[1] 39 | : -splitCoord[1]; 40 | } else if (/^[ew]/i.test(splitCoord[2])) { 41 | longitude = /^[e]/i.test(splitCoord[2]) 42 | ? +splitCoord[1] 43 | : -splitCoord[1]; 44 | } 45 | } 46 | } 47 | } 48 | 49 | if (!isNaN(longitude) && !isNaN(latitude) && !isNaN(height)) { 50 | var result = { 51 | displayName: query, 52 | destination: Cartesian3.fromDegrees(longitude, latitude, height), 53 | }; 54 | return when.resolve([result]); 55 | } 56 | } 57 | return when.resolve([]); 58 | }; 59 | export default CartographicGeocoderService; 60 | -------------------------------------------------------------------------------- /viewer/cesium/Core/DeveloperError.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | /** 4 | * Constructs an exception object that is thrown due to a developer error, e.g., invalid argument, 5 | * argument out of range, etc. This exception should only be thrown during development; 6 | * it usually indicates a bug in the calling code. This exception should never be 7 | * caught; instead the calling code should strive not to generate it. 8 | *

9 | * On the other hand, a {@link RuntimeError} indicates an exception that may 10 | * be thrown at runtime, e.g., out of memory, that the calling code should be prepared 11 | * to catch. 12 | * 13 | * @alias DeveloperError 14 | * @constructor 15 | * @extends Error 16 | * 17 | * @param {String} [message] The error message for this exception. 18 | * 19 | * @see RuntimeError 20 | */ 21 | function DeveloperError(message) { 22 | /** 23 | * 'DeveloperError' indicating that this exception was thrown due to a developer error. 24 | * @type {String} 25 | * @readonly 26 | */ 27 | this.name = "DeveloperError"; 28 | 29 | /** 30 | * The explanation for why this exception was thrown. 31 | * @type {String} 32 | * @readonly 33 | */ 34 | this.message = message; 35 | 36 | //Browsers such as IE don't have a stack property until you actually throw the error. 37 | var stack; 38 | try { 39 | throw new Error(); 40 | } catch (e) { 41 | stack = e.stack; 42 | } 43 | 44 | /** 45 | * The stack trace of this exception, if available. 46 | * @type {String} 47 | * @readonly 48 | */ 49 | this.stack = stack; 50 | } 51 | 52 | if (defined(Object.create)) { 53 | DeveloperError.prototype = Object.create(Error.prototype); 54 | DeveloperError.prototype.constructor = DeveloperError; 55 | } 56 | 57 | DeveloperError.prototype.toString = function () { 58 | var str = this.name + ": " + this.message; 59 | 60 | if (defined(this.stack)) { 61 | str += "\n" + this.stack.toString(); 62 | } 63 | 64 | return str; 65 | }; 66 | 67 | /** 68 | * @private 69 | */ 70 | DeveloperError.throwInstantiationError = function () { 71 | throw new DeveloperError( 72 | "This function defines an interface and should not be called directly." 73 | ); 74 | }; 75 | export default DeveloperError; 76 | -------------------------------------------------------------------------------- /viewer/cesium/Core/HeadingPitchRange.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | import defined from "./defined.js"; 3 | 4 | /** 5 | * Defines a heading angle, pitch angle, and range in a local frame. 6 | * Heading is the rotation from the local north direction where a positive angle is increasing eastward. 7 | * Pitch is the rotation from the local xy-plane. Positive pitch angles are above the plane. Negative pitch 8 | * angles are below the plane. Range is the distance from the center of the frame. 9 | * @alias HeadingPitchRange 10 | * @constructor 11 | * 12 | * @param {Number} [heading=0.0] The heading angle in radians. 13 | * @param {Number} [pitch=0.0] The pitch angle in radians. 14 | * @param {Number} [range=0.0] The distance from the center in meters. 15 | */ 16 | function HeadingPitchRange(heading, pitch, range) { 17 | /** 18 | * Heading is the rotation from the local north direction where a positive angle is increasing eastward. 19 | * @type {Number} 20 | * @default 0.0 21 | */ 22 | this.heading = defaultValue(heading, 0.0); 23 | 24 | /** 25 | * Pitch is the rotation from the local xy-plane. Positive pitch angles 26 | * are above the plane. Negative pitch angles are below the plane. 27 | * @type {Number} 28 | * @default 0.0 29 | */ 30 | this.pitch = defaultValue(pitch, 0.0); 31 | 32 | /** 33 | * Range is the distance from the center of the local frame. 34 | * @type {Number} 35 | * @default 0.0 36 | */ 37 | this.range = defaultValue(range, 0.0); 38 | } 39 | 40 | /** 41 | * Duplicates a HeadingPitchRange instance. 42 | * 43 | * @param {HeadingPitchRange} hpr The HeadingPitchRange to duplicate. 44 | * @param {HeadingPitchRange} [result] The object onto which to store the result. 45 | * @returns {HeadingPitchRange} The modified result parameter or a new HeadingPitchRange instance if one was not provided. (Returns undefined if hpr is undefined) 46 | */ 47 | HeadingPitchRange.clone = function (hpr, result) { 48 | if (!defined(hpr)) { 49 | return undefined; 50 | } 51 | if (!defined(result)) { 52 | result = new HeadingPitchRange(); 53 | } 54 | 55 | result.heading = hpr.heading; 56 | result.pitch = hpr.pitch; 57 | result.range = hpr.range; 58 | return result; 59 | }; 60 | export default HeadingPitchRange; 61 | -------------------------------------------------------------------------------- /apps/credentials.js: -------------------------------------------------------------------------------- 1 | export class Credentials { 2 | constructor(bimServerApi) { 3 | this.bimServerApi = bimServerApi; 4 | 5 | this.div = document.createElement("div"); 6 | this.div.classList.add("credentials"); 7 | 8 | this.error = document.createElement("div"); 9 | this.div.appendChild(this.error); 10 | 11 | this.usernameInput = document.createElement("input"); 12 | this.passwordInput = document.createElement("input"); 13 | let loginButton = document.createElement("button"); 14 | 15 | loginButton.innerHTML = "Login"; 16 | 17 | let usernameLabel = document.createElement("label"); 18 | usernameLabel.innerHTML = "Username "; 19 | this.div.appendChild(usernameLabel); 20 | usernameLabel.appendChild(this.usernameInput); 21 | 22 | let passwordLabel = document.createElement("label"); 23 | passwordLabel.innerHTML = "Password "; 24 | this.div.appendChild(passwordLabel) 25 | passwordLabel.appendChild(this.passwordInput); 26 | 27 | this.div.appendChild(loginButton); 28 | 29 | let keypressListener = (event) => { 30 | if (event.keyCode == 13) { 31 | this.login(); 32 | } 33 | }; 34 | 35 | this.usernameInput.addEventListener("keypress", keypressListener); 36 | passwordLabel.addEventListener("keypress", keypressListener); 37 | 38 | loginButton.addEventListener("click", () => { 39 | this.login(); 40 | }); 41 | } 42 | 43 | login() { 44 | this.bimServerApi.login(this.usernameInput.value, this.passwordInput.value, () => { 45 | this.div.remove(); 46 | localStorage.setItem("token", this.bimServerApi.token); 47 | this.resolve(); 48 | }, (error) => { 49 | console.error(error); 50 | this.error.innerHTML = error.message; 51 | this.usernameInput.focus(); 52 | }); 53 | } 54 | 55 | getCredentials() { 56 | return new Promise((resolve, reject) => { 57 | let token = localStorage.getItem("token"); 58 | if (token) { 59 | this.bimServerApi.setToken(token, () => { 60 | resolve(); 61 | }, () => { 62 | document.body.appendChild(this.div); 63 | this.usernameInput.focus(); 64 | this.resolve = resolve; 65 | localStorage.removeItem("token") 66 | }); 67 | } else { 68 | document.body.appendChild(this.div); 69 | this.usernameInput.focus(); 70 | this.resolve = resolve; 71 | } 72 | }); 73 | } 74 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/IonGeocoderService.js: -------------------------------------------------------------------------------- 1 | import Check from "./Check.js"; 2 | import Credit from "./Credit.js"; 3 | import defaultValue from "./defaultValue.js"; 4 | import defined from "./defined.js"; 5 | import Ion from "./Ion.js"; 6 | import PeliasGeocoderService from "./PeliasGeocoderService.js"; 7 | import Resource from "./Resource.js"; 8 | 9 | /** 10 | * Provides geocoding through Cesium ion. 11 | * @alias IonGeocoderService 12 | * @constructor 13 | * 14 | * @param {Object} options Object with the following properties: 15 | * @param {Scene} options.scene The scene 16 | * @param {String} [options.accessToken=Ion.defaultAccessToken] The access token to use. 17 | * @param {String|Resource} [options.server=Ion.defaultServer] The resource to the Cesium ion API server. 18 | * 19 | * @see Ion 20 | */ 21 | function IonGeocoderService(options) { 22 | options = defaultValue(options, defaultValue.EMPTY_OBJECT); 23 | 24 | //>>includeStart('debug', pragmas.debug); 25 | Check.typeOf.object("options.scene", options.scene); 26 | //>>includeEnd('debug'); 27 | 28 | var accessToken = defaultValue(options.accessToken, Ion.defaultAccessToken); 29 | var server = Resource.createIfNeeded( 30 | defaultValue(options.server, Ion.defaultServer) 31 | ); 32 | server.appendForwardSlash(); 33 | 34 | var defaultTokenCredit = Ion.getDefaultTokenCredit(accessToken); 35 | if (defined(defaultTokenCredit)) { 36 | options.scene.frameState.creditDisplay.addDefaultCredit( 37 | Credit.clone(defaultTokenCredit) 38 | ); 39 | } 40 | 41 | var searchEndpoint = server.getDerivedResource({ 42 | url: "v1/geocode", 43 | }); 44 | 45 | if (defined(accessToken)) { 46 | searchEndpoint.appendQueryParameters({ access_token: accessToken }); 47 | } 48 | 49 | this._accessToken = accessToken; 50 | this._server = server; 51 | this._pelias = new PeliasGeocoderService(searchEndpoint); 52 | } 53 | 54 | /** 55 | * @function 56 | * 57 | * @param {String} query The query to be sent to the geocoder service 58 | * @param {GeocodeType} [type=GeocodeType.SEARCH] The type of geocode to perform. 59 | * @returns {Promise} 60 | */ 61 | IonGeocoderService.prototype.geocode = function (query, geocodeType) { 62 | return this._pelias.geocode(query, geocodeType); 63 | }; 64 | export default IonGeocoderService; 65 | -------------------------------------------------------------------------------- /viewer/executor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Executor allows to submit jobs for execution. Jobs are queued when the maxJobCount is exceeded. 3 | * 4 | */ 5 | export class Executor { 6 | constructor(maxJobCount) { 7 | this.jobCounter = 0; 8 | 9 | this.jobsToDo = {}; 10 | this.idsToDo = []; 11 | this.jobsRunning = {}; 12 | this.maxJobCount = maxJobCount; 13 | 14 | this.nrRunning = 0; 15 | this.jobsDone = 0; 16 | } 17 | 18 | add(job) { 19 | job.id = this.jobCounter++; 20 | if (this.nrRunning < this.maxJobCount) { 21 | return this.startJob(job); 22 | } 23 | this.jobsToDo[job.id] = job; 24 | this.idsToDo.push(job.id); 25 | return job.promise; 26 | } 27 | 28 | jobDone(job) { 29 | delete this.jobsRunning[job.id]; 30 | this.jobsDone++; 31 | this.nrRunning--; 32 | if (this.nrRunning == 0 && this.idsToDo.length == 0) { 33 | this.done(); 34 | return; 35 | } 36 | if (this.idsToDo.length > 0 && this.nrRunning < this.maxJobCount) { 37 | var jobId = this.idsToDo.splice(0, 1)[0]; 38 | var job = this.jobsToDo[jobId]; 39 | this.startJob(job); 40 | } 41 | } 42 | 43 | updateProgress() { 44 | if (this.progressListener != null) { 45 | this.progressListener(100 * this.jobsDone / this.jobCounter); 46 | } 47 | } 48 | 49 | startJob(job) { 50 | this.jobsRunning[job.id] = job; 51 | this.nrRunning++; 52 | this.updateProgress(); 53 | var r; 54 | var newPromise = new Promise((resolve, reject) => { 55 | r = resolve; 56 | }); 57 | var p = job.start(); 58 | p.then(() => { 59 | r(); 60 | this.jobDone(job); 61 | }); 62 | return newPromise; 63 | } 64 | 65 | done() { 66 | if (this.resolve != null) { 67 | this.resolve(); 68 | } 69 | } 70 | 71 | /* 72 | * Will fire a promise when all jobs are done, a problem with this atm is that it should fire after all handlers of the tasks its promise have been handled, not sure how to do that 73 | */ 74 | awaitTermination() { 75 | if (this.terminationPromise == null) { 76 | this.terminationPromise = new Promise((resolve, reject) => { 77 | this.resolve = resolve; 78 | }); 79 | } 80 | return this.terminationPromise; 81 | } 82 | 83 | setProgressListener(progressListener) { 84 | this.progressListener = progressListener; 85 | } 86 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/binarySearch.js: -------------------------------------------------------------------------------- 1 | import Check from "./Check.js"; 2 | 3 | /** 4 | * Finds an item in a sorted array. 5 | * 6 | * @function 7 | * @param {Array} array The sorted array to search. 8 | * @param {*} itemToFind The item to find in the array. 9 | * @param {binarySearchComparator} comparator The function to use to compare the item to 10 | * elements in the array. 11 | * @returns {Number} The index of itemToFind in the array, if it exists. If itemToFind 12 | * does not exist, the return value is a negative number which is the bitwise complement (~) 13 | * of the index before which the itemToFind should be inserted in order to maintain the 14 | * sorted order of the array. 15 | * 16 | * @example 17 | * // Create a comparator function to search through an array of numbers. 18 | * function comparator(a, b) { 19 | * return a - b; 20 | * }; 21 | * var numbers = [0, 2, 4, 6, 8]; 22 | * var index = Cesium.binarySearch(numbers, 6, comparator); // 3 23 | */ 24 | function binarySearch(array, itemToFind, comparator) { 25 | //>>includeStart('debug', pragmas.debug); 26 | Check.defined("array", array); 27 | Check.defined("itemToFind", itemToFind); 28 | Check.defined("comparator", comparator); 29 | //>>includeEnd('debug'); 30 | 31 | var low = 0; 32 | var high = array.length - 1; 33 | var i; 34 | var comparison; 35 | 36 | while (low <= high) { 37 | i = ~~((low + high) / 2); 38 | comparison = comparator(array[i], itemToFind); 39 | if (comparison < 0) { 40 | low = i + 1; 41 | continue; 42 | } 43 | if (comparison > 0) { 44 | high = i - 1; 45 | continue; 46 | } 47 | return i; 48 | } 49 | return ~(high + 1); 50 | } 51 | 52 | /** 53 | * A function used to compare two items while performing a binary search. 54 | * @callback binarySearchComparator 55 | * 56 | * @param {*} a An item in the array. 57 | * @param {*} b The item being searched for. 58 | * @returns {Number} Returns a negative value if a is less than b, 59 | * a positive value if a is greater than b, or 60 | * 0 if a is equal to b. 61 | * 62 | * @example 63 | * function compareNumbers(a, b) { 64 | * return a - b; 65 | * } 66 | */ 67 | export default binarySearch; 68 | -------------------------------------------------------------------------------- /viewer/cesium/Core/MapProjection.js: -------------------------------------------------------------------------------- 1 | import DeveloperError from "./DeveloperError.js"; 2 | 3 | /** 4 | * Defines how geodetic ellipsoid coordinates ({@link Cartographic}) project to a 5 | * flat map like Cesium's 2D and Columbus View modes. 6 | * 7 | * @alias MapProjection 8 | * @constructor 9 | * 10 | * @see GeographicProjection 11 | * @see WebMercatorProjection 12 | */ 13 | function MapProjection() { 14 | DeveloperError.throwInstantiationError(); 15 | } 16 | 17 | Object.defineProperties(MapProjection.prototype, { 18 | /** 19 | * Gets the {@link Ellipsoid}. 20 | * 21 | * @memberof MapProjection.prototype 22 | * 23 | * @type {Ellipsoid} 24 | * @readonly 25 | */ 26 | ellipsoid: { 27 | get: DeveloperError.throwInstantiationError, 28 | }, 29 | }); 30 | 31 | /** 32 | * Projects {@link Cartographic} coordinates, in radians, to projection-specific map coordinates, in meters. 33 | * 34 | * @memberof MapProjection 35 | * @function 36 | * 37 | * @param {Cartographic} cartographic The coordinates to project. 38 | * @param {Cartesian3} [result] An instance into which to copy the result. If this parameter is 39 | * undefined, a new instance is created and returned. 40 | * @returns {Cartesian3} The projected coordinates. If the result parameter is not undefined, the 41 | * coordinates are copied there and that instance is returned. Otherwise, a new instance is 42 | * created and returned. 43 | */ 44 | MapProjection.prototype.project = DeveloperError.throwInstantiationError; 45 | 46 | /** 47 | * Unprojects projection-specific map {@link Cartesian3} coordinates, in meters, to {@link Cartographic} 48 | * coordinates, in radians. 49 | * 50 | * @memberof MapProjection 51 | * @function 52 | * 53 | * @param {Cartesian3} cartesian The Cartesian position to unproject with height (z) in meters. 54 | * @param {Cartographic} [result] An instance into which to copy the result. If this parameter is 55 | * undefined, a new instance is created and returned. 56 | * @returns {Cartographic} The unprojected coordinates. If the result parameter is not undefined, the 57 | * coordinates are copied there and that instance is returned. Otherwise, a new instance is 58 | * created and returned. 59 | */ 60 | MapProjection.prototype.unproject = DeveloperError.throwInstantiationError; 61 | export default MapProjection; 62 | -------------------------------------------------------------------------------- /viewer/cesium/Core/GeometryAttributes.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | 3 | /** 4 | * Attributes, which make up a geometry's vertices. Each property in this object corresponds to a 5 | * {@link GeometryAttribute} containing the attribute's data. 6 | *

7 | * Attributes are always stored non-interleaved in a Geometry. 8 | *

9 | * 10 | * @alias GeometryAttributes 11 | * @constructor 12 | */ 13 | function GeometryAttributes(options) { 14 | options = defaultValue(options, defaultValue.EMPTY_OBJECT); 15 | 16 | /** 17 | * The 3D position attribute. 18 | *

19 | * 64-bit floating-point (for precision). 3 components per attribute. 20 | *

21 | * 22 | * @type GeometryAttribute 23 | * 24 | * @default undefined 25 | */ 26 | this.position = options.position; 27 | 28 | /** 29 | * The normal attribute (normalized), which is commonly used for lighting. 30 | *

31 | * 32-bit floating-point. 3 components per attribute. 32 | *

33 | * 34 | * @type GeometryAttribute 35 | * 36 | * @default undefined 37 | */ 38 | this.normal = options.normal; 39 | 40 | /** 41 | * The 2D texture coordinate attribute. 42 | *

43 | * 32-bit floating-point. 2 components per attribute 44 | *

45 | * 46 | * @type GeometryAttribute 47 | * 48 | * @default undefined 49 | */ 50 | this.st = options.st; 51 | 52 | /** 53 | * The bitangent attribute (normalized), which is used for tangent-space effects like bump mapping. 54 | *

55 | * 32-bit floating-point. 3 components per attribute. 56 | *

57 | * 58 | * @type GeometryAttribute 59 | * 60 | * @default undefined 61 | */ 62 | this.bitangent = options.bitangent; 63 | 64 | /** 65 | * The tangent attribute (normalized), which is used for tangent-space effects like bump mapping. 66 | *

67 | * 32-bit floating-point. 3 components per attribute. 68 | *

69 | * 70 | * @type GeometryAttribute 71 | * 72 | * @default undefined 73 | */ 74 | this.tangent = options.tangent; 75 | 76 | /** 77 | * The color attribute. 78 | *

79 | * 8-bit unsigned integer. 4 components per attribute. 80 | *

81 | * 82 | * @type GeometryAttribute 83 | * 84 | * @default undefined 85 | */ 86 | this.color = options.color; 87 | } 88 | export default GeometryAttributes; 89 | -------------------------------------------------------------------------------- /viewer/cesium/ThirdParty/GltfPipeline/updateAccessorComponentTypes.js: -------------------------------------------------------------------------------- 1 | import addBuffer from './addBuffer.js' 2 | import ForEach from './ForEach.js' 3 | import readAccessorPacked from './readAccessorPacked.js' 4 | import ComponentDatatype from '../../Core/ComponentDatatype.js' 5 | import WebGLConstants from '../../Core/WebGLConstants.js' 6 | 7 | /** 8 | * Update accessors referenced by JOINTS_0 and WEIGHTS_0 attributes to use correct component types. 9 | * 10 | * @param {Object} gltf A javascript object containing a glTF asset. 11 | * @returns {Object} The glTF asset with compressed meshes. 12 | * 13 | * @private 14 | */ 15 | function updateAccessorComponentTypes(gltf) { 16 | var componentType; 17 | ForEach.accessorWithSemantic(gltf, 'JOINTS_0', function(accessorId) { 18 | var accessor = gltf.accessors[accessorId]; 19 | componentType = accessor.componentType; 20 | if (componentType === WebGLConstants.BYTE) { 21 | convertType(gltf, accessor, ComponentDatatype.UNSIGNED_BYTE); 22 | } else if (componentType !== WebGLConstants.UNSIGNED_BYTE 23 | && componentType !== WebGLConstants.UNSIGNED_SHORT) { 24 | convertType(gltf, accessor, ComponentDatatype.UNSIGNED_SHORT); 25 | } 26 | }); 27 | ForEach.accessorWithSemantic(gltf, 'WEIGHTS_0', function(accessorId) { 28 | var accessor = gltf.accessors[accessorId]; 29 | componentType = accessor.componentType; 30 | if (componentType === WebGLConstants.BYTE) { 31 | convertType(gltf, accessor, ComponentDatatype.UNSIGNED_BYTE); 32 | } else if (componentType === WebGLConstants.SHORT) { 33 | convertType(gltf, accessor, ComponentDatatype.UNSIGNED_SHORT); 34 | } 35 | }); 36 | 37 | return gltf; 38 | } 39 | 40 | function convertType(gltf, accessor, updatedComponentType) { 41 | var typedArray = ComponentDatatype.createTypedArray(updatedComponentType, readAccessorPacked(gltf, accessor)); 42 | var newBuffer = new Uint8Array(typedArray.buffer); 43 | accessor.bufferView = addBuffer(gltf, newBuffer); 44 | accessor.componentType = updatedComponentType; 45 | accessor.byteOffset = 0; 46 | } 47 | 48 | export default updateAccessorComponentTypes; 49 | -------------------------------------------------------------------------------- /viewer/cesium/Core/EventHelper.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import DeveloperError from "./DeveloperError.js"; 3 | 4 | /** 5 | * A convenience object that simplifies the common pattern of attaching event listeners 6 | * to several events, then removing all those listeners at once later, for example, in 7 | * a destroy method. 8 | * 9 | * @alias EventHelper 10 | * @constructor 11 | * 12 | * 13 | * @example 14 | * var helper = new Cesium.EventHelper(); 15 | * 16 | * helper.add(someObject.event, listener1, this); 17 | * helper.add(otherObject.event, listener2, this); 18 | * 19 | * // later... 20 | * helper.removeAll(); 21 | * 22 | * @see Event 23 | */ 24 | function EventHelper() { 25 | this._removalFunctions = []; 26 | } 27 | 28 | /** 29 | * Adds a listener to an event, and records the registration to be cleaned up later. 30 | * 31 | * @param {Event} event The event to attach to. 32 | * @param {Function} listener The function to be executed when the event is raised. 33 | * @param {Object} [scope] An optional object scope to serve as the this 34 | * pointer in which the listener function will execute. 35 | * @returns {EventHelper.RemoveCallback} A function that will remove this event listener when invoked. 36 | * 37 | * @see Event#addEventListener 38 | */ 39 | EventHelper.prototype.add = function (event, listener, scope) { 40 | //>>includeStart('debug', pragmas.debug); 41 | if (!defined(event)) { 42 | throw new DeveloperError("event is required"); 43 | } 44 | //>>includeEnd('debug'); 45 | 46 | var removalFunction = event.addEventListener(listener, scope); 47 | this._removalFunctions.push(removalFunction); 48 | 49 | var that = this; 50 | return function () { 51 | removalFunction(); 52 | var removalFunctions = that._removalFunctions; 53 | removalFunctions.splice(removalFunctions.indexOf(removalFunction), 1); 54 | }; 55 | }; 56 | 57 | /** 58 | * Unregisters all previously added listeners. 59 | * 60 | * @see Event#removeEventListener 61 | */ 62 | EventHelper.prototype.removeAll = function () { 63 | var removalFunctions = this._removalFunctions; 64 | for (var i = 0, len = removalFunctions.length; i < len; ++i) { 65 | removalFunctions[i](); 66 | } 67 | removalFunctions.length = 0; 68 | }; 69 | 70 | /** 71 | * A function that removes a listener. 72 | * @callback EventHelper.RemoveCallback 73 | */ 74 | export default EventHelper; 75 | -------------------------------------------------------------------------------- /viewer/buffersetpool.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Keeps track of a collections of buffersets that can be reused. The main reason is that we don't have to allocate new memory for each new bufferset 3 | */ 4 | export class BufferSetPool { 5 | constructor(maxPoolSize, stats) { 6 | this.maxPoolSize = maxPoolSize; 7 | this.stats = stats; 8 | 9 | this.currentPoolSize = 0; 10 | 11 | this.available = new Set(); 12 | this.used = new Set(); 13 | 14 | window.buffersetpool = this; 15 | } 16 | 17 | lease(bufferManager, hasTransparency, color, sizes) { 18 | if (this.currentPoolSize >= this.maxPoolSize) { 19 | throw "Maximum pool size exceeded"; 20 | } 21 | 22 | if (this.available.size > 0) { 23 | var bufferSet = this.available.keys().next().value; 24 | this.used.add(bufferSet); 25 | this.available.delete(bufferSet); 26 | this.stats.setParameter("BufferSet pool", "Used", this.used.size); 27 | this.stats.setParameter("BufferSet pool", "Available", this.available.size); 28 | this.stats.setParameter("BufferSet pool", "Total memory", this.currentPoolSize * bufferManager.getDefaultByteSize()); 29 | 30 | return bufferSet; 31 | } 32 | var newBufferSet = bufferManager.createBufferSet(hasTransparency, color, sizes); 33 | this.currentPoolSize++; 34 | this.used.add(newBufferSet); 35 | this.stats.setParameter("BufferSet pool", "Used", this.used.size); 36 | this.stats.setParameter("BufferSet pool", "Available", this.available.size); 37 | this.stats.setParameter("BufferSet pool", "Total memory", this.currentPoolSize * bufferManager.getDefaultByteSize()); 38 | return newBufferSet; 39 | } 40 | 41 | release(bufferSet) { 42 | this.used.delete(bufferSet); 43 | this.available.add(bufferSet); 44 | 45 | this.stats.setParameter("BufferSet pool", "Used", this.used.size); 46 | this.stats.setParameter("BufferSet pool", "Available", this.available.size); 47 | 48 | bufferSet.positionsIndex = 0; 49 | bufferSet.normalsIndex = 0; 50 | bufferSet.indicesIndex = 0; 51 | bufferSet.nrIndices = 0; 52 | bufferSet.colorsIndex = 0; 53 | } 54 | 55 | cleanup() { 56 | this.available.clear(); 57 | this.used.clear(); 58 | this.currentPoolSize = 0; 59 | this.stats.setParameter("BufferSet pool", "Used", this.used.size); 60 | this.stats.setParameter("BufferSet pool", "Available", this.available.size); 61 | this.stats.setParameter("BufferSet pool", "Total memory", 0); 62 | } 63 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/GregorianDate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents a Gregorian date in a more precise format than the JavaScript Date object. 3 | * In addition to submillisecond precision, this object can also represent leap seconds. 4 | * @alias GregorianDate 5 | * @constructor 6 | * 7 | * @param {Number} [year] The year as a whole number. 8 | * @param {Number} [month] The month as a whole number with range [1, 12]. 9 | * @param {Number} [day] The day of the month as a whole number starting at 1. 10 | * @param {Number} [hour] The hour as a whole number with range [0, 23]. 11 | * @param {Number} [minute] The minute of the hour as a whole number with range [0, 59]. 12 | * @param {Number} [second] The second of the minute as a whole number with range [0, 60], with 60 representing a leap second. 13 | * @param {Number} [millisecond] The millisecond of the second as a floating point number with range [0.0, 1000.0). 14 | * @param {Boolean} [isLeapSecond] Whether this time is during a leap second. 15 | * 16 | * @see JulianDate#toGregorianDate 17 | */ 18 | function GregorianDate( 19 | year, 20 | month, 21 | day, 22 | hour, 23 | minute, 24 | second, 25 | millisecond, 26 | isLeapSecond 27 | ) { 28 | /** 29 | * Gets or sets the year as a whole number. 30 | * @type {Number} 31 | */ 32 | this.year = year; 33 | /** 34 | * Gets or sets the month as a whole number with range [1, 12]. 35 | * @type {Number} 36 | */ 37 | this.month = month; 38 | /** 39 | * Gets or sets the day of the month as a whole number starting at 1. 40 | * @type {Number} 41 | */ 42 | this.day = day; 43 | /** 44 | * Gets or sets the hour as a whole number with range [0, 23]. 45 | * @type {Number} 46 | */ 47 | this.hour = hour; 48 | /** 49 | * Gets or sets the minute of the hour as a whole number with range [0, 59]. 50 | * @type {Number} 51 | */ 52 | this.minute = minute; 53 | /** 54 | * Gets or sets the second of the minute as a whole number with range [0, 60], with 60 representing a leap second. 55 | * @type {Number} 56 | */ 57 | this.second = second; 58 | /** 59 | * Gets or sets the millisecond of the second as a floating point number with range [0.0, 1000.0). 60 | * @type {Number} 61 | */ 62 | this.millisecond = millisecond; 63 | /** 64 | * Gets or sets whether this time is during a leap second. 65 | * @type {Boolean} 66 | */ 67 | this.isLeapSecond = isLeapSecond; 68 | } 69 | export default GregorianDate; 70 | -------------------------------------------------------------------------------- /viewer/cesium/Core/combine.js: -------------------------------------------------------------------------------- 1 | import defaultValue from "./defaultValue.js"; 2 | import defined from "./defined.js"; 3 | 4 | /** 5 | * Merges two objects, copying their properties onto a new combined object. When two objects have the same 6 | * property, the value of the property on the first object is used. If either object is undefined, 7 | * it will be treated as an empty object. 8 | * 9 | * @example 10 | * var object1 = { 11 | * propOne : 1, 12 | * propTwo : { 13 | * value1 : 10 14 | * } 15 | * } 16 | * var object2 = { 17 | * propTwo : 2 18 | * } 19 | * var final = Cesium.combine(object1, object2); 20 | * 21 | * // final === { 22 | * // propOne : 1, 23 | * // propTwo : { 24 | * // value1 : 10 25 | * // } 26 | * // } 27 | * 28 | * @param {Object} [object1] The first object to merge. 29 | * @param {Object} [object2] The second object to merge. 30 | * @param {Boolean} [deep=false] Perform a recursive merge. 31 | * @returns {Object} The combined object containing all properties from both objects. 32 | * 33 | * @function 34 | */ 35 | function combine(object1, object2, deep) { 36 | deep = defaultValue(deep, false); 37 | 38 | var result = {}; 39 | 40 | var object1Defined = defined(object1); 41 | var object2Defined = defined(object2); 42 | var property; 43 | var object1Value; 44 | var object2Value; 45 | if (object1Defined) { 46 | for (property in object1) { 47 | if (object1.hasOwnProperty(property)) { 48 | object1Value = object1[property]; 49 | if ( 50 | object2Defined && 51 | deep && 52 | typeof object1Value === "object" && 53 | object2.hasOwnProperty(property) 54 | ) { 55 | object2Value = object2[property]; 56 | if (typeof object2Value === "object") { 57 | result[property] = combine(object1Value, object2Value, deep); 58 | } else { 59 | result[property] = object1Value; 60 | } 61 | } else { 62 | result[property] = object1Value; 63 | } 64 | } 65 | } 66 | } 67 | if (object2Defined) { 68 | for (property in object2) { 69 | if ( 70 | object2.hasOwnProperty(property) && 71 | !result.hasOwnProperty(property) 72 | ) { 73 | object2Value = object2[property]; 74 | result[property] = object2Value; 75 | } 76 | } 77 | } 78 | return result; 79 | } 80 | export default combine; 81 | -------------------------------------------------------------------------------- /viewer/cesium/Core/TranslationRotationScale.js: -------------------------------------------------------------------------------- 1 | import Cartesian3 from "./Cartesian3.js"; 2 | import defaultValue from "./defaultValue.js"; 3 | import defined from "./defined.js"; 4 | import Quaternion from "./Quaternion.js"; 5 | 6 | var defaultScale = new Cartesian3(1.0, 1.0, 1.0); 7 | var defaultTranslation = Cartesian3.ZERO; 8 | var defaultRotation = Quaternion.IDENTITY; 9 | 10 | /** 11 | * An affine transformation defined by a translation, rotation, and scale. 12 | * @alias TranslationRotationScale 13 | * @constructor 14 | * 15 | * @param {Cartesian3} [translation=Cartesian3.ZERO] A {@link Cartesian3} specifying the (x, y, z) translation to apply to the node. 16 | * @param {Quaternion} [rotation=Quaternion.IDENTITY] A {@link Quaternion} specifying the (x, y, z, w) rotation to apply to the node. 17 | * @param {Cartesian3} [scale=new Cartesian3(1.0, 1.0, 1.0)] A {@link Cartesian3} specifying the (x, y, z) scaling to apply to the node. 18 | */ 19 | function TranslationRotationScale(translation, rotation, scale) { 20 | /** 21 | * Gets or sets the (x, y, z) translation to apply to the node. 22 | * @type {Cartesian3} 23 | * @default Cartesian3.ZERO 24 | */ 25 | this.translation = Cartesian3.clone( 26 | defaultValue(translation, defaultTranslation) 27 | ); 28 | 29 | /** 30 | * Gets or sets the (x, y, z, w) rotation to apply to the node. 31 | * @type {Quaternion} 32 | * @default Quaternion.IDENTITY 33 | */ 34 | this.rotation = Quaternion.clone(defaultValue(rotation, defaultRotation)); 35 | 36 | /** 37 | * Gets or sets the (x, y, z) scaling to apply to the node. 38 | * @type {Cartesian3} 39 | * @default new Cartesian3(1.0, 1.0, 1.0) 40 | */ 41 | this.scale = Cartesian3.clone(defaultValue(scale, defaultScale)); 42 | } 43 | 44 | /** 45 | * Compares this instance against the provided instance and returns 46 | * true if they are equal, false otherwise. 47 | * 48 | * @param {TranslationRotationScale} [right] The right hand side TranslationRotationScale. 49 | * @returns {Boolean} true if they are equal, false otherwise. 50 | */ 51 | TranslationRotationScale.prototype.equals = function (right) { 52 | return ( 53 | this === right || 54 | (defined(right) && 55 | Cartesian3.equals(this.translation, right.translation) && 56 | Quaternion.equals(this.rotation, right.rotation) && 57 | Cartesian3.equals(this.scale, right.scale)) 58 | ); 59 | }; 60 | export default TranslationRotationScale; 61 | -------------------------------------------------------------------------------- /viewer/cesium/Core/LagrangePolynomialApproximation.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | /** 4 | * An {@link InterpolationAlgorithm} for performing Lagrange interpolation. 5 | * 6 | * @namespace LagrangePolynomialApproximation 7 | */ 8 | var LagrangePolynomialApproximation = { 9 | type: "Lagrange", 10 | }; 11 | 12 | /** 13 | * Given the desired degree, returns the number of data points required for interpolation. 14 | * 15 | * @param {Number} degree The desired degree of interpolation. 16 | * @returns {Number} The number of required data points needed for the desired degree of interpolation. 17 | */ 18 | LagrangePolynomialApproximation.getRequiredDataPoints = function (degree) { 19 | return Math.max(degree + 1.0, 2); 20 | }; 21 | 22 | /** 23 | * Interpolates values using Lagrange Polynomial Approximation. 24 | * 25 | * @param {Number} x The independent variable for which the dependent variables will be interpolated. 26 | * @param {Number[]} xTable The array of independent variables to use to interpolate. The values 27 | * in this array must be in increasing order and the same value must not occur twice in the array. 28 | * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three 29 | * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. 30 | * @param {Number} yStride The number of dependent variable values in yTable corresponding to 31 | * each independent variable value in xTable. 32 | * @param {Number[]} [result] An existing array into which to store the result. 33 | * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. 34 | */ 35 | LagrangePolynomialApproximation.interpolateOrderZero = function ( 36 | x, 37 | xTable, 38 | yTable, 39 | yStride, 40 | result 41 | ) { 42 | if (!defined(result)) { 43 | result = new Array(yStride); 44 | } 45 | 46 | var i; 47 | var j; 48 | var length = xTable.length; 49 | 50 | for (i = 0; i < yStride; i++) { 51 | result[i] = 0; 52 | } 53 | 54 | for (i = 0; i < length; i++) { 55 | var coefficient = 1; 56 | 57 | for (j = 0; j < length; j++) { 58 | if (j !== i) { 59 | var diffX = xTable[i] - xTable[j]; 60 | coefficient *= (x - xTable[j]) / diffX; 61 | } 62 | } 63 | 64 | for (j = 0; j < yStride; j++) { 65 | result[j] += coefficient * yTable[i * yStride + j]; 66 | } 67 | } 68 | 69 | return result; 70 | }; 71 | export default LagrangePolynomialApproximation; 72 | -------------------------------------------------------------------------------- /css/apps.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | padding: 0; 4 | height: 100%; 5 | font-size: medium; 6 | } 7 | 8 | #canvasWrapper, canvas.full { 9 | width: 100%; 10 | height: 100%; 11 | } 12 | 13 | #viewerOverlay { 14 | pointer-events: none; 15 | } 16 | 17 | #viewerOverlay circle { 18 | fill: white; 19 | stroke: black; 20 | fill-opacity: 0.4; 21 | } 22 | 23 | canvas { 24 | display: block; 25 | } 26 | 27 | #glcanvas { 28 | } 29 | 30 | #viewer { 31 | position: absolute; 32 | width: 100%; 33 | height: 100%; 34 | } 35 | 36 | #overlay { 37 | } 38 | 39 | #overlay h3 { 40 | font-size: small; 41 | color: dark-gray; 42 | margin-bottom: 0; 43 | } 44 | 45 | #overlay { 46 | z-index: 10; 47 | position: absolute; 48 | background: rgba(200, 200, 255, 0.2); 49 | width: 20%; 50 | height: 100%; 51 | overflow: auto; 52 | } 53 | 54 | #settings .link, #settings .link * { 55 | cursor: pointer; 56 | } 57 | 58 | #inside { 59 | margin: 20px; 60 | } 61 | 62 | a { 63 | cursor: pointer; 64 | } 65 | 66 | #progressbar { 67 | left: 20%; 68 | position: absolute; 69 | bottom: 0px; 70 | height: 10px; 71 | width: 80%; 72 | background-color: transparent; 73 | margin: 0; 74 | padding: 0; 75 | } 76 | 77 | #progress { 78 | width: 0px; 79 | background-color: rgba(100,149,237,0.5); 80 | height: 100%; 81 | } 82 | 83 | #settingsContainer { 84 | z-index: 10; 85 | position: absolute; 86 | right: 0px; 87 | width: 400px; 88 | background: rgba(200, 200, 255, 0.2); 89 | padding: 10px; 90 | } 91 | 92 | #settings input { 93 | width: 100px; 94 | } 95 | 96 | .arrow { 97 | width: 16px; 98 | height: 16px; 99 | } 100 | 101 | .arrow:hover { 102 | cursor: pointer; 103 | } 104 | 105 | .arrowclosed { 106 | background-image: url("../img/black_arrow.png"); 107 | } 108 | 109 | .arrowclosed:hover { 110 | background-image: url("../img/blue_arrow.png"); 111 | } 112 | 113 | .arrowopen { 114 | background-image: url("../img/black_arrow_down.png"); 115 | } 116 | 117 | .arrowopen:hover { 118 | background-image: url("../img/blue_arrow_down.png"); 119 | } 120 | 121 | .wrapper { 122 | display: grid; 123 | grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 124 | } 125 | 126 | .serverstatus { 127 | width: 100px; 128 | } 129 | 130 | .serverstatus.up { 131 | background: green; 132 | } 133 | 134 | .serverstatus.down { 135 | background: red; 136 | } 137 | 138 | .credentials { 139 | position: fixed; 140 | left: 100px; 141 | top: 100px; 142 | width: 300px; 143 | height: 300px; 144 | } 145 | 146 | .credentials label { 147 | display: block; 148 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/PrimitiveType.js: -------------------------------------------------------------------------------- 1 | import WebGLConstants from "./WebGLConstants.js"; 2 | 3 | /** 4 | * The type of a geometric primitive, i.e., points, lines, and triangles. 5 | * 6 | * @enum {Number} 7 | */ 8 | var PrimitiveType = { 9 | /** 10 | * Points primitive where each vertex (or index) is a separate point. 11 | * 12 | * @type {Number} 13 | * @constant 14 | */ 15 | POINTS: WebGLConstants.POINTS, 16 | 17 | /** 18 | * Lines primitive where each two vertices (or indices) is a line segment. Line segments are not necessarily connected. 19 | * 20 | * @type {Number} 21 | * @constant 22 | */ 23 | LINES: WebGLConstants.LINES, 24 | 25 | /** 26 | * Line loop primitive where each vertex (or index) after the first connects a line to 27 | * the previous vertex, and the last vertex implicitly connects to the first. 28 | * 29 | * @type {Number} 30 | * @constant 31 | */ 32 | LINE_LOOP: WebGLConstants.LINE_LOOP, 33 | 34 | /** 35 | * Line strip primitive where each vertex (or index) after the first connects a line to the previous vertex. 36 | * 37 | * @type {Number} 38 | * @constant 39 | */ 40 | LINE_STRIP: WebGLConstants.LINE_STRIP, 41 | 42 | /** 43 | * Triangles primitive where each three vertices (or indices) is a triangle. Triangles do not necessarily share edges. 44 | * 45 | * @type {Number} 46 | * @constant 47 | */ 48 | TRIANGLES: WebGLConstants.TRIANGLES, 49 | 50 | /** 51 | * Triangle strip primitive where each vertex (or index) after the first two connect to 52 | * the previous two vertices forming a triangle. For example, this can be used to model a wall. 53 | * 54 | * @type {Number} 55 | * @constant 56 | */ 57 | TRIANGLE_STRIP: WebGLConstants.TRIANGLE_STRIP, 58 | 59 | /** 60 | * Triangle fan primitive where each vertex (or index) after the first two connect to 61 | * the previous vertex and the first vertex forming a triangle. For example, this can be used 62 | * to model a cone or circle. 63 | * 64 | * @type {Number} 65 | * @constant 66 | */ 67 | TRIANGLE_FAN: WebGLConstants.TRIANGLE_FAN, 68 | }; 69 | 70 | /** 71 | * @private 72 | */ 73 | PrimitiveType.validate = function (primitiveType) { 74 | return ( 75 | primitiveType === PrimitiveType.POINTS || 76 | primitiveType === PrimitiveType.LINES || 77 | primitiveType === PrimitiveType.LINE_LOOP || 78 | primitiveType === PrimitiveType.LINE_STRIP || 79 | primitiveType === PrimitiveType.TRIANGLES || 80 | primitiveType === PrimitiveType.TRIANGLE_STRIP || 81 | primitiveType === PrimitiveType.TRIANGLE_FAN 82 | ); 83 | }; 84 | 85 | export default Object.freeze(PrimitiveType); 86 | -------------------------------------------------------------------------------- /viewer/lighting.js: -------------------------------------------------------------------------------- 1 | import * as mat4 from "./glmatrix/mat4.js"; 2 | import * as vec3 from "./glmatrix/vec3.js"; 3 | 4 | /** 5 | * Configures the viewer's light sources. 6 | * @todo This class's API will probably change as we add ability to configure multiple light sources. 7 | */ 8 | export class Lighting { 9 | 10 | constructor(viewer) { 11 | 12 | this.viewer = viewer; 13 | this._dir = new Float32Array([-0.3, -0.7, -1.0]); 14 | vec3.normalize(this._dir, this._dir); 15 | this._color = new Float32Array([0.4, 0.4, 0.4]); 16 | this._ambientColor = new Float32Array([0.3, 0.3, 0.3]); 17 | this._intensity = 0.5; 18 | this._bufferData = new Float32Array(52); 19 | this._buffer = null; 20 | 21 | this._setDirty(); 22 | } 23 | 24 | _setDirty() { 25 | this._dirty = true; 26 | this.viewer.dirty = 2; 27 | } 28 | 29 | _update() { 30 | if (!this._dirty) { 31 | return; 32 | 33 | } 34 | var bufferData = this._bufferData; 35 | 36 | bufferData[0] = this._dir[0]; 37 | bufferData[1] = this._dir[1]; 38 | bufferData[2] = this._dir[2]; 39 | bufferData[3] = 0; // unused 40 | bufferData[4] = this._color[0]; 41 | bufferData[5] = this._color[1]; 42 | bufferData[6] = this._color[2]; 43 | bufferData[7] = 0; // unused 44 | bufferData[8] = this._ambientColor[0]; 45 | bufferData[9] = this._ambientColor[1]; 46 | bufferData[10] = this._ambientColor[2]; 47 | bufferData[11] = 0; // unused; 48 | bufferData[12] = this._intensity; 49 | 50 | var gl = this.viewer.gl; 51 | 52 | this._buffer = gl.createBuffer(); 53 | gl.bindBuffer(gl.UNIFORM_BUFFER, this._buffer); 54 | gl.bufferData(gl.UNIFORM_BUFFER, bufferData, gl.DYNAMIC_DRAW, 0, 52); 55 | 56 | this._dirty = false; 57 | } 58 | 59 | setDir(dir) { 60 | this._dir.set(dir); 61 | this._setDirty(); 62 | } 63 | 64 | setColor(color) { 65 | this._color.set(color); 66 | this._setDirty(); 67 | } 68 | 69 | setAmbientColor(ambientColor) { 70 | this._ambientColor.set(ambientColor); 71 | this._setDirty(); 72 | } 73 | 74 | setIntensity(intensity) { 75 | this._intensity = intensity; 76 | this._setDirty(); 77 | } 78 | 79 | render(uniformBlockLocation) { 80 | if (this._dirty) { 81 | this._update(); 82 | } 83 | this.viewer.gl.bindBufferBase(this.viewer.gl.UNIFORM_BUFFER, uniformBlockLocation, this._buffer); 84 | } 85 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/CompressedTextureBuffer.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | /** 4 | * Describes a compressed texture and contains a compressed texture buffer. 5 | * @alias CompressedTextureBuffer 6 | * @constructor 7 | * 8 | * @param {PixelFormat} internalFormat The pixel format of the compressed texture. 9 | * @param {Number} width The width of the texture. 10 | * @param {Number} height The height of the texture. 11 | * @param {Uint8Array} buffer The compressed texture buffer. 12 | */ 13 | function CompressedTextureBuffer(internalFormat, width, height, buffer) { 14 | this._format = internalFormat; 15 | this._width = width; 16 | this._height = height; 17 | this._buffer = buffer; 18 | } 19 | 20 | Object.defineProperties(CompressedTextureBuffer.prototype, { 21 | /** 22 | * The format of the compressed texture. 23 | * @type PixelFormat 24 | * @readonly 25 | * @memberof CompressedTextureBuffer.prototype 26 | */ 27 | internalFormat: { 28 | get: function () { 29 | return this._format; 30 | }, 31 | }, 32 | /** 33 | * The width of the texture. 34 | * @type Number 35 | * @readonly 36 | * @memberof CompressedTextureBuffer.prototype 37 | */ 38 | width: { 39 | get: function () { 40 | return this._width; 41 | }, 42 | }, 43 | /** 44 | * The height of the texture. 45 | * @type Number 46 | * @readonly 47 | * @memberof CompressedTextureBuffer.prototype 48 | */ 49 | height: { 50 | get: function () { 51 | return this._height; 52 | }, 53 | }, 54 | /** 55 | * The compressed texture buffer. 56 | * @type Uint8Array 57 | * @readonly 58 | * @memberof CompressedTextureBuffer.prototype 59 | */ 60 | bufferView: { 61 | get: function () { 62 | return this._buffer; 63 | }, 64 | }, 65 | }); 66 | 67 | /** 68 | * Creates a shallow clone of a compressed texture buffer. 69 | * 70 | * @param {CompressedTextureBuffer} object The compressed texture buffer to be cloned. 71 | * @return {CompressedTextureBuffer} A shallow clone of the compressed texture buffer. 72 | */ 73 | CompressedTextureBuffer.clone = function (object) { 74 | if (!defined(object)) { 75 | return undefined; 76 | } 77 | 78 | return new CompressedTextureBuffer( 79 | object._format, 80 | object._width, 81 | object._height, 82 | object._buffer 83 | ); 84 | }; 85 | 86 | /** 87 | * Creates a shallow clone of this compressed texture buffer. 88 | * 89 | * @return {CompressedTextureBuffer} A shallow clone of the compressed texture buffer. 90 | */ 91 | CompressedTextureBuffer.prototype.clone = function () { 92 | return CompressedTextureBuffer.clone(this); 93 | }; 94 | export default CompressedTextureBuffer; 95 | -------------------------------------------------------------------------------- /viewer/cesium/Core/ScreenSpaceEventType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This enumerated type is for classifying mouse events: down, up, click, double click, move and move while a button is held down. 3 | * 4 | * @enum {Number} 5 | */ 6 | var ScreenSpaceEventType = { 7 | /** 8 | * Represents a mouse left button down event. 9 | * 10 | * @type {Number} 11 | * @constant 12 | */ 13 | LEFT_DOWN: 0, 14 | 15 | /** 16 | * Represents a mouse left button up event. 17 | * 18 | * @type {Number} 19 | * @constant 20 | */ 21 | LEFT_UP: 1, 22 | 23 | /** 24 | * Represents a mouse left click event. 25 | * 26 | * @type {Number} 27 | * @constant 28 | */ 29 | LEFT_CLICK: 2, 30 | 31 | /** 32 | * Represents a mouse left double click event. 33 | * 34 | * @type {Number} 35 | * @constant 36 | */ 37 | LEFT_DOUBLE_CLICK: 3, 38 | 39 | /** 40 | * Represents a mouse left button down event. 41 | * 42 | * @type {Number} 43 | * @constant 44 | */ 45 | RIGHT_DOWN: 5, 46 | 47 | /** 48 | * Represents a mouse right button up event. 49 | * 50 | * @type {Number} 51 | * @constant 52 | */ 53 | RIGHT_UP: 6, 54 | 55 | /** 56 | * Represents a mouse right click event. 57 | * 58 | * @type {Number} 59 | * @constant 60 | */ 61 | RIGHT_CLICK: 7, 62 | 63 | /** 64 | * Represents a mouse middle button down event. 65 | * 66 | * @type {Number} 67 | * @constant 68 | */ 69 | MIDDLE_DOWN: 10, 70 | 71 | /** 72 | * Represents a mouse middle button up event. 73 | * 74 | * @type {Number} 75 | * @constant 76 | */ 77 | MIDDLE_UP: 11, 78 | 79 | /** 80 | * Represents a mouse middle click event. 81 | * 82 | * @type {Number} 83 | * @constant 84 | */ 85 | MIDDLE_CLICK: 12, 86 | 87 | /** 88 | * Represents a mouse move event. 89 | * 90 | * @type {Number} 91 | * @constant 92 | */ 93 | MOUSE_MOVE: 15, 94 | 95 | /** 96 | * Represents a mouse wheel event. 97 | * 98 | * @type {Number} 99 | * @constant 100 | */ 101 | WHEEL: 16, 102 | 103 | /** 104 | * Represents the start of a two-finger event on a touch surface. 105 | * 106 | * @type {Number} 107 | * @constant 108 | */ 109 | PINCH_START: 17, 110 | 111 | /** 112 | * Represents the end of a two-finger event on a touch surface. 113 | * 114 | * @type {Number} 115 | * @constant 116 | */ 117 | PINCH_END: 18, 118 | 119 | /** 120 | * Represents a change of a two-finger event on a touch surface. 121 | * 122 | * @type {Number} 123 | * @constant 124 | */ 125 | PINCH_MOVE: 19, 126 | }; 127 | export default Object.freeze(ScreenSpaceEventType); 128 | -------------------------------------------------------------------------------- /viewer/frustum.js: -------------------------------------------------------------------------------- 1 | import * as mat4 from "./glmatrix/mat4.js"; 2 | import * as vec3 from "./glmatrix/vec3.js"; 3 | 4 | import {FrustumPlane} from "./frustumplane.js"; 5 | 6 | /** 7 | * Frustum for fast World-space frustum-AABB collision testing 8 | * 9 | * @class Frustum 10 | */ 11 | export class Frustum { 12 | 13 | constructor() { 14 | this.tempMat4 = mat4.create(); 15 | 16 | this.planes = [ // Allocate now, init when needed 17 | new FrustumPlane(), 18 | new FrustumPlane(), 19 | new FrustumPlane(), 20 | new FrustumPlane(), 21 | new FrustumPlane(), 22 | new FrustumPlane() 23 | ]; 24 | } 25 | 26 | init(viewMatrix, projMatrix) { // Builds frustum planes} from view and projection matrices 27 | var m = this.tempMat4; 28 | mat4.multiply(m, projMatrix, viewMatrix); 29 | var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3]; 30 | var m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7]; 31 | var m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11]; 32 | var m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15]; 33 | this.planes[0].init(m3 - m0, m7 - m4, m11 - m8, m15 - m12); 34 | this.planes[1].init(m3 + m0, m7 + m4, m11 + m8, m15 + m12); 35 | this.planes[2].init(m3 - m1, m7 - m5, m11 - m9, m15 - m13); 36 | this.planes[3].init(m3 + m1, m7 + m5, m11 + m9, m15 + m13); 37 | this.planes[4].init(m3 - m2, m7 - m6, m11 - m10, m15 - m14); 38 | this.planes[5].init(m3 + m2, m7 + m6, m11 + m10, m15 + m14); 39 | } 40 | 41 | // Tests for intersection with World-space AABB, which is assumed to be: [xmin, ymin, zmin, xwidth, ywidth, zwidth] 42 | intersectsWorldAABB(minmax) { 43 | var result = Frustum.INSIDE_FRUSTUM; 44 | var plane = null; 45 | var normal; 46 | var offset; 47 | var testVertex; 48 | for (var i = 0; i < 6; ++i) { 49 | plane = this.planes[i]; 50 | normal = plane.normal; 51 | offset = plane.offset; 52 | testVertex = plane.testVertex; 53 | if (((normal[0] * minmax[testVertex[0]][0]) + (normal[1] * minmax[testVertex[1]][1]) + (normal[2] * minmax[testVertex[2]][2]) + (offset)) < 0.0) { 54 | return Frustum.OUTSIDE_FRUSTUM; 55 | } 56 | if (((normal[0] * minmax[1 - testVertex[0]][0]) + (normal[1] * minmax[1 - testVertex[1]][1]) + (normal[2] * minmax[1 - testVertex[2]][2]) + (offset)) < 0.0) { 57 | result = Frustum.INTERSECT_FRUSTUM; // May still become OUTSIDE_FRUSTUM 58 | } 59 | } 60 | return result; 61 | } 62 | } 63 | 64 | Frustum.OUTSIDE_FRUSTUM = 0; 65 | Frustum.INTERSECT_FRUSTUM = 1; 66 | Frustum.INSIDE_FRUSTUM = 2; -------------------------------------------------------------------------------- /viewer/cesium/Core/requestAnimationFrame.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import getTimestamp from "./getTimestamp.js"; 3 | 4 | var implementation; 5 | if (typeof requestAnimationFrame !== "undefined") { 6 | implementation = requestAnimationFrame; 7 | } 8 | 9 | (function () { 10 | // look for vendor prefixed function 11 | if (!defined(implementation) && typeof window !== "undefined") { 12 | var vendors = ["webkit", "moz", "ms", "o"]; 13 | var i = 0; 14 | var len = vendors.length; 15 | while (i < len && !defined(implementation)) { 16 | implementation = window[vendors[i] + "RequestAnimationFrame"]; 17 | ++i; 18 | } 19 | } 20 | 21 | // build an implementation based on setTimeout 22 | if (!defined(implementation)) { 23 | var msPerFrame = 1000.0 / 60.0; 24 | var lastFrameTime = 0; 25 | implementation = function (callback) { 26 | var currentTime = getTimestamp(); 27 | 28 | // schedule the callback to target 60fps, 16.7ms per frame, 29 | // accounting for the time taken by the callback 30 | var delay = Math.max(msPerFrame - (currentTime - lastFrameTime), 0); 31 | lastFrameTime = currentTime + delay; 32 | 33 | return setTimeout(function () { 34 | callback(lastFrameTime); 35 | }, delay); 36 | }; 37 | } 38 | })(); 39 | 40 | /** 41 | * A browser-independent function to request a new animation frame. This is used to create 42 | * an application's draw loop as shown in the example below. 43 | * 44 | * @function requestAnimationFrame 45 | * 46 | * @param {requestAnimationFrameCallback} callback The function to call when the next frame should be drawn. 47 | * @returns {Number} An ID that can be passed to {@link cancelAnimationFrame} to cancel the request. 48 | * 49 | * 50 | * @example 51 | * // Create a draw loop using requestAnimationFrame. The 52 | * // tick callback function is called for every animation frame. 53 | * function tick() { 54 | * scene.render(); 55 | * Cesium.requestAnimationFrame(tick); 56 | * } 57 | * tick(); 58 | * 59 | * @see {@link https://www.w3.org/TR/html51/webappapis.html#animation-frames|The Web API Animation Frames interface} 60 | */ 61 | function requestAnimationFramePolyFill(callback) { 62 | // we need this extra wrapper function because the native requestAnimationFrame 63 | // functions must be invoked on the global scope (window), which is not the case 64 | // if invoked as Cesium.requestAnimationFrame(callback) 65 | return implementation(callback); 66 | } 67 | 68 | /** 69 | * A function that will be called when the next frame should be drawn. 70 | * @callback requestAnimationFrameCallback 71 | * 72 | * @param {Number} timestamp A timestamp for the frame, in milliseconds. 73 | */ 74 | export default requestAnimationFramePolyFill; 75 | -------------------------------------------------------------------------------- /viewer/projection.js: -------------------------------------------------------------------------------- 1 | import * as mat4 from "./glmatrix/mat4.js"; 2 | import * as vec3 from "./glmatrix/vec3.js"; 3 | 4 | export class Projection { 5 | constructor(viewer) { 6 | this.viewer = viewer; 7 | 8 | this._projMatrix = mat4.create(); 9 | this._projMatrixInverted = mat4.create(); 10 | 11 | this._dirty = true; 12 | } 13 | 14 | setModelBounds(modelBounds) { 15 | this.modelBounds = modelBounds; 16 | } 17 | 18 | build() { 19 | if (this.viewer.width == null || this.viewer.height == null) { 20 | throw "Viewer dimensions unknown, cannot continue"; 21 | } 22 | this._dirty = false; 23 | } 24 | 25 | _setDirty() { 26 | this._dirty = true; 27 | this.viewer.dirty = 2; 28 | } 29 | 30 | /** 31 | * Sets the position of the near plane on the positive View-space Z-axis. 32 | * Default is 0.1. 33 | * 34 | * @param {Number} 35 | * near Position of the near clipping plane. The valid range is 36 | * between 0 and the current value of the far plane 37 | */ 38 | set near(near) { 39 | this._near = near || 0.01; 40 | this._setDirty(); 41 | } 42 | 43 | /** 44 | * Gets the position of the near plane on the positive View-space Z-axis. 45 | * 46 | * @return {Number} Position of the near clipping plane. 47 | */ 48 | get near() { 49 | return this._near; 50 | } 51 | 52 | /** 53 | * Sets the position of the far plane on the positive View-space Z-axis. 54 | * Default is 5000. 55 | * 56 | * @param {Number} 57 | * far Position of the far clipping plane. The valid range is 58 | * between the current value of the near plane and infinity. 59 | */ 60 | set far(far) { 61 | this._far = far || 5000; 62 | this._setDirty(); 63 | } 64 | 65 | /** 66 | * Gets the position of the far clipping plane on the positive View-space 67 | * Z-axis. 68 | * 69 | * @return {Number} Position of the far clipping plane. 70 | */ 71 | get far() { 72 | return this._far; 73 | } 74 | 75 | /** 76 | * Gets the current projection projection transform matrix. 77 | * 78 | * This will be the camera's current projection matrix when it's in 79 | * perspective projection mode. 80 | * 81 | * @return {Float32Array} 4x4 column-order matrix as an array of 16 82 | * contiguous floats. 83 | */ 84 | get projMatrix() { 85 | if (this._dirty) { 86 | this.build(); 87 | } 88 | return this._projMatrix; 89 | } 90 | 91 | get projMatrixInverted() { 92 | if (this._dirty) { 93 | this.build(); 94 | } 95 | return this._projMatrixInverted; 96 | } 97 | } -------------------------------------------------------------------------------- /viewer/cesium/Core/Ray.js: -------------------------------------------------------------------------------- 1 | import Cartesian3 from "./Cartesian3.js"; 2 | import Check from "./Check.js"; 3 | import defaultValue from "./defaultValue.js"; 4 | import defined from "./defined.js"; 5 | 6 | /** 7 | * Represents a ray that extends infinitely from the provided origin in the provided direction. 8 | * @alias Ray 9 | * @constructor 10 | * 11 | * @param {Cartesian3} [origin=Cartesian3.ZERO] The origin of the ray. 12 | * @param {Cartesian3} [direction=Cartesian3.ZERO] The direction of the ray. 13 | */ 14 | function Ray(origin, direction) { 15 | direction = Cartesian3.clone(defaultValue(direction, Cartesian3.ZERO)); 16 | if (!Cartesian3.equals(direction, Cartesian3.ZERO)) { 17 | Cartesian3.normalize(direction, direction); 18 | } 19 | 20 | /** 21 | * The origin of the ray. 22 | * @type {Cartesian3} 23 | * @default {@link Cartesian3.ZERO} 24 | */ 25 | this.origin = Cartesian3.clone(defaultValue(origin, Cartesian3.ZERO)); 26 | 27 | /** 28 | * The direction of the ray. 29 | * @type {Cartesian3} 30 | */ 31 | this.direction = direction; 32 | } 33 | 34 | /** 35 | * Duplicates a Ray instance. 36 | * 37 | * @param {Ray} ray The ray to duplicate. 38 | * @param {Ray} [result] The object onto which to store the result. 39 | * @returns {Ray} The modified result parameter or a new Ray instance if one was not provided. (Returns undefined if ray is undefined) 40 | */ 41 | Ray.clone = function (ray, result) { 42 | if (!defined(ray)) { 43 | return undefined; 44 | } 45 | if (!defined(result)) { 46 | return new Ray(ray.origin, ray.direction); 47 | } 48 | result.origin = Cartesian3.clone(ray.origin); 49 | result.direction = Cartesian3.clone(ray.direction); 50 | return result; 51 | }; 52 | 53 | /** 54 | * Computes the point along the ray given by r(t) = o + t*d, 55 | * where o is the origin of the ray and d is the direction. 56 | * 57 | * @param {Ray} ray The ray. 58 | * @param {Number} t A scalar value. 59 | * @param {Cartesian3} [result] The object in which the result will be stored. 60 | * @returns {Cartesian3} The modified result parameter, or a new instance if none was provided. 61 | * 62 | * @example 63 | * //Get the first intersection point of a ray and an ellipsoid. 64 | * var intersection = Cesium.IntersectionTests.rayEllipsoid(ray, ellipsoid); 65 | * var point = Cesium.Ray.getPoint(ray, intersection.start); 66 | */ 67 | Ray.getPoint = function (ray, t, result) { 68 | //>>includeStart('debug', pragmas.debug); 69 | Check.typeOf.object("ray", ray); 70 | Check.typeOf.number("t", t); 71 | //>>includeEnd('debug'); 72 | 73 | if (!defined(result)) { 74 | result = new Cartesian3(); 75 | } 76 | 77 | result = Cartesian3.multiplyByScalar(ray.direction, t, result); 78 | return Cartesian3.add(ray.origin, result, result); 79 | }; 80 | export default Ray; 81 | -------------------------------------------------------------------------------- /viewer/cesium/Core/DoublyLinkedList.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | 3 | /** 4 | * @private 5 | */ 6 | function DoublyLinkedList() { 7 | this.head = undefined; 8 | this.tail = undefined; 9 | this._length = 0; 10 | } 11 | 12 | Object.defineProperties(DoublyLinkedList.prototype, { 13 | length: { 14 | get: function () { 15 | return this._length; 16 | }, 17 | }, 18 | }); 19 | 20 | /** 21 | * @private 22 | */ 23 | function DoublyLinkedListNode(item, previous, next) { 24 | this.item = item; 25 | this.previous = previous; 26 | this.next = next; 27 | } 28 | 29 | /** 30 | * Adds the item to the end of the list 31 | * @param {*} [item] 32 | * @return {DoublyLinkedListNode} 33 | */ 34 | DoublyLinkedList.prototype.add = function (item) { 35 | var node = new DoublyLinkedListNode(item, this.tail, undefined); 36 | 37 | if (defined(this.tail)) { 38 | this.tail.next = node; 39 | this.tail = node; 40 | } else { 41 | this.head = node; 42 | this.tail = node; 43 | } 44 | 45 | ++this._length; 46 | 47 | return node; 48 | }; 49 | 50 | function remove(list, node) { 51 | if (defined(node.previous) && defined(node.next)) { 52 | node.previous.next = node.next; 53 | node.next.previous = node.previous; 54 | } else if (defined(node.previous)) { 55 | // Remove last node 56 | node.previous.next = undefined; 57 | list.tail = node.previous; 58 | } else if (defined(node.next)) { 59 | // Remove first node 60 | node.next.previous = undefined; 61 | list.head = node.next; 62 | } else { 63 | // Remove last node in the linked list 64 | list.head = undefined; 65 | list.tail = undefined; 66 | } 67 | 68 | node.next = undefined; 69 | node.previous = undefined; 70 | } 71 | 72 | /** 73 | * Removes the given node from the list 74 | * @param {DoublyLinkedListNode} node 75 | */ 76 | DoublyLinkedList.prototype.remove = function (node) { 77 | if (!defined(node)) { 78 | return; 79 | } 80 | 81 | remove(this, node); 82 | 83 | --this._length; 84 | }; 85 | 86 | /** 87 | * Moves nextNode after node 88 | * @param {DoublyLinkedListNode} node 89 | * @param {DoublyLinkedListNode} nextNode 90 | */ 91 | DoublyLinkedList.prototype.splice = function (node, nextNode) { 92 | if (node === nextNode) { 93 | return; 94 | } 95 | 96 | // Remove nextNode, then insert after node 97 | remove(this, nextNode); 98 | 99 | var oldNodeNext = node.next; 100 | node.next = nextNode; 101 | 102 | // nextNode is the new tail 103 | if (this.tail === node) { 104 | this.tail = nextNode; 105 | } else { 106 | oldNodeNext.previous = nextNode; 107 | } 108 | 109 | nextNode.next = oldNodeNext; 110 | nextNode.previous = node; 111 | }; 112 | export default DoublyLinkedList; 113 | -------------------------------------------------------------------------------- /viewer/cesium/Core/LinearApproximation.js: -------------------------------------------------------------------------------- 1 | import defined from "./defined.js"; 2 | import DeveloperError from "./DeveloperError.js"; 3 | 4 | /** 5 | * An {@link InterpolationAlgorithm} for performing linear interpolation. 6 | * 7 | * @namespace LinearApproximation 8 | */ 9 | var LinearApproximation = { 10 | type: "Linear", 11 | }; 12 | 13 | /** 14 | * Given the desired degree, returns the number of data points required for interpolation. 15 | * Since linear interpolation can only generate a first degree polynomial, this function 16 | * always returns 2. 17 | * @param {Number} degree The desired degree of interpolation. 18 | * @returns {Number} This function always returns 2. 19 | * 20 | */ 21 | LinearApproximation.getRequiredDataPoints = function (degree) { 22 | return 2; 23 | }; 24 | 25 | /** 26 | * Interpolates values using linear approximation. 27 | * 28 | * @param {Number} x The independent variable for which the dependent variables will be interpolated. 29 | * @param {Number[]} xTable The array of independent variables to use to interpolate. The values 30 | * in this array must be in increasing order and the same value must not occur twice in the array. 31 | * @param {Number[]} yTable The array of dependent variables to use to interpolate. For a set of three 32 | * dependent values (p,q,w) at time 1 and time 2 this should be as follows: {p1, q1, w1, p2, q2, w2}. 33 | * @param {Number} yStride The number of dependent variable values in yTable corresponding to 34 | * each independent variable value in xTable. 35 | * @param {Number[]} [result] An existing array into which to store the result. 36 | * @returns {Number[]} The array of interpolated values, or the result parameter if one was provided. 37 | */ 38 | LinearApproximation.interpolateOrderZero = function ( 39 | x, 40 | xTable, 41 | yTable, 42 | yStride, 43 | result 44 | ) { 45 | //>>includeStart('debug', pragmas.debug); 46 | if (xTable.length !== 2) { 47 | throw new DeveloperError( 48 | "The xTable provided to the linear interpolator must have exactly two elements." 49 | ); 50 | } else if (yStride <= 0) { 51 | throw new DeveloperError( 52 | "There must be at least 1 dependent variable for each independent variable." 53 | ); 54 | } 55 | //>>includeEnd('debug'); 56 | 57 | if (!defined(result)) { 58 | result = new Array(yStride); 59 | } 60 | 61 | var i; 62 | var y0; 63 | var y1; 64 | var x0 = xTable[0]; 65 | var x1 = xTable[1]; 66 | 67 | //>>includeStart('debug', pragmas.debug); 68 | if (x0 === x1) { 69 | throw new DeveloperError( 70 | "Divide by zero error: xTable[0] and xTable[1] are equal" 71 | ); 72 | } 73 | //>>includeEnd('debug'); 74 | 75 | for (i = 0; i < yStride; i++) { 76 | y0 = yTable[i]; 77 | y1 = yTable[i + yStride]; 78 | result[i] = ((y1 - y0) * x + x1 * y0 - x0 * y1) / (x1 - x0); 79 | } 80 | 81 | return result; 82 | }; 83 | export default LinearApproximation; 84 | -------------------------------------------------------------------------------- /viewer/cesium/Core/RectangleCollisionChecker.js: -------------------------------------------------------------------------------- 1 | import RBush from "../ThirdParty/rbush.js"; 2 | import Check from "./Check.js"; 3 | 4 | /** 5 | * Wrapper around rbush for use with Rectangle types. 6 | * @private 7 | */ 8 | function RectangleCollisionChecker() { 9 | this._tree = new RBush(); 10 | } 11 | 12 | function RectangleWithId() { 13 | this.minX = 0.0; 14 | this.minY = 0.0; 15 | this.maxX = 0.0; 16 | this.maxY = 0.0; 17 | this.id = ""; 18 | } 19 | 20 | RectangleWithId.fromRectangleAndId = function (id, rectangle, result) { 21 | result.minX = rectangle.west; 22 | result.minY = rectangle.south; 23 | result.maxX = rectangle.east; 24 | result.maxY = rectangle.north; 25 | result.id = id; 26 | return result; 27 | }; 28 | 29 | /** 30 | * Insert a rectangle into the collision checker. 31 | * 32 | * @param {String} id Unique string ID for the rectangle being inserted. 33 | * @param {Rectangle} rectangle A Rectangle 34 | * @private 35 | */ 36 | RectangleCollisionChecker.prototype.insert = function (id, rectangle) { 37 | //>>includeStart('debug', pragmas.debug); 38 | Check.typeOf.string("id", id); 39 | Check.typeOf.object("rectangle", rectangle); 40 | //>>includeEnd('debug'); 41 | 42 | var withId = RectangleWithId.fromRectangleAndId( 43 | id, 44 | rectangle, 45 | new RectangleWithId() 46 | ); 47 | this._tree.insert(withId); 48 | }; 49 | 50 | function idCompare(a, b) { 51 | return a.id === b.id; 52 | } 53 | 54 | var removalScratch = new RectangleWithId(); 55 | /** 56 | * Remove a rectangle from the collision checker. 57 | * 58 | * @param {String} id Unique string ID for the rectangle being removed. 59 | * @param {Rectangle} rectangle A Rectangle 60 | * @private 61 | */ 62 | RectangleCollisionChecker.prototype.remove = function (id, rectangle) { 63 | //>>includeStart('debug', pragmas.debug); 64 | Check.typeOf.string("id", id); 65 | Check.typeOf.object("rectangle", rectangle); 66 | //>>includeEnd('debug'); 67 | 68 | var withId = RectangleWithId.fromRectangleAndId( 69 | id, 70 | rectangle, 71 | removalScratch 72 | ); 73 | this._tree.remove(withId, idCompare); 74 | }; 75 | 76 | var collisionScratch = new RectangleWithId(); 77 | /** 78 | * Checks if a given rectangle collides with any of the rectangles in the collection. 79 | * 80 | * @param {Rectangle} rectangle A Rectangle that should be checked against the rectangles in the collision checker. 81 | * @returns {Boolean} Whether the rectangle collides with any of the rectangles in the collision checker. 82 | */ 83 | RectangleCollisionChecker.prototype.collides = function (rectangle) { 84 | //>>includeStart('debug', pragmas.debug); 85 | Check.typeOf.object("rectangle", rectangle); 86 | //>>includeEnd('debug'); 87 | 88 | var withId = RectangleWithId.fromRectangleAndId( 89 | "", 90 | rectangle, 91 | collisionScratch 92 | ); 93 | return this._tree.collides(withId); 94 | }; 95 | export default RectangleCollisionChecker; 96 | -------------------------------------------------------------------------------- /viewer/cesium/Core/decodeGoogleEarthEnterpriseData.js: -------------------------------------------------------------------------------- 1 | import Check from "./Check.js"; 2 | import RuntimeError from "./RuntimeError.js"; 3 | 4 | var compressedMagic = 0x7468dead; 5 | var compressedMagicSwap = 0xadde6874; 6 | 7 | /** 8 | * Decodes data that is received from the Google Earth Enterprise server. 9 | * 10 | * @param {ArrayBuffer} key The key used during decoding. 11 | * @param {ArrayBuffer} data The data to be decoded. 12 | * 13 | * @private 14 | */ 15 | function decodeGoogleEarthEnterpriseData(key, data) { 16 | if (decodeGoogleEarthEnterpriseData.passThroughDataForTesting) { 17 | return data; 18 | } 19 | 20 | //>>includeStart('debug', pragmas.debug); 21 | Check.typeOf.object("key", key); 22 | Check.typeOf.object("data", data); 23 | //>>includeEnd('debug'); 24 | 25 | var keyLength = key.byteLength; 26 | if (keyLength === 0 || keyLength % 4 !== 0) { 27 | throw new RuntimeError( 28 | "The length of key must be greater than 0 and a multiple of 4." 29 | ); 30 | } 31 | 32 | var dataView = new DataView(data); 33 | var magic = dataView.getUint32(0, true); 34 | if (magic === compressedMagic || magic === compressedMagicSwap) { 35 | // Occasionally packets don't come back encoded, so just return 36 | return data; 37 | } 38 | 39 | var keyView = new DataView(key); 40 | 41 | var dp = 0; 42 | var dpend = data.byteLength; 43 | var dpend64 = dpend - (dpend % 8); 44 | var kpend = keyLength; 45 | var kp; 46 | var off = 8; 47 | 48 | // This algorithm is intentionally asymmetric to make it more difficult to 49 | // guess. Security through obscurity. :-( 50 | 51 | // while we have a full uint64 (8 bytes) left to do 52 | // assumes buffer is 64bit aligned (or processor doesn't care) 53 | while (dp < dpend64) { 54 | // rotate the key each time through by using the offets 16,0,8,16,0,8,... 55 | off = (off + 8) % 24; 56 | kp = off; 57 | 58 | // run through one key length xor'ing one uint64 at a time 59 | // then drop out to rotate the key for the next bit 60 | while (dp < dpend64 && kp < kpend) { 61 | dataView.setUint32( 62 | dp, 63 | dataView.getUint32(dp, true) ^ keyView.getUint32(kp, true), 64 | true 65 | ); 66 | dataView.setUint32( 67 | dp + 4, 68 | dataView.getUint32(dp + 4, true) ^ keyView.getUint32(kp + 4, true), 69 | true 70 | ); 71 | dp += 8; 72 | kp += 24; 73 | } 74 | } 75 | 76 | // now the remaining 1 to 7 bytes 77 | if (dp < dpend) { 78 | if (kp >= kpend) { 79 | // rotate the key one last time (if necessary) 80 | off = (off + 8) % 24; 81 | kp = off; 82 | } 83 | 84 | while (dp < dpend) { 85 | dataView.setUint8(dp, dataView.getUint8(dp) ^ keyView.getUint8(kp)); 86 | dp++; 87 | kp++; 88 | } 89 | } 90 | } 91 | 92 | decodeGoogleEarthEnterpriseData.passThroughDataForTesting = false; 93 | export default decodeGoogleEarthEnterpriseData; 94 | --------------------------------------------------------------------------------