1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363 |
- import arraySlice from '../Core/arraySlice.js';
- import BoundingSphere from '../Core/BoundingSphere.js';
- import Cartesian3 from '../Core/Cartesian3.js';
- import Cartesian4 from '../Core/Cartesian4.js';
- import Check from '../Core/Check.js';
- import Color from '../Core/Color.js';
- import combine from '../Core/combine.js';
- import ComponentDatatype from '../Core/ComponentDatatype.js';
- import defaultValue from '../Core/defaultValue.js';
- import defined from '../Core/defined.js';
- import defineProperties from '../Core/defineProperties.js';
- import destroyObject from '../Core/destroyObject.js';
- import getStringFromTypedArray from '../Core/getStringFromTypedArray.js';
- import CesiumMath from '../Core/Math.js';
- import Matrix4 from '../Core/Matrix4.js';
- import oneTimeWarning from '../Core/oneTimeWarning.js';
- import OrthographicFrustum from '../Core/OrthographicFrustum.js';
- import PrimitiveType from '../Core/PrimitiveType.js';
- import RuntimeError from '../Core/RuntimeError.js';
- import Transforms from '../Core/Transforms.js';
- import Buffer from '../Renderer/Buffer.js';
- import BufferUsage from '../Renderer/BufferUsage.js';
- import DrawCommand from '../Renderer/DrawCommand.js';
- import Pass from '../Renderer/Pass.js';
- import RenderState from '../Renderer/RenderState.js';
- import ShaderProgram from '../Renderer/ShaderProgram.js';
- import VertexArray from '../Renderer/VertexArray.js';
- import when from '../ThirdParty/when.js';
- import BlendingState from './BlendingState.js';
- import Cesium3DTileBatchTable from './Cesium3DTileBatchTable.js';
- import Cesium3DTileFeatureTable from './Cesium3DTileFeatureTable.js';
- import DracoLoader from './DracoLoader.js';
- import getClipAndStyleCode from './getClipAndStyleCode.js';
- import getClippingFunction from './getClippingFunction.js';
- import SceneMode from './SceneMode.js';
- import ShadowMode from './ShadowMode.js';
- import StencilConstants from './StencilConstants.js';
- var DecodingState = {
- NEEDS_DECODE : 0,
- DECODING : 1,
- READY : 2,
- FAILED : 3
- };
- /**
- * Represents the contents of a
- * {@link https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification/TileFormats/PointCloud|Point Cloud}
- * tile. Used internally by {@link PointCloud3DTileContent} and {@link TimeDynamicPointCloud}.
- *
- * @alias PointCloud
- * @constructor
- *
- * @see PointCloud3DTileContent
- * @see TimeDynamicPointCloud
- *
- * @private
- */
- function PointCloud(options) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object('options', options);
- Check.typeOf.object('options.arrayBuffer', options.arrayBuffer);
- //>>includeEnd('debug');
- // Hold onto the payload until the render resources are created
- this._parsedContent = undefined;
- this._drawCommand = undefined;
- this._isTranslucent = false;
- this._styleTranslucent = false;
- this._constantColor = Color.clone(Color.DARKGRAY);
- this._highlightColor = Color.clone(Color.WHITE);
- this._pointSize = 1.0;
- this._rtcCenter = undefined;
- this._quantizedVolumeScale = undefined;
- this._quantizedVolumeOffset = undefined;
- // These values are used to regenerate the shader when the style changes
- this._styleableShaderAttributes = undefined;
- this._isQuantized = false;
- this._isOctEncoded16P = false;
- this._isRGB565 = false;
- this._hasColors = false;
- this._hasNormals = false;
- this._hasBatchIds = false;
- // Draco
- this._decodingState = DecodingState.READY;
- this._dequantizeInShader = true;
- this._isQuantizedDraco = false;
- this._isOctEncodedDraco = false;
- this._quantizedRange = 0.0;
- this._octEncodedRange = 0.0;
- // Use per-point normals to hide back-facing points.
- this.backFaceCulling = false;
- this._backFaceCulling = false;
- // Whether to enable normal shading
- this.normalShading = true;
- this._normalShading = true;
- this._opaqueRenderState = undefined;
- this._translucentRenderState = undefined;
- this._mode = undefined;
- this._ready = false;
- this._readyPromise = when.defer();
- this._pointsLength = 0;
- this._geometryByteLength = 0;
- this._vertexShaderLoaded = options.vertexShaderLoaded;
- this._fragmentShaderLoaded = options.fragmentShaderLoaded;
- this._uniformMapLoaded = options.uniformMapLoaded;
- this._batchTableLoaded = options.batchTableLoaded;
- this._pickIdLoaded = options.pickIdLoaded;
- this._opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE);
- this._cull = defaultValue(options.cull, true);
- this.style = undefined;
- this._style = undefined;
- this.styleDirty = false;
- this.modelMatrix = Matrix4.clone(Matrix4.IDENTITY);
- this._modelMatrix = Matrix4.clone(Matrix4.IDENTITY);
- this.time = 0.0; // For styling
- this.shadows = ShadowMode.ENABLED;
- this._boundingSphere = undefined;
- this.clippingPlanes = undefined;
- this.isClipped = false;
- this.clippingPlanesDirty = false;
- // If defined, use this matrix to position the clipping planes instead of the modelMatrix.
- // This is so that when point clouds are part of a tileset they all get clipped relative
- // to the root tile.
- this.clippingPlanesOriginMatrix = undefined;
- this.attenuation = false;
- this._attenuation = false;
- // Options for geometric error based attenuation
- this.geometricError = 0.0;
- this.geometricErrorScale = 1.0;
- this.maximumAttenuation = this._pointSize;
- initialize(this, options);
- }
- defineProperties(PointCloud.prototype, {
- pointsLength : {
- get : function() {
- return this._pointsLength;
- }
- },
- geometryByteLength : {
- get : function() {
- return this._geometryByteLength;
- }
- },
- ready : {
- get : function() {
- return this._ready;
- }
- },
- readyPromise : {
- get : function() {
- return this._readyPromise.promise;
- }
- },
- color : {
- get : function() {
- return Color.clone(this._highlightColor);
- },
- set : function(value) {
- this._highlightColor = Color.clone(value, this._highlightColor);
- }
- },
- boundingSphere : {
- get : function() {
- if (defined(this._drawCommand)) {
- return this._drawCommand.boundingVolume;
- }
- },
- set : function(value) {
- this._boundingSphere = BoundingSphere.clone(value);
- }
- }
- });
- var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
- function initialize(pointCloud, options) {
- var arrayBuffer = options.arrayBuffer;
- var byteOffset = defaultValue(options.byteOffset, 0);
- var uint8Array = new Uint8Array(arrayBuffer);
- var view = new DataView(arrayBuffer);
- byteOffset += sizeOfUint32; // Skip magic
- var version = view.getUint32(byteOffset, true);
- if (version !== 1) {
- throw new RuntimeError('Only Point Cloud tile version 1 is supported. Version ' + version + ' is not.');
- }
- byteOffset += sizeOfUint32;
- // Skip byteLength
- byteOffset += sizeOfUint32;
- var featureTableJsonByteLength = view.getUint32(byteOffset, true);
- if (featureTableJsonByteLength === 0) {
- throw new RuntimeError('Feature table must have a byte length greater than zero');
- }
- byteOffset += sizeOfUint32;
- var featureTableBinaryByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- var batchTableJsonByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- var batchTableBinaryByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- var featureTableString = getStringFromTypedArray(uint8Array, byteOffset, featureTableJsonByteLength);
- var featureTableJson = JSON.parse(featureTableString);
- byteOffset += featureTableJsonByteLength;
- var featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength);
- byteOffset += featureTableBinaryByteLength;
- // Get the batch table JSON and binary
- var batchTableJson;
- var batchTableBinary;
- if (batchTableJsonByteLength > 0) {
- // Has a batch table JSON
- var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJsonByteLength);
- batchTableJson = JSON.parse(batchTableString);
- byteOffset += batchTableJsonByteLength;
- if (batchTableBinaryByteLength > 0) {
- // Has a batch table binary
- batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength);
- byteOffset += batchTableBinaryByteLength;
- }
- }
- var featureTable = new Cesium3DTileFeatureTable(featureTableJson, featureTableBinary);
- var pointsLength = featureTable.getGlobalProperty('POINTS_LENGTH');
- featureTable.featuresLength = pointsLength;
- if (!defined(pointsLength)) {
- throw new RuntimeError('Feature table global property: POINTS_LENGTH must be defined');
- }
- var rtcCenter = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3);
- if (defined(rtcCenter)) {
- pointCloud._rtcCenter = Cartesian3.unpack(rtcCenter);
- }
- var positions;
- var colors;
- var normals;
- var batchIds;
- var hasPositions = false;
- var hasColors = false;
- var hasNormals = false;
- var hasBatchIds = false;
- var isQuantized = false;
- var isTranslucent = false;
- var isRGB565 = false;
- var isOctEncoded16P = false;
- var dracoBuffer;
- var dracoFeatureTableProperties;
- var dracoBatchTableProperties;
- var featureTableDraco = defined(featureTableJson.extensions) ? featureTableJson.extensions['3DTILES_draco_point_compression'] : undefined;
- var batchTableDraco = (defined(batchTableJson) && defined(batchTableJson.extensions)) ? batchTableJson.extensions['3DTILES_draco_point_compression'] : undefined;
- if (defined(batchTableDraco)) {
- dracoBatchTableProperties = batchTableDraco.properties;
- }
- if (defined(featureTableDraco)) {
- dracoFeatureTableProperties = featureTableDraco.properties;
- var dracoByteOffset = featureTableDraco.byteOffset;
- var dracoByteLength = featureTableDraco.byteLength;
- if (!defined(dracoFeatureTableProperties) || !defined(dracoByteOffset) || !defined(dracoByteLength)) {
- throw new RuntimeError('Draco properties, byteOffset, and byteLength must be defined');
- }
- dracoBuffer = arraySlice(featureTableBinary, dracoByteOffset, dracoByteOffset + dracoByteLength);
- hasPositions = defined(dracoFeatureTableProperties.POSITION);
- hasColors = defined(dracoFeatureTableProperties.RGB) || defined(dracoFeatureTableProperties.RGBA);
- hasNormals = defined(dracoFeatureTableProperties.NORMAL);
- hasBatchIds = defined(dracoFeatureTableProperties.BATCH_ID);
- isTranslucent = defined(dracoFeatureTableProperties.RGBA);
- pointCloud._decodingState = DecodingState.NEEDS_DECODE;
- }
- var draco;
- if (defined(dracoBuffer)) {
- draco = {
- buffer : dracoBuffer,
- featureTableProperties : dracoFeatureTableProperties,
- batchTableProperties : dracoBatchTableProperties,
- properties : combine(dracoFeatureTableProperties, dracoBatchTableProperties),
- dequantizeInShader : pointCloud._dequantizeInShader
- };
- }
- if (!hasPositions) {
- if (defined(featureTableJson.POSITION)) {
- positions = featureTable.getPropertyArray('POSITION', ComponentDatatype.FLOAT, 3);
- hasPositions = true;
- } else if (defined(featureTableJson.POSITION_QUANTIZED)) {
- positions = featureTable.getPropertyArray('POSITION_QUANTIZED', ComponentDatatype.UNSIGNED_SHORT, 3);
- isQuantized = true;
- hasPositions = true;
- var quantizedVolumeScale = featureTable.getGlobalProperty('QUANTIZED_VOLUME_SCALE', ComponentDatatype.FLOAT, 3);
- if (!defined(quantizedVolumeScale)) {
- throw new RuntimeError('Global property: QUANTIZED_VOLUME_SCALE must be defined for quantized positions.');
- }
- pointCloud._quantizedVolumeScale = Cartesian3.unpack(quantizedVolumeScale);
- pointCloud._quantizedRange = (1 << 16) - 1;
- var quantizedVolumeOffset = featureTable.getGlobalProperty('QUANTIZED_VOLUME_OFFSET', ComponentDatatype.FLOAT, 3);
- if (!defined(quantizedVolumeOffset)) {
- throw new RuntimeError('Global property: QUANTIZED_VOLUME_OFFSET must be defined for quantized positions.');
- }
- pointCloud._quantizedVolumeOffset = Cartesian3.unpack(quantizedVolumeOffset);
- }
- }
- if (!hasColors) {
- if (defined(featureTableJson.RGBA)) {
- colors = featureTable.getPropertyArray('RGBA', ComponentDatatype.UNSIGNED_BYTE, 4);
- isTranslucent = true;
- hasColors = true;
- } else if (defined(featureTableJson.RGB)) {
- colors = featureTable.getPropertyArray('RGB', ComponentDatatype.UNSIGNED_BYTE, 3);
- hasColors = true;
- } else if (defined(featureTableJson.RGB565)) {
- colors = featureTable.getPropertyArray('RGB565', ComponentDatatype.UNSIGNED_SHORT, 1);
- isRGB565 = true;
- hasColors = true;
- }
- }
- if (!hasNormals) {
- if (defined(featureTableJson.NORMAL)) {
- normals = featureTable.getPropertyArray('NORMAL', ComponentDatatype.FLOAT, 3);
- hasNormals = true;
- } else if (defined(featureTableJson.NORMAL_OCT16P)) {
- normals = featureTable.getPropertyArray('NORMAL_OCT16P', ComponentDatatype.UNSIGNED_BYTE, 2);
- isOctEncoded16P = true;
- hasNormals = true;
- }
- }
- if (!hasBatchIds) {
- if (defined(featureTableJson.BATCH_ID)) {
- batchIds = featureTable.getPropertyArray('BATCH_ID', ComponentDatatype.UNSIGNED_SHORT, 1);
- hasBatchIds = true;
- }
- }
- if (!hasPositions) {
- throw new RuntimeError('Either POSITION or POSITION_QUANTIZED must be defined.');
- }
- if (defined(featureTableJson.CONSTANT_RGBA)) {
- var constantRGBA = featureTable.getGlobalProperty('CONSTANT_RGBA', ComponentDatatype.UNSIGNED_BYTE, 4);
- pointCloud._constantColor = Color.fromBytes(constantRGBA[0], constantRGBA[1], constantRGBA[2], constantRGBA[3], pointCloud._constantColor);
- }
- if (hasBatchIds) {
- var batchLength = featureTable.getGlobalProperty('BATCH_LENGTH');
- if (!defined(batchLength)) {
- throw new RuntimeError('Global property: BATCH_LENGTH must be defined when BATCH_ID is defined.');
- }
- if (defined(batchTableBinary)) {
- // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed
- batchTableBinary = new Uint8Array(batchTableBinary);
- }
- if (defined(pointCloud._batchTableLoaded)) {
- pointCloud._batchTableLoaded(batchLength, batchTableJson, batchTableBinary);
- }
- }
- // If points are not batched and there are per-point properties, use these properties for styling purposes
- var styleableProperties;
- if (!hasBatchIds && defined(batchTableBinary)) {
- styleableProperties = Cesium3DTileBatchTable.getBinaryProperties(pointsLength, batchTableJson, batchTableBinary);
- }
- pointCloud._parsedContent = {
- positions : positions,
- colors : colors,
- normals : normals,
- batchIds : batchIds,
- styleableProperties : styleableProperties,
- draco : draco
- };
- pointCloud._pointsLength = pointsLength;
- pointCloud._isQuantized = isQuantized;
- pointCloud._isOctEncoded16P = isOctEncoded16P;
- pointCloud._isRGB565 = isRGB565;
- pointCloud._isTranslucent = isTranslucent;
- pointCloud._hasColors = hasColors;
- pointCloud._hasNormals = hasNormals;
- pointCloud._hasBatchIds = hasBatchIds;
- }
- var scratchMin = new Cartesian3();
- var scratchMax = new Cartesian3();
- var scratchPosition = new Cartesian3();
- var randomValues;
- function getRandomValues(samplesLength) {
- // Use same random values across all runs
- if (!defined(randomValues)) {
- CesiumMath.setRandomNumberSeed(0);
- randomValues = new Array(samplesLength);
- for (var i = 0; i < samplesLength; ++i) {
- randomValues[i] = CesiumMath.nextRandomNumber();
- }
- }
- return randomValues;
- }
- function computeApproximateBoundingSphereFromPositions(positions) {
- var maximumSamplesLength = 20;
- var pointsLength = positions.length / 3;
- var samplesLength = Math.min(pointsLength, maximumSamplesLength);
- var randomValues = getRandomValues(maximumSamplesLength);
- var maxValue = Number.MAX_VALUE;
- var minValue = -Number.MAX_VALUE;
- var min = Cartesian3.fromElements(maxValue, maxValue, maxValue, scratchMin);
- var max = Cartesian3.fromElements(minValue, minValue, minValue, scratchMax);
- for (var i = 0; i < samplesLength; ++i) {
- var index = Math.floor(randomValues[i] * pointsLength);
- var position = Cartesian3.unpack(positions, index * 3, scratchPosition);
- Cartesian3.minimumByComponent(min, position, min);
- Cartesian3.maximumByComponent(max, position, max);
- }
- var boundingSphere = BoundingSphere.fromCornerPoints(min, max);
- boundingSphere.radius += CesiumMath.EPSILON2; // To avoid radius of zero
- return boundingSphere;
- }
- function prepareVertexAttribute(typedArray, name) {
- // WebGL does not support UNSIGNED_INT, INT, or DOUBLE vertex attributes. Convert these to FLOAT.
- var componentDatatype = ComponentDatatype.fromTypedArray(typedArray);
- if (componentDatatype === ComponentDatatype.INT || componentDatatype === ComponentDatatype.UNSIGNED_INT || componentDatatype === ComponentDatatype.DOUBLE) {
- oneTimeWarning('Cast pnts property to floats', 'Point cloud property "' + name + '" will be casted to a float array because INT, UNSIGNED_INT, and DOUBLE are not valid WebGL vertex attribute types. Some precision may be lost.');
- return new Float32Array(typedArray);
- }
- return typedArray;
- }
- var scratchPointSizeAndTimeAndGeometricErrorAndDepthMultiplier = new Cartesian4();
- var scratchQuantizedVolumeScaleAndOctEncodedRange = new Cartesian4();
- var scratchColor = new Color();
- var positionLocation = 0;
- var colorLocation = 1;
- var normalLocation = 2;
- var batchIdLocation = 3;
- var numberOfAttributes = 4;
- var scratchClippingPlaneMatrix = new Matrix4();
- function createResources(pointCloud, frameState) {
- var context = frameState.context;
- var parsedContent = pointCloud._parsedContent;
- var pointsLength = pointCloud._pointsLength;
- var positions = parsedContent.positions;
- var colors = parsedContent.colors;
- var normals = parsedContent.normals;
- var batchIds = parsedContent.batchIds;
- var styleableProperties = parsedContent.styleableProperties;
- var hasStyleableProperties = defined(styleableProperties);
- var isQuantized = pointCloud._isQuantized;
- var isQuantizedDraco = pointCloud._isQuantizedDraco;
- var isOctEncoded16P = pointCloud._isOctEncoded16P;
- var isOctEncodedDraco = pointCloud._isOctEncodedDraco;
- var quantizedRange = pointCloud._quantizedRange;
- var octEncodedRange = pointCloud._octEncodedRange;
- var isRGB565 = pointCloud._isRGB565;
- var isTranslucent = pointCloud._isTranslucent;
- var hasColors = pointCloud._hasColors;
- var hasNormals = pointCloud._hasNormals;
- var hasBatchIds = pointCloud._hasBatchIds;
- var componentsPerAttribute;
- var componentDatatype;
- var styleableVertexAttributes = [];
- var styleableShaderAttributes = {};
- pointCloud._styleableShaderAttributes = styleableShaderAttributes;
- if (hasStyleableProperties) {
- var attributeLocation = numberOfAttributes;
- for (var name in styleableProperties) {
- if (styleableProperties.hasOwnProperty(name)) {
- var property = styleableProperties[name];
- var typedArray = prepareVertexAttribute(property.typedArray, name);
- componentsPerAttribute = property.componentCount;
- componentDatatype = ComponentDatatype.fromTypedArray(typedArray);
- var vertexBuffer = Buffer.createVertexBuffer({
- context : context,
- typedArray : typedArray,
- usage : BufferUsage.STATIC_DRAW
- });
- pointCloud._geometryByteLength += vertexBuffer.sizeInBytes;
- var vertexAttribute = {
- index : attributeLocation,
- vertexBuffer : vertexBuffer,
- componentsPerAttribute : componentsPerAttribute,
- componentDatatype : componentDatatype,
- normalize : false,
- offsetInBytes : 0,
- strideInBytes : 0
- };
- styleableVertexAttributes.push(vertexAttribute);
- styleableShaderAttributes[name] = {
- location : attributeLocation,
- componentCount : componentsPerAttribute
- };
- ++attributeLocation;
- }
- }
- }
- var positionsVertexBuffer = Buffer.createVertexBuffer({
- context : context,
- typedArray : positions,
- usage : BufferUsage.STATIC_DRAW
- });
- pointCloud._geometryByteLength += positionsVertexBuffer.sizeInBytes;
- var colorsVertexBuffer;
- if (hasColors) {
- colorsVertexBuffer = Buffer.createVertexBuffer({
- context : context,
- typedArray : colors,
- usage : BufferUsage.STATIC_DRAW
- });
- pointCloud._geometryByteLength += colorsVertexBuffer.sizeInBytes;
- }
- var normalsVertexBuffer;
- if (hasNormals) {
- normalsVertexBuffer = Buffer.createVertexBuffer({
- context : context,
- typedArray : normals,
- usage : BufferUsage.STATIC_DRAW
- });
- pointCloud._geometryByteLength += normalsVertexBuffer.sizeInBytes;
- }
- var batchIdsVertexBuffer;
- if (hasBatchIds) {
- batchIds = prepareVertexAttribute(batchIds, 'batchIds');
- batchIdsVertexBuffer = Buffer.createVertexBuffer({
- context : context,
- typedArray : batchIds,
- usage : BufferUsage.STATIC_DRAW
- });
- pointCloud._geometryByteLength += batchIdsVertexBuffer.sizeInBytes;
- }
- var attributes = [];
- if (isQuantized) {
- componentDatatype = ComponentDatatype.UNSIGNED_SHORT;
- } else if (isQuantizedDraco) {
- componentDatatype = (quantizedRange <= 255) ? ComponentDatatype.UNSIGNED_BYTE : ComponentDatatype.UNSIGNED_SHORT;
- } else {
- componentDatatype = ComponentDatatype.FLOAT;
- }
- attributes.push({
- index : positionLocation,
- vertexBuffer : positionsVertexBuffer,
- componentsPerAttribute : 3,
- componentDatatype : componentDatatype,
- normalize : false,
- offsetInBytes : 0,
- strideInBytes : 0
- });
- if (pointCloud._cull) {
- if (isQuantized || isQuantizedDraco) {
- pointCloud._boundingSphere = BoundingSphere.fromCornerPoints(Cartesian3.ZERO, pointCloud._quantizedVolumeScale);
- } else {
- pointCloud._boundingSphere = computeApproximateBoundingSphereFromPositions(positions);
- }
- }
- if (hasColors) {
- if (isRGB565) {
- attributes.push({
- index : colorLocation,
- vertexBuffer : colorsVertexBuffer,
- componentsPerAttribute : 1,
- componentDatatype : ComponentDatatype.UNSIGNED_SHORT,
- normalize : false,
- offsetInBytes : 0,
- strideInBytes : 0
- });
- } else {
- var colorComponentsPerAttribute = isTranslucent ? 4 : 3;
- attributes.push({
- index : colorLocation,
- vertexBuffer : colorsVertexBuffer,
- componentsPerAttribute : colorComponentsPerAttribute,
- componentDatatype : ComponentDatatype.UNSIGNED_BYTE,
- normalize : true,
- offsetInBytes : 0,
- strideInBytes : 0
- });
- }
- }
- if (hasNormals) {
- if (isOctEncoded16P) {
- componentsPerAttribute = 2;
- componentDatatype = ComponentDatatype.UNSIGNED_BYTE;
- } else if (isOctEncodedDraco) {
- componentsPerAttribute = 2;
- componentDatatype = (octEncodedRange <= 255) ? ComponentDatatype.UNSIGNED_BYTE : ComponentDatatype.UNSIGNED_SHORT;
- } else {
- componentsPerAttribute = 3;
- componentDatatype = ComponentDatatype.FLOAT;
- }
- attributes.push({
- index : normalLocation,
- vertexBuffer : normalsVertexBuffer,
- componentsPerAttribute : componentsPerAttribute,
- componentDatatype : componentDatatype,
- normalize : false,
- offsetInBytes : 0,
- strideInBytes : 0
- });
- }
- if (hasBatchIds) {
- attributes.push({
- index : batchIdLocation,
- vertexBuffer : batchIdsVertexBuffer,
- componentsPerAttribute : 1,
- componentDatatype : ComponentDatatype.fromTypedArray(batchIds),
- normalize : false,
- offsetInBytes : 0,
- strideInBytes : 0
- });
- }
- if (hasStyleableProperties) {
- attributes = attributes.concat(styleableVertexAttributes);
- }
- var vertexArray = new VertexArray({
- context : context,
- attributes : attributes
- });
- var opaqueRenderState = {
- depthTest : {
- enabled : true
- }
- };
- if (pointCloud._opaquePass === Pass.CESIUM_3D_TILE) {
- opaqueRenderState.stencilTest = StencilConstants.setCesium3DTileBit();
- opaqueRenderState.stencilMask = StencilConstants.CESIUM_3D_TILE_MASK;
- }
- pointCloud._opaqueRenderState = RenderState.fromCache(opaqueRenderState);
- pointCloud._translucentRenderState = RenderState.fromCache({
- depthTest : {
- enabled : true
- },
- depthMask : false,
- blending : BlendingState.ALPHA_BLEND
- });
- pointCloud._drawCommand = new DrawCommand({
- boundingVolume : new BoundingSphere(),
- cull : pointCloud._cull,
- modelMatrix : new Matrix4(),
- primitiveType : PrimitiveType.POINTS,
- vertexArray : vertexArray,
- count : pointsLength,
- shaderProgram : undefined, // Updated in createShaders
- uniformMap : undefined, // Updated in createShaders
- renderState : isTranslucent ? pointCloud._translucentRenderState : pointCloud._opaqueRenderState,
- pass : isTranslucent ? Pass.TRANSLUCENT : pointCloud._opaquePass,
- owner : pointCloud,
- castShadows : false,
- receiveShadows : false,
- pickId : pointCloud._pickIdLoaded()
- });
- }
- function createUniformMap(pointCloud, frameState) {
- var context = frameState.context;
- var isQuantized = pointCloud._isQuantized;
- var isQuantizedDraco = pointCloud._isQuantizedDraco;
- var isOctEncodedDraco = pointCloud._isOctEncodedDraco;
- var uniformMap = {
- u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier : function() {
- var scratch = scratchPointSizeAndTimeAndGeometricErrorAndDepthMultiplier;
- scratch.x = pointCloud._attenuation ? pointCloud.maximumAttenuation : pointCloud._pointSize;
- scratch.x *= frameState.pixelRatio;
- scratch.y = pointCloud.time;
- if (pointCloud._attenuation) {
- var frustum = frameState.camera.frustum;
- var depthMultiplier;
- // Attenuation is maximumAttenuation in 2D/ortho
- if (frameState.mode === SceneMode.SCENE2D || frustum instanceof OrthographicFrustum) {
- depthMultiplier = Number.POSITIVE_INFINITY;
- } else {
- depthMultiplier = context.drawingBufferHeight / frameState.camera.frustum.sseDenominator;
- }
- scratch.z = pointCloud.geometricError * pointCloud.geometricErrorScale;
- scratch.w = depthMultiplier;
- }
- return scratch;
- },
- u_highlightColor : function() {
- return pointCloud._highlightColor;
- },
- u_constantColor : function() {
- return pointCloud._constantColor;
- },
- u_clippingPlanes : function() {
- var clippingPlanes = pointCloud.clippingPlanes;
- var isClipped = pointCloud.isClipped;
- return isClipped ? clippingPlanes.texture : context.defaultTexture;
- },
- u_clippingPlanesEdgeStyle : function() {
- var clippingPlanes = pointCloud.clippingPlanes;
- if (!defined(clippingPlanes)) {
- return Color.TRANSPARENT;
- }
- var style = Color.clone(clippingPlanes.edgeColor, scratchColor);
- style.alpha = clippingPlanes.edgeWidth;
- return style;
- },
- u_clippingPlanesMatrix : function() {
- var clippingPlanes = pointCloud.clippingPlanes;
- if (!defined(clippingPlanes)) {
- return Matrix4.IDENTITY;
- }
- var clippingPlanesOriginMatrix = defaultValue(pointCloud.clippingPlanesOriginMatrix, pointCloud._modelMatrix);
- Matrix4.multiply(context.uniformState.view3D, clippingPlanesOriginMatrix, scratchClippingPlaneMatrix);
- return Matrix4.multiply(scratchClippingPlaneMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix);
- }
- };
- if (isQuantized || isQuantizedDraco || isOctEncodedDraco) {
- uniformMap = combine(uniformMap, {
- u_quantizedVolumeScaleAndOctEncodedRange : function() {
- var scratch = scratchQuantizedVolumeScaleAndOctEncodedRange;
- if (defined(pointCloud._quantizedVolumeScale)) {
- var scale = Cartesian3.clone(pointCloud._quantizedVolumeScale, scratch);
- Cartesian3.divideByScalar(scale, pointCloud._quantizedRange, scratch);
- }
- scratch.w = pointCloud._octEncodedRange;
- return scratch;
- }
- });
- }
- if (defined(pointCloud._uniformMapLoaded)) {
- uniformMap = pointCloud._uniformMapLoaded(uniformMap);
- }
- pointCloud._drawCommand.uniformMap = uniformMap;
- }
- var defaultProperties = ['POSITION', 'COLOR', 'NORMAL', 'POSITION_ABSOLUTE'];
- function getStyleableProperties(source, properties) {
- // Get all the properties used by this style
- var regex = /czm_tiles3d_style_(\w+)/g;
- var matches = regex.exec(source);
- while (matches !== null) {
- var name = matches[1];
- if (properties.indexOf(name) === -1) {
- properties.push(name);
- }
- matches = regex.exec(source);
- }
- }
- function getVertexAttribute(vertexArray, index) {
- var numberOfAttributes = vertexArray.numberOfAttributes;
- for (var i = 0; i < numberOfAttributes; ++i) {
- var attribute = vertexArray.getAttribute(i);
- if (attribute.index === index) {
- return attribute;
- }
- }
- }
- function modifyStyleFunction(source) {
- // Replace occurrences of czm_tiles3d_style_DEFAULTPROPERTY
- var length = defaultProperties.length;
- for (var i = 0; i < length; ++i) {
- var property = defaultProperties[i];
- var styleName = 'czm_tiles3d_style_' + property;
- var replaceName = property.toLowerCase();
- source = source.replace(new RegExp(styleName + '(\\W)', 'g'), replaceName + '$1');
- }
- // Edit the function header to accept the point position, color, and normal
- return source.replace('()', '(vec3 position, vec3 position_absolute, vec4 color, vec3 normal)');
- }
- function createShaders(pointCloud, frameState, style) {
- var i;
- var name;
- var attribute;
- var context = frameState.context;
- var hasStyle = defined(style);
- var isQuantized = pointCloud._isQuantized;
- var isQuantizedDraco = pointCloud._isQuantizedDraco;
- var isOctEncoded16P = pointCloud._isOctEncoded16P;
- var isOctEncodedDraco = pointCloud._isOctEncodedDraco;
- var isRGB565 = pointCloud._isRGB565;
- var isTranslucent = pointCloud._isTranslucent;
- var hasColors = pointCloud._hasColors;
- var hasNormals = pointCloud._hasNormals;
- var hasBatchIds = pointCloud._hasBatchIds;
- var backFaceCulling = pointCloud._backFaceCulling;
- var normalShading = pointCloud._normalShading;
- var vertexArray = pointCloud._drawCommand.vertexArray;
- var clippingPlanes = pointCloud.clippingPlanes;
- var attenuation = pointCloud._attenuation;
- var colorStyleFunction;
- var showStyleFunction;
- var pointSizeStyleFunction;
- var styleTranslucent = isTranslucent;
- if (hasStyle) {
- var shaderState = {
- translucent : false
- };
- colorStyleFunction = style.getColorShaderFunction('getColorFromStyle', 'czm_tiles3d_style_', shaderState);
- showStyleFunction = style.getShowShaderFunction('getShowFromStyle', 'czm_tiles3d_style_', shaderState);
- pointSizeStyleFunction = style.getPointSizeShaderFunction('getPointSizeFromStyle', 'czm_tiles3d_style_', shaderState);
- if (defined(colorStyleFunction) && shaderState.translucent) {
- styleTranslucent = true;
- }
- }
- pointCloud._styleTranslucent = styleTranslucent;
- var hasColorStyle = defined(colorStyleFunction);
- var hasShowStyle = defined(showStyleFunction);
- var hasPointSizeStyle = defined(pointSizeStyleFunction);
- var hasClippedContent = pointCloud.isClipped;
- // Get the properties in use by the style
- var styleableProperties = [];
- if (hasColorStyle) {
- getStyleableProperties(colorStyleFunction, styleableProperties);
- colorStyleFunction = modifyStyleFunction(colorStyleFunction);
- }
- if (hasShowStyle) {
- getStyleableProperties(showStyleFunction, styleableProperties);
- showStyleFunction = modifyStyleFunction(showStyleFunction);
- }
- if (hasPointSizeStyle) {
- getStyleableProperties(pointSizeStyleFunction, styleableProperties);
- pointSizeStyleFunction = modifyStyleFunction(pointSizeStyleFunction);
- }
- var usesColorSemantic = (styleableProperties.indexOf('COLOR') >= 0);
- var usesNormalSemantic = (styleableProperties.indexOf('NORMAL') >= 0);
- // Split default properties from user properties
- var userProperties = styleableProperties.filter(function(property) { return defaultProperties.indexOf(property) === -1; });
- if (usesNormalSemantic && !hasNormals) {
- throw new RuntimeError('Style references the NORMAL semantic but the point cloud does not have normals');
- }
- // Disable vertex attributes that aren't used in the style, enable attributes that are
- var styleableShaderAttributes = pointCloud._styleableShaderAttributes;
- for (name in styleableShaderAttributes) {
- if (styleableShaderAttributes.hasOwnProperty(name)) {
- attribute = styleableShaderAttributes[name];
- var enabled = (userProperties.indexOf(name) >= 0);
- var vertexAttribute = getVertexAttribute(vertexArray, attribute.location);
- vertexAttribute.enabled = enabled;
- }
- }
- var usesColors = hasColors && (!hasColorStyle || usesColorSemantic);
- if (hasColors) {
- // Disable the color vertex attribute if the color style does not reference the color semantic
- var colorVertexAttribute = getVertexAttribute(vertexArray, colorLocation);
- colorVertexAttribute.enabled = usesColors;
- }
- var usesNormals = hasNormals && (normalShading || backFaceCulling || usesNormalSemantic);
- if (hasNormals) {
- // Disable the normal vertex attribute if normals are not used
- var normalVertexAttribute = getVertexAttribute(vertexArray, normalLocation);
- normalVertexAttribute.enabled = usesNormals;
- }
- var attributeLocations = {
- a_position : positionLocation
- };
- if (usesColors) {
- attributeLocations.a_color = colorLocation;
- }
- if (usesNormals) {
- attributeLocations.a_normal = normalLocation;
- }
- if (hasBatchIds) {
- attributeLocations.a_batchId = batchIdLocation;
- }
- var attributeDeclarations = '';
- var length = userProperties.length;
- for (i = 0; i < length; ++i) {
- name = userProperties[i];
- attribute = styleableShaderAttributes[name];
- if (!defined(attribute)) {
- throw new RuntimeError('Style references a property "' + name + '" that does not exist or is not styleable.');
- }
- var componentCount = attribute.componentCount;
- var attributeName = 'czm_tiles3d_style_' + name;
- var attributeType;
- if (componentCount === 1) {
- attributeType = 'float';
- } else {
- attributeType = 'vec' + componentCount;
- }
- attributeDeclarations += 'attribute ' + attributeType + ' ' + attributeName + '; \n';
- attributeLocations[attributeName] = attribute.location;
- }
- createUniformMap(pointCloud, frameState);
- var vs = 'attribute vec3 a_position; \n' +
- 'varying vec4 v_color; \n' +
- 'uniform vec4 u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier; \n' +
- 'uniform vec4 u_constantColor; \n' +
- 'uniform vec4 u_highlightColor; \n';
- vs += 'float u_pointSize; \n' +
- 'float u_time; \n';
- if (attenuation) {
- vs += 'float u_geometricError; \n' +
- 'float u_depthMultiplier; \n';
- }
- vs += attributeDeclarations;
- if (usesColors) {
- if (isTranslucent) {
- vs += 'attribute vec4 a_color; \n';
- } else if (isRGB565) {
- vs += 'attribute float a_color; \n' +
- 'const float SHIFT_RIGHT_11 = 1.0 / 2048.0; \n' +
- 'const float SHIFT_RIGHT_5 = 1.0 / 32.0; \n' +
- 'const float SHIFT_LEFT_11 = 2048.0; \n' +
- 'const float SHIFT_LEFT_5 = 32.0; \n' +
- 'const float NORMALIZE_6 = 1.0 / 64.0; \n' +
- 'const float NORMALIZE_5 = 1.0 / 32.0; \n';
- } else {
- vs += 'attribute vec3 a_color; \n';
- }
- }
- if (usesNormals) {
- if (isOctEncoded16P || isOctEncodedDraco) {
- vs += 'attribute vec2 a_normal; \n';
- } else {
- vs += 'attribute vec3 a_normal; \n';
- }
- }
- if (hasBatchIds) {
- vs += 'attribute float a_batchId; \n';
- }
- if (isQuantized || isQuantizedDraco || isOctEncodedDraco) {
- vs += 'uniform vec4 u_quantizedVolumeScaleAndOctEncodedRange; \n';
- }
- if (hasColorStyle) {
- vs += colorStyleFunction;
- }
- if (hasShowStyle) {
- vs += showStyleFunction;
- }
- if (hasPointSizeStyle) {
- vs += pointSizeStyleFunction;
- }
- vs += 'void main() \n' +
- '{ \n' +
- ' u_pointSize = u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier.x; \n' +
- ' u_time = u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier.y; \n';
- if (attenuation) {
- vs += ' u_geometricError = u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier.z; \n' +
- ' u_depthMultiplier = u_pointSizeAndTimeAndGeometricErrorAndDepthMultiplier.w; \n';
- }
- if (usesColors) {
- if (isTranslucent) {
- vs += ' vec4 color = a_color; \n';
- } else if (isRGB565) {
- vs += ' float compressed = a_color; \n' +
- ' float r = floor(compressed * SHIFT_RIGHT_11); \n' +
- ' compressed -= r * SHIFT_LEFT_11; \n' +
- ' float g = floor(compressed * SHIFT_RIGHT_5); \n' +
- ' compressed -= g * SHIFT_LEFT_5; \n' +
- ' float b = compressed; \n' +
- ' vec3 rgb = vec3(r * NORMALIZE_5, g * NORMALIZE_6, b * NORMALIZE_5); \n' +
- ' vec4 color = vec4(rgb, 1.0); \n';
- } else {
- vs += ' vec4 color = vec4(a_color, 1.0); \n';
- }
- } else {
- vs += ' vec4 color = u_constantColor; \n';
- }
- if (isQuantized || isQuantizedDraco) {
- vs += ' vec3 position = a_position * u_quantizedVolumeScaleAndOctEncodedRange.xyz; \n';
- } else {
- vs += ' vec3 position = a_position; \n';
- }
- vs += ' vec3 position_absolute = vec3(czm_model * vec4(position, 1.0)); \n';
- if (usesNormals) {
- if (isOctEncoded16P) {
- vs += ' vec3 normal = czm_octDecode(a_normal); \n';
- } else if (isOctEncodedDraco) {
- // Draco oct-encoding decodes to zxy order
- vs += ' vec3 normal = czm_octDecode(a_normal, u_quantizedVolumeScaleAndOctEncodedRange.w).zxy; \n';
- } else {
- vs += ' vec3 normal = a_normal; \n';
- }
- vs += ' vec3 normalEC = czm_normal * normal; \n';
- } else {
- vs += ' vec3 normal = vec3(1.0); \n';
- }
- if (hasColorStyle) {
- vs += ' color = getColorFromStyle(position, position_absolute, color, normal); \n';
- }
- if (hasShowStyle) {
- vs += ' float show = float(getShowFromStyle(position, position_absolute, color, normal)); \n';
- }
- if (hasPointSizeStyle) {
- vs += ' gl_PointSize = getPointSizeFromStyle(position, position_absolute, color, normal) * czm_pixelRatio; \n';
- } else if (attenuation) {
- vs += ' vec4 positionEC = czm_modelView * vec4(position, 1.0); \n' +
- ' float depth = -positionEC.z; \n' +
- // compute SSE for this point
- ' gl_PointSize = min((u_geometricError / depth) * u_depthMultiplier, u_pointSize); \n';
- } else {
- vs += ' gl_PointSize = u_pointSize; \n';
- }
- vs += ' color = color * u_highlightColor; \n';
- if (usesNormals && normalShading) {
- vs += ' float diffuseStrength = czm_getLambertDiffuse(czm_sunDirectionEC, normalEC); \n' +
- ' diffuseStrength = max(diffuseStrength, 0.4); \n' + // Apply some ambient lighting
- ' color.xyz *= diffuseStrength; \n';
- }
- vs += ' v_color = color; \n' +
- ' gl_Position = czm_modelViewProjection * vec4(position, 1.0); \n';
- if (usesNormals && backFaceCulling) {
- vs += ' float visible = step(-normalEC.z, 0.0); \n' +
- ' gl_Position *= visible; \n' +
- ' gl_PointSize *= visible; \n';
- }
- if (hasShowStyle) {
- vs += ' gl_Position *= show; \n' +
- ' gl_PointSize *= show; \n';
- }
- vs += '} \n';
- var fs = 'varying vec4 v_color; \n';
- if (hasClippedContent) {
- fs += 'uniform sampler2D u_clippingPlanes; \n' +
- 'uniform mat4 u_clippingPlanesMatrix; \n' +
- 'uniform vec4 u_clippingPlanesEdgeStyle; \n';
- fs += '\n';
- fs += getClippingFunction(clippingPlanes, context);
- fs += '\n';
- }
- fs += 'void main() \n' +
- '{ \n' +
- ' gl_FragColor = czm_gammaCorrect(v_color); \n';
- if (hasClippedContent) {
- fs += getClipAndStyleCode('u_clippingPlanes', 'u_clippingPlanesMatrix', 'u_clippingPlanesEdgeStyle');
- }
- fs += '} \n';
- if (defined(pointCloud._vertexShaderLoaded)) {
- vs = pointCloud._vertexShaderLoaded(vs);
- }
- if (defined(pointCloud._fragmentShaderLoaded)) {
- fs = pointCloud._fragmentShaderLoaded(fs);
- }
- var drawCommand = pointCloud._drawCommand;
- if (defined(drawCommand.shaderProgram)) {
- // Destroy the old shader
- drawCommand.shaderProgram.destroy();
- }
- drawCommand.shaderProgram = ShaderProgram.fromCache({
- context : context,
- vertexShaderSource : vs,
- fragmentShaderSource : fs,
- attributeLocations : attributeLocations
- });
- try {
- // Check if the shader compiles correctly. If not there is likely a syntax error with the style.
- drawCommand.shaderProgram._bind();
- } catch (error) {
- // Rephrase the error.
- throw new RuntimeError('Error generating style shader: this may be caused by a type mismatch, index out-of-bounds, or other syntax error.');
- }
- }
- function decodeDraco(pointCloud, context) {
- if (pointCloud._decodingState === DecodingState.READY) {
- return false;
- }
- if (pointCloud._decodingState === DecodingState.NEEDS_DECODE) {
- var parsedContent = pointCloud._parsedContent;
- var draco = parsedContent.draco;
- var decodePromise = DracoLoader.decodePointCloud(draco, context);
- if (defined(decodePromise)) {
- pointCloud._decodingState = DecodingState.DECODING;
- decodePromise.then(function(result) {
- pointCloud._decodingState = DecodingState.READY;
- var decodedPositions = defined(result.POSITION) ? result.POSITION.array : undefined;
- var decodedRgb = defined(result.RGB) ? result.RGB.array : undefined;
- var decodedRgba = defined(result.RGBA) ? result.RGBA.array : undefined;
- var decodedNormals = defined(result.NORMAL) ? result.NORMAL.array : undefined;
- var decodedBatchIds = defined(result.BATCH_ID) ? result.BATCH_ID.array : undefined;
- var isQuantizedDraco = defined(decodedPositions) && defined(result.POSITION.data.quantization);
- var isOctEncodedDraco = defined(decodedNormals) && defined(result.NORMAL.data.quantization);
- if (isQuantizedDraco) {
- // Draco quantization range == quantized volume scale - size in meters of the quantized volume
- // Internal quantized range is the range of values of the quantized data, e.g. 255 for 8-bit, 1023 for 10-bit, etc
- var quantization = result.POSITION.data.quantization;
- var range = quantization.range;
- pointCloud._quantizedVolumeScale = Cartesian3.fromElements(range, range, range);
- pointCloud._quantizedVolumeOffset = Cartesian3.unpack(quantization.minValues);
- pointCloud._quantizedRange = (1 << quantization.quantizationBits) - 1.0;
- pointCloud._isQuantizedDraco = true;
- }
- if (isOctEncodedDraco) {
- pointCloud._octEncodedRange = (1 << result.NORMAL.data.quantization.quantizationBits) - 1.0;
- pointCloud._isOctEncodedDraco = true;
- }
- var styleableProperties = parsedContent.styleableProperties;
- var batchTableProperties = draco.batchTableProperties;
- for (var name in batchTableProperties) {
- if (batchTableProperties.hasOwnProperty(name)) {
- var property = result[name];
- if (!defined(styleableProperties)) {
- styleableProperties = {};
- }
- styleableProperties[name] = {
- typedArray : property.array,
- componentCount : property.data.componentsPerAttribute
- };
- }
- }
- parsedContent.positions = defaultValue(decodedPositions, parsedContent.positions);
- parsedContent.colors = defaultValue(defaultValue(decodedRgba, decodedRgb), parsedContent.colors);
- parsedContent.normals = defaultValue(decodedNormals, parsedContent.normals);
- parsedContent.batchIds = defaultValue(decodedBatchIds, parsedContent.batchIds);
- parsedContent.styleableProperties = styleableProperties;
- }).otherwise(function(error) {
- pointCloud._decodingState = DecodingState.FAILED;
- pointCloud._readyPromise.reject(error);
- });
- }
- }
- return true;
- }
- var scratchComputedTranslation = new Cartesian4();
- var scratchScale = new Cartesian3();
- PointCloud.prototype.update = function(frameState) {
- var context = frameState.context;
- var decoding = decodeDraco(this, context);
- if (decoding) {
- return;
- }
- var shadersDirty = false;
- var modelMatrixDirty = !Matrix4.equals(this._modelMatrix, this.modelMatrix);
- if (this._mode !== frameState.mode) {
- this._mode = frameState.mode;
- modelMatrixDirty = true;
- }
- if (!defined(this._drawCommand)) {
- createResources(this, frameState);
- modelMatrixDirty = true;
- shadersDirty = true;
- this._ready = true;
- this._readyPromise.resolve(this);
- this._parsedContent = undefined; // Unload
- }
- if (modelMatrixDirty) {
- Matrix4.clone(this.modelMatrix, this._modelMatrix);
- var modelMatrix = this._drawCommand.modelMatrix;
- Matrix4.clone(this._modelMatrix, modelMatrix);
- if (defined(this._rtcCenter)) {
- Matrix4.multiplyByTranslation(modelMatrix, this._rtcCenter, modelMatrix);
- }
- if (defined(this._quantizedVolumeOffset)) {
- Matrix4.multiplyByTranslation(modelMatrix, this._quantizedVolumeOffset, modelMatrix);
- }
- if (frameState.mode !== SceneMode.SCENE3D) {
- var projection = frameState.mapProjection;
- var translation = Matrix4.getColumn(modelMatrix, 3, scratchComputedTranslation);
- if (!Cartesian4.equals(translation, Cartesian4.UNIT_W)) {
- Transforms.basisTo2D(projection, modelMatrix, modelMatrix);
- }
- }
- var boundingSphere = this._drawCommand.boundingVolume;
- BoundingSphere.clone(this._boundingSphere, boundingSphere);
- if (this._cull) {
- var center = boundingSphere.center;
- Matrix4.multiplyByPoint(modelMatrix, center, center);
- var scale = Matrix4.getScale(modelMatrix, scratchScale);
- boundingSphere.radius *= Cartesian3.maximumComponent(scale);
- }
- }
- if (this.clippingPlanesDirty) {
- this.clippingPlanesDirty = false;
- shadersDirty = true;
- }
- if (this._attenuation !== this.attenuation) {
- this._attenuation = this.attenuation;
- shadersDirty = true;
- }
- if (this.backFaceCulling !== this._backFaceCulling) {
- this._backFaceCulling = this.backFaceCulling;
- shadersDirty = true;
- }
- if (this.normalShading !== this._normalShading) {
- this._normalShading = this.normalShading;
- shadersDirty = true;
- }
- if (this._style !== this.style || this.styleDirty) {
- this._style = this.style;
- this.styleDirty = false;
- shadersDirty = true;
- }
- if (shadersDirty) {
- createShaders(this, frameState, this._style);
- }
- this._drawCommand.castShadows = ShadowMode.castShadows(this.shadows);
- this._drawCommand.receiveShadows = ShadowMode.receiveShadows(this.shadows);
- // Update the render state
- var isTranslucent = (this._highlightColor.alpha < 1.0) || (this._constantColor.alpha < 1.0) || this._styleTranslucent;
- this._drawCommand.renderState = isTranslucent ? this._translucentRenderState : this._opaqueRenderState;
- this._drawCommand.pass = isTranslucent ? Pass.TRANSLUCENT : this._opaquePass;
- var commandList = frameState.commandList;
- var passes = frameState.passes;
- if (passes.render || passes.pick) {
- commandList.push(this._drawCommand);
- }
- };
- PointCloud.prototype.isDestroyed = function() {
- return false;
- };
- PointCloud.prototype.destroy = function() {
- var command = this._drawCommand;
- if (defined(command)) {
- command.vertexArray = command.vertexArray && command.vertexArray.destroy();
- command.shaderProgram = command.shaderProgram && command.shaderProgram.destroy();
- }
- return destroyObject(this);
- };
- export default PointCloud;
|