From 30eb4effcf3c284e272ef96f03a9bbb498d8327f Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Mon, 19 Sep 2016 16:58:17 +1000 Subject: [PATCH 01/23] Fix off by one error in compressing/decompressing texture coordinates. --- Source/Core/AttributeCompression.js | 22 ++++++++++--------- .../decompressTextureCoordinates.glsl | 5 +++-- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Source/Core/AttributeCompression.js b/Source/Core/AttributeCompression.js index f4a41c5da943..d5e6973d29cf 100644 --- a/Source/Core/AttributeCompression.js +++ b/Source/Core/AttributeCompression.js @@ -75,9 +75,9 @@ define([ * @param {Cartesian3} vector The normalized vector to be compressed into 2 byte 'oct' encoding. * @param {Cartesian2} result The 2 byte oct-encoded unit length vector. * @returns {Cartesian2} The 2 byte oct-encoded unit length vector. - * + * * @exception {DeveloperError} vector must be normalized. - * + * * @see AttributeCompression.octEncodeInRange * @see AttributeCompression.octDecode */ @@ -124,14 +124,14 @@ define([ /** * Decodes a unit-length vector in 2 byte 'oct' encoding to a normalized 3-component vector. - * + * * @param {Number} x The x component of the oct-encoded unit length vector. * @param {Number} y The y component of the oct-encoded unit length vector. * @param {Cartesian3} result The decoded and normalized vector. * @returns {Cartesian3} The decoded and normalized vector. - * + * * @exception {DeveloperError} x and y must be an unsigned normalized integer between 0 and 255. - * + * * @see AttributeCompression.octDecodeInRange */ AttributeCompression.octDecode = function(x, y, result) { @@ -268,7 +268,7 @@ define([ /** * Pack texture coordinates into a single float. The texture coordinates will only preserve 12 bits of precision. * - * @param {Cartesian2} textureCoordinates The texture coordinates to compress + * @param {Cartesian2} textureCoordinates The texture coordinates to compress. Both coordinates must be in the range 0.0-1.0. * @returns {Number} The packed texture coordinates. * */ @@ -279,8 +279,9 @@ define([ } //>>includeEnd('debug'); - var x = textureCoordinates.x === 1.0 ? 4095.0 : (textureCoordinates.x * 4096.0) | 0; - var y = textureCoordinates.y === 1.0 ? 4095.0 : (textureCoordinates.y * 4096.0) | 0; + // Move x and y to the range 0-4095; + var x = (textureCoordinates.x * 4095.0) | 0; + var y = (textureCoordinates.y * 4095.0) | 0; return 4096.0 * x + y; }; @@ -303,8 +304,9 @@ define([ //>>includeEnd('debug'); var temp = compressed / 4096.0; - result.x = Math.floor(temp) / 4096.0; - result.y = temp - Math.floor(temp); + var xZeroTo4095 = Math.floor(temp); + result.x = xZeroTo4095 / 4095.0; + result.y = (compressed - xZeroTo4095 * 4096) / 4095; return result; }; diff --git a/Source/Shaders/Builtin/Functions/decompressTextureCoordinates.glsl b/Source/Shaders/Builtin/Functions/decompressTextureCoordinates.glsl index c91a5e87473c..fa2a6814382c 100644 --- a/Source/Shaders/Builtin/Functions/decompressTextureCoordinates.glsl +++ b/Source/Shaders/Builtin/Functions/decompressTextureCoordinates.glsl @@ -10,7 +10,8 @@ vec2 czm_decompressTextureCoordinates(float encoded) { float temp = encoded / 4096.0; - float stx = floor(temp) / 4096.0; - float sty = temp - floor(temp); + float xZeroTo4095 = floor(temp); + float stx = xZeroTo4095 / 4095.0; + float sty = (encoded - xZeroTo4095 * 4096.0) / 4095.0; return vec2(stx, sty); } From 48a4a5d7e0c79ced1daf1b37ab78cadc35dae230 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 21 Sep 2016 16:03:58 -0400 Subject: [PATCH 02/23] Use batch table for per instance geometry attributes. --- Source/Scene/Primitive.js | 187 +++++++++++++++++- Source/Scene/PrimitivePipeline.js | 33 ++++ .../Appearances/AllMaterialAppearanceVS.glsl | 1 + .../BasicMaterialAppearanceVS.glsl | 1 + .../EllipsoidSurfaceAppearanceVS.glsl | 1 + .../PerInstanceColorAppearanceVS.glsl | 1 + .../PerInstanceFlatColorAppearanceVS.glsl | 1 + .../Appearances/PointAppearanceVS.glsl | 1 + .../PolylineColorAppearanceVS.glsl | 1 + .../PolylineMaterialAppearanceVS.glsl | 1 + .../TexturedMaterialAppearanceVS.glsl | 1 + 11 files changed, 224 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 995078d0fe1b..2b7750eb75f8 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -3,7 +3,9 @@ define([ '../Core/BoundingSphere', '../Core/Cartesian2', '../Core/Cartesian3', + '../Core/Cartesian4', '../Core/clone', + '../Core/Color', '../Core/combine', '../Core/ComponentDatatype', '../Core/defaultValue', @@ -30,6 +32,7 @@ define([ '../Renderer/ShaderSource', '../Renderer/VertexArray', '../ThirdParty/when', + './BatchTable', './CullFace', './Pass', './PrimitivePipeline', @@ -40,7 +43,9 @@ define([ BoundingSphere, Cartesian2, Cartesian3, + Cartesian4, clone, + Color, combine, ComponentDatatype, defaultValue, @@ -67,6 +72,7 @@ define([ ShaderSource, VertexArray, when, + BatchTable, CullFace, Pass, PrimitivePipeline, @@ -350,6 +356,9 @@ define([ this._createGeometryResults = undefined; this._ready = false; this._readyPromise = when.defer(); + + this._batchTable = undefined; + this._batchTableAttributeIndices = undefined; } defineProperties(Primitive.prototype, { @@ -518,6 +527,145 @@ define([ } }); + function getCommonPerInstanceAttributeNames(instances) { + var length = instances.length; + + var attributesInAllInstances = []; + var attributes0 = instances[0].attributes; + var name; + + for (name in attributes0) { + if (attributes0.hasOwnProperty(name)) { + var attribute = attributes0[name]; + var inAllInstances = true; + + // Does this same attribute exist in all instances? + for (var i = 1; i < length; ++i) { + var otherAttribute = instances[i].attributes[name]; + + if (!defined(otherAttribute) || + (attribute.componentDatatype !== otherAttribute.componentDatatype) || + (attribute.componentsPerAttribute !== otherAttribute.componentsPerAttribute) || + (attribute.normalize !== otherAttribute.normalize)) { + + inAllInstances = false; + break; + } + } + + if (inAllInstances) { + attributesInAllInstances.push(name); + } + } + } + + return attributesInAllInstances; + } + + var scratchGetAttributeCartesian2 = new Cartesian2(); + var scratchGetAttributeCartesian3 = new Cartesian3(); + var scratchGetAttributeCartesian4 = new Cartesian4(); + + function getAttributeValue(attribute) { + var componentsPerAttribute = attribute.componentsPerAttribute; + var value = attribute.value; + if (componentsPerAttribute === 1) { + return value[0]; + } else if (componentsPerAttribute === 2) { + return Cartesian2.unpack(value, 0, scratchGetAttributeCartesian2); + } else if (componentsPerAttribute === 3) { + return Cartesian3.unpack(value, 0, scratchGetAttributeCartesian3); + } else if (componentsPerAttribute === 4) { + return Cartesian4.unpack(value, 0, scratchGetAttributeCartesian4); + } + } + + function createBatchTable(primitive, context) { + var geometryInstances = primitive.geometryInstances; + var instances = (isArray(geometryInstances)) ? geometryInstances : [geometryInstances]; + var numberOfInstances = instances.length; + if (numberOfInstances === 0) { + return; + } + + var names = getCommonPerInstanceAttributeNames(instances); + var length = names.length; + + var allowPicking = primitive.allowPicking; + var attributesLength = allowPicking ? length + 1 : length; + var attributes = new Array(attributesLength); + var attributeIndices = {}; + + var firstInstance = instances[0]; + var instanceAttributes = firstInstance.attributes; + + var i; + var name; + var attribute; + + for (i = 0; i < length; ++i) { + name = names[i]; + attribute = instanceAttributes[name]; + + attributeIndices[name] = i; + attributes[i] = { + functionName : 'czm_batchTable_' + name, + componentDatatype : attribute.componentDatatype, + componentsPerAttribute : attribute.componentsPerAttribute, + normalize : attribute.normalize + }; + } + + if (allowPicking) { + attributes[attributesLength - 1] = { + functionName : 'czm_batchTable_pickColor', + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + componentsPerAttribute : 4, + normalize : true + }; + } + + var batchTable = new BatchTable(attributes, numberOfInstances); + + for (i = 0; i < numberOfInstances; ++i) { + var instance = instances[i]; + instanceAttributes = instance.attributes; + + for (var j = 0; j < length; ++j) { + name = names[j]; + attribute = instanceAttributes[name]; + var value = getAttributeValue(attribute); + var attributeIndex = attributeIndices[name]; + batchTable.setBatchedAttribute(i, attributeIndex, value); + } + + if (allowPicking) { + var pickObject = { + primitive : defaultValue(instance.pickPrimitive, primitive) + }; + + if (defined(instance.id)) { + pickObject.id = instance.id; + } + + var pickId = context.createPickId(pickObject); + primitive._pickIds.push(pickId); + + var pickColor = pickId.color; + var color = scratchGetAttributeCartesian4; + color.x = Color.floatToByte(pickColor.red); + color.y = Color.floatToByte(pickColor.green); + color.z = Color.floatToByte(pickColor.blue); + color.w = Color.floatToByte(pickColor.alpha); + + batchTable.setBatchedAttribute(i, attributesLength - 1, color); + } + } + + primitive._batchTable = batchTable; + primitive._batchTableAttributeIndices = attributeIndices; + } + function cloneAttribute(attribute) { var clonedValues; if (isArray(attribute.values)) { @@ -667,22 +815,38 @@ define([ }; Primitive._appendShowToShader = function(primitive, vertexShaderSource) { - if (!defined(primitive._attributeLocations.show)) { + if (!defined(primitive._batchTableAttributeIndices.show)) { return vertexShaderSource; } var renamedVS = ShaderSource.replaceMain(vertexShaderSource, 'czm_non_show_main'); var showMain = - 'attribute float show;\n' + 'void main() \n' + '{ \n' + ' czm_non_show_main(); \n' + - ' gl_Position *= show; \n' + + ' gl_Position *= czm_batchTable_show; \n' + '}'; return renamedVS + '\n' + showMain; }; + function updateColorAttribute(primitive, vertexShaderSource) { + // some appearances have a color attribute for per vertex color. + // only remove if color is a per instance attribute. + if (!defined(primitive._batchTableAttributeIndices.color)) { + return vertexShaderSource; + } + + if (vertexShaderSource.search(/attribute\s+vec4\s+color;/g) === -1) { + return vertexShaderSource; + } + + var modifiedVS = vertexShaderSource; + modifiedVS = modifiedVS.replace(/attribute\s+vec4\s+color;/g, ''); + modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_color(batchId)$2'); + return modifiedVS; + } + function modifyForEncodedNormals(primitive, vertexShaderSource) { if (!primitive.compressVertices) { return vertexShaderSource; @@ -1149,17 +1313,24 @@ define([ var attributeLocations = primitive._attributeLocations; - var vs = Primitive._modifyShaderPosition(primitive, appearance.vertexShaderSource, frameState.scene3DOnly); + var vs = primitive._batchTable.getVertexShaderCallback()(appearance.vertexShaderSource); + vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); vs = Primitive._appendShowToShader(primitive, vs); + vs = updateColorAttribute(primitive, vs); vs = modifyForEncodedNormals(primitive, vs); var fs = appearance.getFragmentShaderSource(); // Create pick program if (primitive.allowPicking) { + var vsPick = ShaderSource.createPickVertexShaderSource(vs); + + vsPick = vsPick.replace(/attribute\s+vec4\s+pickColor;/g, ''); + vsPick = vsPick.replace(/(\b)pickColor(\b)/g, '$1czm_batchTable_pickColor(batchId)$2'); + primitive._pickSP = ShaderProgram.replaceCache({ context : context, shaderProgram : primitive._pickSP, - vertexShaderSource : ShaderSource.createPickVertexShaderSource(vs), + vertexShaderSource : vsPick, fragmentShaderSource : ShaderSource.createPickFragmentShaderSource(fs, 'varying'), attributeLocations : attributeLocations }); @@ -1205,6 +1376,7 @@ define([ } } var uniforms = combine(appearanceUniformMap, materialUniformMap); + uniforms = primitive._batchTable.getUniformMapCallback()(uniforms); if (defined(primitive.rtcCenter)) { uniforms.u_modifiedModelView = function() { @@ -1440,6 +1612,11 @@ define([ createVertexArray(this, frameState); } + if (!defined(this._batchTable)) { + createBatchTable(this, frameState.context); + } + this._batchTable.update(frameState); + if (!this.show || this._state !== PrimitiveState.COMPLETE) { return; } diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index c4986f352daa..6e6201f83b15 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -109,6 +109,37 @@ define([ } } + function addGeometryBatchId(geometry, batchId) { + var attributes = geometry.attributes; + var positionAttr = attributes.position; + var numberOfComponents = positionAttr.values.length / positionAttr.componentsPerAttribute; + + attributes.batchId = new GeometryAttribute({ + componentDatatype : ComponentDatatype.FLOAT, + componentsPerAttribute : 1, + values : new Float32Array(numberOfComponents) + }); + + var values = attributes.batchId.values; + for (var j = 0; j < numberOfComponents; ++j) { + values[j] = batchId; + } + } + + function addBatchIds(instances) { + var length = instances.length; + + for (var i = 0; i < length; ++i) { + var instance = instances[i]; + if (defined(instance.geometry)) { + addGeometryBatchId(instance.geometry, i); + } else { + addGeometryBatchId(instance.westHemisphereGeometry, i); + addGeometryBatchId(instance.eastHemisphereGeometry, i); + } + } + } + function getCommonPerInstanceAttributeNames(instances) { var length = instances.length; @@ -218,6 +249,8 @@ define([ } } + addBatchIds(instances); + // Add pickColor attribute for picking individual instances if (allowPicking) { addPickColorAttribute(instances, pickIds); diff --git a/Source/Shaders/Appearances/AllMaterialAppearanceVS.glsl b/Source/Shaders/Appearances/AllMaterialAppearanceVS.glsl index 59d74a27b25a..72e2081604ef 100644 --- a/Source/Shaders/Appearances/AllMaterialAppearanceVS.glsl +++ b/Source/Shaders/Appearances/AllMaterialAppearanceVS.glsl @@ -4,6 +4,7 @@ attribute vec3 normal; attribute vec3 tangent; attribute vec3 binormal; attribute vec2 st; +attribute float batchId; varying vec3 v_positionEC; varying vec3 v_normalEC; diff --git a/Source/Shaders/Appearances/BasicMaterialAppearanceVS.glsl b/Source/Shaders/Appearances/BasicMaterialAppearanceVS.glsl index 6fe9772ba516..0d496a877e7c 100644 --- a/Source/Shaders/Appearances/BasicMaterialAppearanceVS.glsl +++ b/Source/Shaders/Appearances/BasicMaterialAppearanceVS.glsl @@ -1,6 +1,7 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 normal; +attribute float batchId; varying vec3 v_positionEC; varying vec3 v_normalEC; diff --git a/Source/Shaders/Appearances/EllipsoidSurfaceAppearanceVS.glsl b/Source/Shaders/Appearances/EllipsoidSurfaceAppearanceVS.glsl index 61f12dcb32e2..1bd13c9a5382 100644 --- a/Source/Shaders/Appearances/EllipsoidSurfaceAppearanceVS.glsl +++ b/Source/Shaders/Appearances/EllipsoidSurfaceAppearanceVS.glsl @@ -1,6 +1,7 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec2 st; +attribute float batchId; varying vec3 v_positionMC; varying vec3 v_positionEC; diff --git a/Source/Shaders/Appearances/PerInstanceColorAppearanceVS.glsl b/Source/Shaders/Appearances/PerInstanceColorAppearanceVS.glsl index aa8de58a0ba9..b429e64c6896 100644 --- a/Source/Shaders/Appearances/PerInstanceColorAppearanceVS.glsl +++ b/Source/Shaders/Appearances/PerInstanceColorAppearanceVS.glsl @@ -2,6 +2,7 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 normal; attribute vec4 color; +attribute float batchId; varying vec3 v_positionEC; varying vec3 v_normalEC; diff --git a/Source/Shaders/Appearances/PerInstanceFlatColorAppearanceVS.glsl b/Source/Shaders/Appearances/PerInstanceFlatColorAppearanceVS.glsl index 44c759da268e..ce015c678423 100644 --- a/Source/Shaders/Appearances/PerInstanceFlatColorAppearanceVS.glsl +++ b/Source/Shaders/Appearances/PerInstanceFlatColorAppearanceVS.glsl @@ -1,6 +1,7 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec4 color; +attribute float batchId; varying vec4 v_color; diff --git a/Source/Shaders/Appearances/PointAppearanceVS.glsl b/Source/Shaders/Appearances/PointAppearanceVS.glsl index dd4a639ea7fa..4d41d523be98 100644 --- a/Source/Shaders/Appearances/PointAppearanceVS.glsl +++ b/Source/Shaders/Appearances/PointAppearanceVS.glsl @@ -1,6 +1,7 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 color; +attribute float batchId; uniform float pointSize; diff --git a/Source/Shaders/Appearances/PolylineColorAppearanceVS.glsl b/Source/Shaders/Appearances/PolylineColorAppearanceVS.glsl index f096e4a0d676..db7c610d10d6 100644 --- a/Source/Shaders/Appearances/PolylineColorAppearanceVS.glsl +++ b/Source/Shaders/Appearances/PolylineColorAppearanceVS.glsl @@ -6,6 +6,7 @@ attribute vec3 nextPosition3DHigh; attribute vec3 nextPosition3DLow; attribute vec2 expandAndWidth; attribute vec4 color; +attribute float batchId; varying vec4 v_color; diff --git a/Source/Shaders/Appearances/PolylineMaterialAppearanceVS.glsl b/Source/Shaders/Appearances/PolylineMaterialAppearanceVS.glsl index 9148abc52bce..dcb40b5ad322 100644 --- a/Source/Shaders/Appearances/PolylineMaterialAppearanceVS.glsl +++ b/Source/Shaders/Appearances/PolylineMaterialAppearanceVS.glsl @@ -6,6 +6,7 @@ attribute vec3 nextPosition3DHigh; attribute vec3 nextPosition3DLow; attribute vec2 expandAndWidth; attribute vec2 st; +attribute float batchId; varying float v_width; varying vec2 v_st; diff --git a/Source/Shaders/Appearances/TexturedMaterialAppearanceVS.glsl b/Source/Shaders/Appearances/TexturedMaterialAppearanceVS.glsl index b606f12a0ef1..19c102bba321 100644 --- a/Source/Shaders/Appearances/TexturedMaterialAppearanceVS.glsl +++ b/Source/Shaders/Appearances/TexturedMaterialAppearanceVS.glsl @@ -2,6 +2,7 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 normal; attribute vec2 st; +attribute float batchId; varying vec3 v_positionEC; varying vec3 v_normalEC; From a9c607f43ffe8c95b486d33f9cc8cfb411b78ee7 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 21 Sep 2016 17:02:04 -0400 Subject: [PATCH 03/23] Update getting and setting per instance geometry attributes to use batch table. --- Source/Scene/Primitive.js | 113 +++++++++++--------------------------- 1 file changed, 33 insertions(+), 80 deletions(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 2b7750eb75f8..aa56b78e2ea2 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -566,9 +566,8 @@ define([ var scratchGetAttributeCartesian3 = new Cartesian3(); var scratchGetAttributeCartesian4 = new Cartesian4(); - function getAttributeValue(attribute) { - var componentsPerAttribute = attribute.componentsPerAttribute; - var value = attribute.value; + function getAttributeValue(value) { + var componentsPerAttribute = value.length; if (componentsPerAttribute === 1) { return value[0]; } else if (componentsPerAttribute === 2) { @@ -634,7 +633,7 @@ define([ for (var j = 0; j < length; ++j) { name = names[j]; attribute = instanceAttributes[name]; - var value = getAttributeValue(attribute); + var value = getAttributeValue(attribute.value); var attributeIndex = attributeIndices[name]; batchTable.setBatchedAttribute(i, attributeIndex, value); } @@ -1197,7 +1196,6 @@ define([ function createVertexArray(primitive, frameState) { var attributeLocations = primitive._attributeLocations; var geometries = primitive._geometries; - var vaAttributes = primitive._vaAttributes; var scene3DOnly = frameState.scene3DOnly; var context = frameState.context; @@ -1206,24 +1204,12 @@ define([ for (var i = 0; i < length; ++i) { var geometry = geometries[i]; - var attributes = vaAttributes[i]; - var vaLength = attributes.length; - for (var j = 0; j < vaLength; ++j) { - var attribute = attributes[j]; - attribute.vertexBuffer = Buffer.createVertexBuffer({ - context : context, - typedArray : attribute.values, - usage : BufferUsage.DYNAMIC_DRAW}); - delete attribute.values; - } - va.push(VertexArray.fromGeometry({ context : context, geometry : geometry, attributeLocations : attributeLocations, bufferUsage : BufferUsage.STATIC_DRAW, - interleave : primitive._interleave, - vertexArrayAttributes : attributes + interleave : primitive._interleave })); if (defined(primitive._createBoundingVolumeFunction)) { @@ -1447,41 +1433,6 @@ define([ } } - function updatePerInstanceAttributes(primitive) { - if (primitive._dirtyAttributes.length === 0) { - return; - } - - var attributes = primitive._dirtyAttributes; - var length = attributes.length; - for (var i = 0; i < length; ++i) { - var attribute = attributes[i]; - var value = attribute.value; - var indices = attribute.indices; - var indicesLength = indices.length; - for (var j = 0; j < indicesLength; ++j) { - var index = indices[j]; - var offset = index.offset; - var count = index.count; - - var vaAttribute = index.attribute; - var componentDatatype = vaAttribute.componentDatatype; - var componentsPerAttribute = vaAttribute.componentsPerAttribute; - - var typedArray = ComponentDatatype.createTypedArray(componentDatatype, count * componentsPerAttribute); - for (var k = 0; k < count; ++k) { - typedArray.set(value, k * componentsPerAttribute); - } - - var offsetInBytes = offset * componentsPerAttribute * ComponentDatatype.getSizeInBytes(componentDatatype); - vaAttribute.vertexBuffer.copyFromArrayView(typedArray, offsetInBytes); - } - attribute.dirty = false; - } - - attributes.length = 0; - } - function updateBoundingVolumes(primitive, frameState) { // Update bounding volumes for primitives that are sized in pixels. // The pixel size in meters varies based on the distance from the camera. @@ -1600,6 +1551,11 @@ define([ return; } + if (!defined(this._batchTable)) { + createBatchTable(this, frameState.context); + } + this._batchTable.update(frameState); + if (this._state !== PrimitiveState.COMPLETE && this._state !== PrimitiveState.COMBINED) { if (this.asynchronous) { loadAsynchronous(this, frameState); @@ -1612,11 +1568,6 @@ define([ createVertexArray(this, frameState); } - if (!defined(this._batchTable)) { - createBatchTable(this, frameState.context); - } - this._batchTable.update(frameState); - if (!this.show || this._state !== PrimitiveState.COMPLETE) { return; } @@ -1665,36 +1616,34 @@ define([ commandFunc(this, appearance, material, translucent, twoPasses, this._colorCommands, this._pickCommands, frameState); } - updatePerInstanceAttributes(this); - var updateAndQueueCommandsFunc = defaultValue(this._updateAndQueueCommandsFunction, updateAndQueueCommands); updateAndQueueCommandsFunc(this, frameState, this._colorCommands, this._pickCommands, this.modelMatrix, this.cull, this.debugShowBoundingVolume, twoPasses); }; - function createGetFunction(name, perInstanceAttributes) { - var attribute = perInstanceAttributes[name]; + function createGetFunction(batchTable, instanceIndex, attributeIndex) { return function() { - if (defined(attribute) && defined(attribute.value)) { - return perInstanceAttributes[name].value; + var attributeValue = batchTable.getBatchedAttribute(instanceIndex, attributeIndex); + var attribute = batchTable.attributes[attributeIndex]; + var componentsPerAttribute = attribute.componentsPerAttribute; + var value = ComponentDatatype.createTypedArray(attribute.componentDatatype, componentsPerAttribute); + if (defined(attributeValue.constructor.pack)) { + attributeValue.constructor.pack(attributeValue, value, 0); + } else { + value[0] = attributeValue; } - return attribute; + return value; }; } - function createSetFunction(name, perInstanceAttributes, dirtyList) { - return function (value) { + function createSetFunction(batchTable, instanceIndex, attributeIndex) { + return function(value) { //>>includeStart('debug', pragmas.debug); if (!defined(value) || !defined(value.length) || value.length < 1 || value.length > 4) { throw new DeveloperError('value must be and array with length between 1 and 4.'); } //>>includeEnd('debug'); - - var attribute = perInstanceAttributes[name]; - attribute.value = value; - if (!attribute.dirty && attribute.valid) { - dirtyList.push(attribute); - attribute.dirty = true; - } + var attributeValue = getAttributeValue(value); + batchTable.setBatchedAttribute(instanceIndex, attributeIndex, attributeValue); }; } @@ -1718,7 +1667,7 @@ define([ if (!defined(id)) { throw new DeveloperError('id is required'); } - if (!defined(this._perInstanceAttributeLocations)) { + if (!defined(this._batchTable)) { throw new DeveloperError('must call update before calling getGeometryInstanceAttributes'); } //>>includeEnd('debug'); @@ -1738,21 +1687,25 @@ define([ if (index === -1) { return undefined; } + var attributes = this._perInstanceAttributeCache[index]; if (defined(attributes)) { return attributes; } - var perInstanceAttributes = this._perInstanceAttributeLocations[index]; + var batchTable = this._batchTable; + var perInstanceAttributeIndices = this._batchTableAttributeIndices; attributes = {}; var properties = {}; var hasProperties = false; - for (var name in perInstanceAttributes) { - if (perInstanceAttributes.hasOwnProperty(name)) { + for (var name in perInstanceAttributeIndices) { + if (perInstanceAttributeIndices.hasOwnProperty(name)) { + var attributeIndex = perInstanceAttributeIndices[name]; + hasProperties = true; properties[name] = { - get : createGetFunction(name, perInstanceAttributes) + get : createGetFunction(batchTable, index, attributeIndex) }; var createSetter = true; @@ -1777,7 +1730,7 @@ define([ } if (createSetter) { - properties[name].set = createSetFunction(name, perInstanceAttributes, this._dirtyAttributes); + properties[name].set = createSetFunction(batchTable, index, attributeIndex); } } } From 28aa9bbb5c92b7f610dd89b7cf989a11665d2be2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 21 Sep 2016 17:19:04 -0400 Subject: [PATCH 04/23] Fix primitives with show per instance attribute. --- Source/Scene/Primitive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index aa56b78e2ea2..583f249c60f2 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -823,7 +823,7 @@ define([ 'void main() \n' + '{ \n' + ' czm_non_show_main(); \n' + - ' gl_Position *= czm_batchTable_show; \n' + + ' gl_Position *= czm_batchTable_show(batchId); \n' + '}'; return renamedVS + '\n' + showMain; From 6a4e4f2d58de808d394b4c3e6d6c732f444cea8c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 21 Sep 2016 17:27:54 -0400 Subject: [PATCH 05/23] Remove pick color attribute that is now in the batch table. Remove packing/unpacking pick ids for transfer to/from web workers. --- Source/Scene/Primitive.js | 27 ---------- Source/Scene/PrimitivePipeline.js | 83 ------------------------------- 2 files changed, 110 deletions(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 583f249c60f2..ec9c78a99c3c 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -940,27 +940,6 @@ define([ //>>includeEnd('debug'); } - function createPickIds(context, primitive, instances) { - var pickColors = []; - var length = instances.length; - - for (var i = 0; i < length; ++i) { - var pickObject = { - primitive : defaultValue(instances[i].pickPrimitive, primitive) - }; - - if (defined(instances[i].id)) { - pickObject.id = instances[i].id; - } - - var pickId = context.createPickId(pickObject); - primitive._pickIds.push(pickId); - pickColors.push(pickId.color); - } - - return pickColors; - } - function getUniformFunction(uniforms, name) { return function() { return uniforms[name]; @@ -1057,19 +1036,16 @@ define([ var transferableObjects = []; instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; - var allowPicking = primitive.allowPicking; var scene3DOnly = frameState.scene3DOnly; var projection = frameState.mapProjection; var promise = combineGeometryTaskProcessor.scheduleTask(PrimitivePipeline.packCombineGeometryParameters({ createGeometryResults : primitive._createGeometryResults, instances : instances, - pickIds : allowPicking ? createPickIds(frameState.context, primitive, instances) : undefined, ellipsoid : projection.ellipsoid, projection : projection, elementIndexUintSupported : frameState.context.elementIndexUint, scene3DOnly : scene3DOnly, - allowPicking : allowPicking, vertexCacheOptimize : primitive.vertexCacheOptimize, compressVertices : primitive.compressVertices, modelMatrix : primitive.modelMatrix, @@ -1154,19 +1130,16 @@ define([ geometries.length = geometryIndex; clonedInstances.length = geometryIndex; - var allowPicking = primitive.allowPicking; var scene3DOnly = frameState.scene3DOnly; var projection = frameState.mapProjection; var result = PrimitivePipeline.combineGeometry({ instances : clonedInstances, invalidInstances : invalidInstances, - pickIds : allowPicking ? createPickIds(frameState.context, primitive, clonedInstances) : undefined, ellipsoid : projection.ellipsoid, projection : projection, elementIndexUintSupported : frameState.context.elementIndexUint, scene3DOnly : scene3DOnly, - allowPicking : allowPicking, vertexCacheOptimize : primitive.vertexCacheOptimize, compressVertices : primitive.compressVertices, modelMatrix : primitive.modelMatrix, diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index 6e6201f83b15..6eb2249a955a 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -67,48 +67,6 @@ define([ } } - function addGeometryPickColor(geometry, pickColor) { - var attributes = geometry.attributes; - var positionAttr = attributes.position; - var numberOfComponents = 4 * (positionAttr.values.length / positionAttr.componentsPerAttribute); - - attributes.pickColor = new GeometryAttribute({ - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - componentsPerAttribute : 4, - normalize : true, - values : new Uint8Array(numberOfComponents) - }); - - var red = Color.floatToByte(pickColor.red); - var green = Color.floatToByte(pickColor.green); - var blue = Color.floatToByte(pickColor.blue); - var alpha = Color.floatToByte(pickColor.alpha); - var values = attributes.pickColor.values; - - for (var j = 0; j < numberOfComponents; j += 4) { - values[j] = red; - values[j + 1] = green; - values[j + 2] = blue; - values[j + 3] = alpha; - } - } - - function addPickColorAttribute(instances, pickIds) { - var length = instances.length; - - for (var i = 0; i < length; ++i) { - var instance = instances[i]; - var pickColor = pickIds[i]; - - if (defined(instance.geometry)) { - addGeometryPickColor(instance.geometry, pickColor); - } else { - addGeometryPickColor(instance.westHemisphereGeometry, pickColor); - addGeometryPickColor(instance.eastHemisphereGeometry, pickColor); - } - } - } - function addGeometryBatchId(geometry, batchId) { var attributes = geometry.attributes; var positionAttr = attributes.position; @@ -217,11 +175,9 @@ define([ function geometryPipeline(parameters) { var instances = parameters.instances; - var pickIds = parameters.pickIds; var projection = parameters.projection; var uintIndexSupport = parameters.elementIndexUintSupported; var scene3DOnly = parameters.scene3DOnly; - var allowPicking = parameters.allowPicking; var vertexCacheOptimize = parameters.vertexCacheOptimize; var compressVertices = parameters.compressVertices; var modelMatrix = parameters.modelMatrix; @@ -251,11 +207,6 @@ define([ addBatchIds(instances); - // Add pickColor attribute for picking individual instances - if (allowPicking) { - addPickColorAttribute(instances, pickIds); - } - // add attributes to the geometry for each per-instance attribute var perInstanceAttributeNames = getCommonPerInstanceAttributeNames(instances); addPerInstanceAttributes(instances, perInstanceAttributeNames); @@ -820,25 +771,6 @@ define([ return result; }; - function packPickIds(pickIds, transferableObjects) { - var length = pickIds.length; - var packedPickIds = new Uint32Array(pickIds.length); - for (var i = 0; i < length; ++i) { - packedPickIds[i] = pickIds[i].toRgba(); - } - transferableObjects.push(packedPickIds.buffer); - return packedPickIds; - } - - function unpackPickIds(packedPickIds) { - var length = packedPickIds.length; - var pickIds = new Array(length); - for (var i = 0; i < length; i++) { - pickIds[i] = Color.fromRgba(packedPickIds[i]); - } - return pickIds; - } - // This function was created by simplifying packInstancesForCombine into a count-only operation. function countInstancesForCombine(instances) { var length = instances.length; @@ -1111,20 +1043,13 @@ define([ transferableObjects.push(createGeometryResults[i].packedData.buffer); } - var packedPickIds; - if (parameters.allowPicking) { - packedPickIds = packPickIds(parameters.pickIds, transferableObjects); - } - return { createGeometryResults : parameters.createGeometryResults, packedInstances : packInstancesForCombine(parameters.instances, transferableObjects), - packedPickIds : packedPickIds, ellipsoid : parameters.ellipsoid, isGeographic : parameters.projection instanceof GeographicProjection, elementIndexUintSupported : parameters.elementIndexUintSupported, scene3DOnly : parameters.scene3DOnly, - allowPicking : parameters.allowPicking, vertexCacheOptimize : parameters.vertexCacheOptimize, compressVertices : parameters.compressVertices, modelMatrix : parameters.modelMatrix, @@ -1137,8 +1062,6 @@ define([ */ PrimitivePipeline.unpackCombineGeometryParameters = function(packedParameters) { var instances = unpackInstancesForCombine(packedParameters.packedInstances); - var allowPicking = packedParameters.allowPicking; - var pickIds = allowPicking ? unpackPickIds(packedParameters.packedPickIds) : undefined; var createGeometryResults = packedParameters.createGeometryResults; var length = createGeometryResults.length; var instanceIndex = 0; @@ -1147,7 +1070,6 @@ define([ var invalidInstances = []; var validInstancesIndices = []; var invalidInstancesIndices = []; - var validPickIds = []; for (var resultIndex = 0; resultIndex < length; resultIndex++) { var geometries = PrimitivePipeline.unpackCreateGeometryResults(createGeometryResults[resultIndex]); @@ -1160,9 +1082,6 @@ define([ instance.geometry = geometry; validInstances.push(instance); validInstancesIndices.push(instanceIndex); - if (allowPicking) { - validPickIds.push(pickIds[instanceIndex]); - } } else { invalidInstances.push(instance); invalidInstancesIndices.push(instanceIndex); @@ -1180,12 +1099,10 @@ define([ invalidInstances : invalidInstances, validInstancesIndices : validInstancesIndices, invalidInstancesIndices : invalidInstancesIndices, - pickIds : validPickIds, ellipsoid : ellipsoid, projection : projection, elementIndexUintSupported : packedParameters.elementIndexUintSupported, scene3DOnly : packedParameters.scene3DOnly, - allowPicking : packedParameters.allowPicking, vertexCacheOptimize : packedParameters.vertexCacheOptimize, compressVertices : packedParameters.compressVertices, modelMatrix : Matrix4.clone(packedParameters.modelMatrix), From 684475923fe51b5e4d1b6e5cd242da451664b633 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 22 Sep 2016 11:11:11 +1000 Subject: [PATCH 06/23] Update CHANGES.md. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index e2124ba1d132..e036ffa28de2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Change Log * Added `DebugCameraPrimitive` to visualize the view frustum of a camera. * Fixed touch events for the timeline [#4305](https://github.com/AnalyticalGraphicsInc/cesium/pull/4305) * Removed the default gamma correction for Bing Maps aerial imagery, because we no longer think it is an improvement in current versions of the tiles. To restore the previous look, set the `defaultGamma` property of your `BingMapsImageryProvider` instance to 1.3. +* Fixed a bug in `AttributeCompression.compressTextureCoordinates` and `decompressTextureCoordinates` that could cause a small inaccuracy in the encoded texture coordinates. ### 1.25 - 2016-09-01 From 66b347e896f0f2e2f1d863ca918a5a67faae09a7 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 22 Sep 2016 11:42:10 +1000 Subject: [PATCH 07/23] Add specs. --- Specs/Core/AttributeCompressionSpec.js | 33 ++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/Specs/Core/AttributeCompressionSpec.js b/Specs/Core/AttributeCompressionSpec.js index 1a37151f3380..574bda8995bf 100644 --- a/Specs/Core/AttributeCompressionSpec.js +++ b/Specs/Core/AttributeCompressionSpec.js @@ -490,24 +490,49 @@ defineSuite([ it('compresses texture coordinates', function() { var coords = new Cartesian2(0.5, 0.5); - expect(AttributeCompression.decompressTextureCoordinates(AttributeCompression.compressTextureCoordinates(coords), new Cartesian2())).toEqual(coords); + expect(AttributeCompression.decompressTextureCoordinates(AttributeCompression.compressTextureCoordinates(coords), new Cartesian2())).toEqualEpsilon(coords, 1.0 / 4096.0); }); - + it('compress texture coordinates throws without texture coordinates', function() { expect(function() { AttributeCompression.compressTextureCoordinates(undefined); }).toThrowDeveloperError(); }); - + it('decompress texture coordinates throws without encoded texture coordinates', function() { expect(function() { AttributeCompression.decompressTextureCoordinates(undefined, new Cartesian2()); }).toThrowDeveloperError(); }); - + it('decompress texture coordinates throws without result', function() { expect(function() { AttributeCompression.decompressTextureCoordinates(0.0, undefined); }).toThrowDeveloperError(); }); + + it('compresses/decompresses 1.0', function() { + var coords = new Cartesian2(1.0, 1.0); + expect(AttributeCompression.decompressTextureCoordinates(AttributeCompression.compressTextureCoordinates(coords), new Cartesian2())).toEqual(coords); + }); + + it('compresses/decompresses 0.0', function() { + var coords = new Cartesian2(1.0, 1.0); + expect(AttributeCompression.decompressTextureCoordinates(AttributeCompression.compressTextureCoordinates(coords), new Cartesian2())).toEqual(coords); + }); + + it('compresses/decompresses 0.5 / 1.0', function() { + var coords = new Cartesian2(0.5, 1.0); + expect(AttributeCompression.decompressTextureCoordinates(AttributeCompression.compressTextureCoordinates(coords), new Cartesian2())).toEqualEpsilon(coords, 1.0 / 4095.0); + }); + + it('compresses/decompresses 1.0 / 0.5', function() { + var coords = new Cartesian2(1.0, 0.5); + expect(AttributeCompression.decompressTextureCoordinates(AttributeCompression.compressTextureCoordinates(coords), new Cartesian2())).toEqualEpsilon(coords, 1.0 / 4095.0); + }); + + it('compresses/decompresses values very close but not equal to 1.0', function() { + var coords = new Cartesian2(0.99999999999999, 0.99999999999999); + expect(AttributeCompression.decompressTextureCoordinates(AttributeCompression.compressTextureCoordinates(coords), new Cartesian2())).toEqualEpsilon(coords, 1.0 / 4095.0); + }); }); From 02524f0dfd21c3c3de379014fa9382a9af4607c1 Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Thu, 22 Sep 2016 12:05:08 +1000 Subject: [PATCH 08/23] Fix test failures. --- Specs/Core/TerrainEncodingSpec.js | 8 ++++---- Specs/Renderer/BuiltinFunctionsSpec.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Specs/Core/TerrainEncodingSpec.js b/Specs/Core/TerrainEncodingSpec.js index e2f4b3195bf0..9928217ae848 100644 --- a/Specs/Core/TerrainEncodingSpec.js +++ b/Specs/Core/TerrainEncodingSpec.js @@ -183,7 +183,7 @@ defineSuite([ expect(encoding.getStride()).toEqual(3); expect(buffer.length).toEqual(encoding.getStride()); - expect(encoding.decodeTextureCoordinates(buffer, 0)).toEqualEpsilon(texCoords, CesiumMath.EPSILON14); + expect(encoding.decodeTextureCoordinates(buffer, 0)).toEqualEpsilon(texCoords, 1.0 / 4095.0); }); it('encodes textureCoordinates with quantization and normals', function() { @@ -198,7 +198,7 @@ defineSuite([ expect(encoding.getStride()).toEqual(4); expect(buffer.length).toEqual(encoding.getStride()); - expect(encoding.decodeTextureCoordinates(buffer, 0)).toEqualEpsilon(texCoords, CesiumMath.EPSILON14); + expect(encoding.decodeTextureCoordinates(buffer, 0)).toEqualEpsilon(texCoords, 1.0 / 4095.0); }); it('encodes height with quantization and without normals', function() { @@ -214,7 +214,7 @@ defineSuite([ expect(encoding.getStride()).toEqual(3); expect(buffer.length).toEqual(encoding.getStride()); - expect(encoding.decodeHeight(buffer, 0)).toEqualEpsilon(height, CesiumMath.EPSILON14); + expect(encoding.decodeHeight(buffer, 0)).toEqualEpsilon(height, 200.0 / 4095.0); }); it('encodes height with quantization and normals', function() { @@ -230,7 +230,7 @@ defineSuite([ expect(encoding.getStride()).toEqual(4); expect(buffer.length).toEqual(encoding.getStride()); - expect(encoding.decodeHeight(buffer, 0)).toEqualEpsilon(height, CesiumMath.EPSILON14); + expect(encoding.decodeHeight(buffer, 0)).toEqualEpsilon(height, 200.0 / 4095.0); }); it('gets oct-encoded normal', function() { diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index 9ff5c55e04d3..24387af25124 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -219,7 +219,7 @@ defineSuite([ it('has czm_decompressTextureCoordinates', function() { var fs = 'void main() { ' + - ' gl_FragColor = vec4(czm_decompressTextureCoordinates(8390656.0) == vec2(0.5, 0.5)); ' + + ' gl_FragColor = vec4(czm_decompressTextureCoordinates(8386559.0) == vec2(0.4998779, 0.4998779)); ' + '}'; context.verifyDrawForSpecs(fs); }); From 13a32ca4a0c6fdc025c63cf4f1ed79bb8bef68a0 Mon Sep 17 00:00:00 2001 From: greenkeeperio-bot Date: Thu, 22 Sep 2016 07:30:28 -0400 Subject: [PATCH 09/23] chore(package): update electron-prebuilt to version 1.4.1 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 441ccced29f6..2b00af309247 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "bluebird": "3.4.6", "compressible": "2.0.8", "compression": "1.6.2", - "electron-prebuilt": "1.4.0", + "electron-prebuilt": "1.4.1", "event-stream": "3.3.4", "express": "4.14.0", "globby": "6.0.0", From f2eb439c660c7eb2db78a2918186f96f064a1327 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 22 Sep 2016 10:18:00 -0400 Subject: [PATCH 10/23] Remove per instance vertex attribute packing/unpacking. --- Source/Scene/Primitive.js | 69 +---- Source/Scene/PrimitivePipeline.js | 440 +----------------------------- 2 files changed, 5 insertions(+), 504 deletions(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index ec9c78a99c3c..77438ec61efb 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -311,21 +311,17 @@ define([ this._state = PrimitiveState.READY; this._geometries = []; - this._vaAttributes = undefined; this._error = undefined; this._numberOfInstances = 0; - this._validModelMatrix = false; this._boundingSpheres = []; this._boundingSphereWC = []; this._boundingSphereCV = []; this._boundingSphere2D = []; this._boundingSphereMorph = []; - this._perInstanceAttributeLocations = undefined; this._perInstanceAttributeCache = []; this._instanceIds = []; this._lastPerInstanceAttributeIndex = 0; - this._dirtyAttributes = []; this._va = []; this._attributeLocations = undefined; @@ -703,34 +699,10 @@ define([ }); } - function cloneGeometryInstanceAttribute(attribute) { - var clonedValue; - if (isArray(attribute.value)) { - clonedValue = attribute.value.slice(0); - } else { - clonedValue = new attribute.value.constructor(attribute.value); - } - return new GeometryInstanceAttribute({ - componentDatatype : attribute.componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize, - value : clonedValue - }); - } - function cloneInstance(instance, geometry) { - var attributes = instance.attributes; - var newAttributes = {}; - for (var property in attributes) { - if (attributes.hasOwnProperty(property)) { - newAttributes[property] = cloneGeometryInstanceAttribute(attributes[property]); - } - } - return new GeometryInstance({ geometry : geometry, modelMatrix : Matrix4.clone(instance.modelMatrix), - attributes : newAttributes, pickPrimitive : instance.pickPrimitive, id : instance.id }); @@ -1059,28 +1031,11 @@ define([ var result = PrimitivePipeline.unpackCombineGeometryResults(packedResult); primitive._geometries = result.geometries; primitive._attributeLocations = result.attributeLocations; - primitive._vaAttributes = result.vaAttributes; - primitive._perInstanceAttributeLocations = result.perInstanceAttributeLocations; primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); - primitive._validModelMatrix = !Matrix4.equals(primitive.modelMatrix, Matrix4.IDENTITY); primitive._pickOffsets = result.pickOffsets; - var validInstancesIndices = packedResult.validInstancesIndices; - var invalidInstancesIndices = packedResult.invalidInstancesIndices; - var instanceIds = primitive._instanceIds; - var reorderedInstanceIds = new Array(instanceIds.length); - - var validLength = validInstancesIndices.length; - for (var i = 0; i < validLength; ++i) { - reorderedInstanceIds[i] = instanceIds[validInstancesIndices[i]]; - } - - var invalidLength = invalidInstancesIndices.length; - for (var j = 0; j < invalidLength; ++j) { - reorderedInstanceIds[validLength + j] = instanceIds[invalidInstancesIndices[j]]; - } - - primitive._instanceIds = reorderedInstanceIds; + // TODO + //var invalidInstancesIndices = packedResult.invalidInstancesIndices; if (defined(primitive._geometries)) { primitive._state = PrimitiveState.COMBINED; @@ -1096,11 +1051,7 @@ define([ function loadSynchronous(primitive, frameState) { var instances = (isArray(primitive.geometryInstances)) ? primitive.geometryInstances : [primitive.geometryInstances]; var length = primitive._numberOfInstances = instances.length; - - var geometries = new Array(length); var clonedInstances = new Array(length); - - var invalidInstances = []; var instanceIds = primitive._instanceIds; var instance; @@ -1119,15 +1070,12 @@ define([ } if (defined(createdGeometry)) { - geometries[geometryIndex] = createdGeometry; clonedInstances[geometryIndex++] = cloneInstance(instance, createdGeometry); - instanceIds.push(instance.id); - } else { - invalidInstances.push(instance); } + + instanceIds.push(instance.id); } - geometries.length = geometryIndex; clonedInstances.length = geometryIndex; var scene3DOnly = frameState.scene3DOnly; @@ -1135,7 +1083,6 @@ define([ var result = PrimitivePipeline.combineGeometry({ instances : clonedInstances, - invalidInstances : invalidInstances, ellipsoid : projection.ellipsoid, projection : projection, elementIndexUintSupported : frameState.context.elementIndexUint, @@ -1148,17 +1095,9 @@ define([ primitive._geometries = result.geometries; primitive._attributeLocations = result.attributeLocations; - primitive._vaAttributes = result.vaAttributes; - primitive._perInstanceAttributeLocations = result.vaAttributeLocations; primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); - primitive._validModelMatrix = !Matrix4.equals(primitive.modelMatrix, Matrix4.IDENTITY); primitive._pickOffsets = result.pickOffsets; - for (i = 0; i < invalidInstances.length; ++i) { - instance = invalidInstances[i]; - instanceIds.push(instance.id); - } - if (defined(primitive._geometries)) { primitive._state = PrimitiveState.COMBINED; } else { diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index 6eb2249a955a..ed4e31a014a2 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -98,81 +98,6 @@ define([ } } - function getCommonPerInstanceAttributeNames(instances) { - var length = instances.length; - - var attributesInAllInstances = []; - var attributes0 = instances[0].attributes; - var name; - - for (name in attributes0) { - if (attributes0.hasOwnProperty(name)) { - var attribute = attributes0[name]; - var inAllInstances = true; - - // Does this same attribute exist in all instances? - for (var i = 1; i < length; ++i) { - var otherAttribute = instances[i].attributes[name]; - - if (!defined(otherAttribute) || - (attribute.componentDatatype !== otherAttribute.componentDatatype) || - (attribute.componentsPerAttribute !== otherAttribute.componentsPerAttribute) || - (attribute.normalize !== otherAttribute.normalize)) { - - inAllInstances = false; - break; - } - } - - if (inAllInstances) { - attributesInAllInstances.push(name); - } - } - } - - return attributesInAllInstances; - } - - function addPerInstanceAttributesToGeometry(instanceAttributes, geometry, names) { - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - - var namesLength = names.length; - for (var j = 0; j < namesLength; ++j) { - var name = names[j]; - var attribute = instanceAttributes[name]; - var componentDatatype = attribute.componentDatatype; - var value = attribute.value; - var componentsPerAttribute = attribute.componentsPerAttribute; - - var buffer = ComponentDatatype.createTypedArray(componentDatatype, numberOfVertices * componentsPerAttribute); - for (var k = 0; k < numberOfVertices; ++k) { - buffer.set(value, k * componentsPerAttribute); - } - - geometry.attributes[name] = new GeometryAttribute({ - componentDatatype : componentDatatype, - componentsPerAttribute : componentsPerAttribute, - normalize : attribute.normalize, - values : buffer - }); - } - } - - function addPerInstanceAttributes(instances, names) { - var length = instances.length; - for (var i = 0; i < length; ++i) { - var instance = instances[i]; - var instanceAttributes = instance.attributes; - - if (defined(instance.geometry)) { - addPerInstanceAttributesToGeometry(instanceAttributes, instance.geometry, names); - } else { - addPerInstanceAttributesToGeometry(instanceAttributes, instance.westHemisphereGeometry, names); - addPerInstanceAttributesToGeometry(instanceAttributes, instance.eastHemisphereGeometry, names); - } - } - } - function geometryPipeline(parameters) { var instances = parameters.instances; var projection = parameters.projection; @@ -207,10 +132,6 @@ define([ addBatchIds(instances); - // add attributes to the geometry for each per-instance attribute - var perInstanceAttributeNames = getCommonPerInstanceAttributeNames(instances); - addPerInstanceAttributes(instances, perInstanceAttributeNames); - // Optimize for vertex shader caches if (vertexCacheOptimize) { for (i = 0; i < length; ++i) { @@ -283,159 +204,6 @@ define([ return geometries; } - function createPerInstanceVAAttributes(geometry, attributeLocations, names) { - var vaAttributes = []; - var attributes = geometry.attributes; - - var length = names.length; - for (var i = 0; i < length; ++i) { - var name = names[i]; - var attribute = attributes[name]; - - var componentDatatype = attribute.componentDatatype; - if (componentDatatype === ComponentDatatype.DOUBLE) { - componentDatatype = ComponentDatatype.FLOAT; - } - - var typedArray = ComponentDatatype.createTypedArray(componentDatatype, attribute.values); - vaAttributes.push({ - index : attributeLocations[name], - componentDatatype : componentDatatype, - componentsPerAttribute : attribute.componentsPerAttribute, - normalize : attribute.normalize, - values : typedArray - }); - - delete attributes[name]; - } - - return vaAttributes; - } - - function computePerInstanceAttributeLocationsForGeometry(instanceIndex, geometry, instanceAttributes, names, attributeLocations, vertexArrays, indices, offsets, vaIndices) { - var numberOfVertices = Geometry.computeNumberOfVertices(geometry); - - if (!defined(indices[instanceIndex])) { - indices[instanceIndex] = { - boundingSphere : geometry.boundingSphere, - boundingSphereCV : geometry.boundingSphereCV - }; - } - - var namesLength = names.length; - for (var j = 0; j < namesLength; ++j) { - var name = names[j]; - var index = attributeLocations[name]; - - var tempVertexCount = numberOfVertices; - while (tempVertexCount > 0) { - var vaIndex = defaultValue(vaIndices[name], 0); - var va = vertexArrays[vaIndex]; - var vaLength = va.length; - - var attribute; - for (var k = 0; k < vaLength; ++k) { - attribute = va[k]; - if (attribute.index === index) { - break; - } - } - - if (!defined(indices[instanceIndex][name])) { - indices[instanceIndex][name] = { - dirty : false, - valid : true, - value : instanceAttributes[name].value, - indices : [] - }; - } - - var size = attribute.values.length / attribute.componentsPerAttribute; - var offset = defaultValue(offsets[name], 0); - - var count; - if (offset + tempVertexCount < size) { - count = tempVertexCount; - indices[instanceIndex][name].indices.push({ - attribute : attribute, - offset : offset, - count : count - }); - offsets[name] = offset + tempVertexCount; - } else { - count = size - offset; - indices[instanceIndex][name].indices.push({ - attribute : attribute, - offset : offset, - count : count - }); - offsets[name] = 0; - vaIndices[name] = vaIndex + 1; - } - - tempVertexCount -= count; - } - } - } - - function computePerInstanceAttributeLocations(instances, invalidInstances, vertexArrays, attributeLocations, names) { - var indices = []; - - var length = instances.length; - var offsets = {}; - var vaIndices = {}; - - var i; - var instance; - var attributes; - - for (i = 0; i < length; ++i) { - instance = instances[i]; - attributes = instance.attributes; - if (defined(instance.geometry)) { - computePerInstanceAttributeLocationsForGeometry(i, instance.geometry, attributes, names, attributeLocations, vertexArrays, indices, offsets, vaIndices); - } - } - - for (i = 0; i < length; ++i) { - instance = instances[i]; - attributes = instance.attributes; - if (defined(instance.westHemisphereGeometry)) { - computePerInstanceAttributeLocationsForGeometry(i, instance.westHemisphereGeometry, attributes, names, attributeLocations, vertexArrays, indices, offsets, vaIndices); - } - } - - for (i = 0; i < length; ++i) { - instance = instances[i]; - attributes = instance.attributes; - if (defined(instance.eastHemisphereGeometry)) { - computePerInstanceAttributeLocationsForGeometry(i, instance.eastHemisphereGeometry, attributes, names, attributeLocations, vertexArrays, indices, offsets, vaIndices); - } - } - - length = invalidInstances.length; - for (i = 0; i < length; ++i) { - instance = invalidInstances[i]; - attributes = instance.attributes; - - var instanceAttributes = {}; - indices.push(instanceAttributes); - - var namesLength = names.length; - for (var j = 0; j < namesLength; ++j) { - var name = names[j]; - instanceAttributes[name] = { - dirty : false, - valid : false, - value : attributes[name].value, - indices : [] - }; - } - } - - return indices; - } - function createPickOffsets(instances, geometryName, geometries, pickOffsets) { var offset; var indexCount; @@ -496,30 +264,13 @@ define([ PrimitivePipeline.combineGeometry = function(parameters) { var geometries; var attributeLocations; - var perInstanceAttributes; - var perInstanceAttributeNames; - var length; - var instances = parameters.instances; - var invalidInstances = parameters.invalidInstances; if (instances.length > 0) { geometries = geometryPipeline(parameters); attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); - - perInstanceAttributeNames = getCommonPerInstanceAttributeNames(instances); - - perInstanceAttributes = []; - length = geometries.length; - for (var i = 0; i < length; ++i) { - var geometry = geometries[i]; - perInstanceAttributes.push(createPerInstanceVAAttributes(geometry, attributeLocations, perInstanceAttributeNames)); - } } - perInstanceAttributeNames = defined(perInstanceAttributeNames) ? perInstanceAttributeNames : getCommonPerInstanceAttributeNames(invalidInstances); - var indices = computePerInstanceAttributeLocations(instances, invalidInstances, perInstanceAttributes, attributeLocations, perInstanceAttributeNames); - var pickOffsets; if (parameters.createPickOffsets && defined(geometries)) { pickOffsets = createInstancePickOffsets(instances, geometries); @@ -529,9 +280,6 @@ define([ geometries : geometries, modelMatrix : parameters.modelMatrix, attributeLocations : attributeLocations, - vaAttributes : perInstanceAttributes, - vaAttributeLocations : indices, - validInstancesIndices : parameters.validInstancesIndices, invalidInstancesIndices : parameters.invalidInstancesIndices, pickOffsets : pickOffsets }; @@ -561,20 +309,6 @@ define([ } } - /** - * @private - */ - function transferPerInstanceAttributes(perInstanceAttributes, transferableObjects) { - var length = perInstanceAttributes.length; - for (var i = 0; i < length; ++i) { - var vaAttributes = perInstanceAttributes[i]; - var vaLength = vaAttributes.length; - for (var j = 0; j < vaLength; ++j) { - transferableObjects.push(vaAttributes[j].values.buffer); - } - } - } - // This function was created by simplifying packCreateGeometryResults into a count-only operation. function countCreateGeometryResults(items) { var count = 1; @@ -875,163 +609,6 @@ define([ return result; } - // This function was created by simplifying packAttributeLocations into a count-only operation. - function countAttributeLocations(attributeLocations) { - var length = attributeLocations.length; - var count = 1 + length; - for (var i = 0; i < length; i++) { - var instance = attributeLocations[i]; - - count += 2; - count += defined(instance.boundingSphere) ? BoundingSphere.packedLength : 0.0; - count += defined(instance.boundingSphereCV) ? BoundingSphere.packedLength : 0.0; - - for ( var propertyName in instance) { - if (instance.hasOwnProperty(propertyName) && defined(instance[propertyName]) && - propertyName !== 'boundingSphere' && propertyName !== 'boundingSphereCV') { - var property = instance[propertyName]; - count += 4 + (property.indices.length * 3) + property.value.length; - } - } - } - return count; - } - - function packAttributeLocations(attributeLocations, transferableObjects) { - var packedData = new Float64Array(countAttributeLocations(attributeLocations)); - var stringTable = []; - var attributeTable = []; - - var stringHash = {}; - var length = attributeLocations.length; - var count = 0; - packedData[count++] = length; - for (var i = 0; i < length; i++) { - var instance = attributeLocations[i]; - - var boundingSphere = instance.boundingSphere; - var hasBoundingSphere = defined(boundingSphere); - packedData[count++] = hasBoundingSphere ? 1.0 : 0.0; - if (hasBoundingSphere) { - BoundingSphere.pack(boundingSphere, packedData, count); - count += BoundingSphere.packedLength; - } - - boundingSphere = instance.boundingSphereCV; - hasBoundingSphere = defined(boundingSphere); - packedData[count++] = hasBoundingSphere ? 1.0 : 0.0; - if (hasBoundingSphere) { - BoundingSphere.pack(boundingSphere, packedData, count); - count += BoundingSphere.packedLength; - } - - var propertiesToWrite = []; - for ( var propertyName in instance) { - if (instance.hasOwnProperty(propertyName) && defined(instance[propertyName]) && - propertyName !== 'boundingSphere' && propertyName !== 'boundingSphereCV') { - propertiesToWrite.push(propertyName); - if (!defined(stringHash[propertyName])) { - stringHash[propertyName] = stringTable.length; - stringTable.push(propertyName); - } - } - } - - packedData[count++] = propertiesToWrite.length; - for (var q = 0; q < propertiesToWrite.length; q++) { - var name = propertiesToWrite[q]; - var property = instance[name]; - packedData[count++] = stringHash[name]; - packedData[count++] = property.valid ? 1.0 : 0.0; - - var indices = property.indices; - var indicesLength = indices.length; - packedData[count++] = indicesLength; - for (var x = 0; x < indicesLength; x++) { - var index = indices[x]; - packedData[count++] = index.count; - packedData[count++] = index.offset; - var tableIndex = attributeTable.indexOf(index.attribute); - if (tableIndex === -1) { - tableIndex = attributeTable.length; - attributeTable.push(index.attribute); - } - packedData[count++] = tableIndex; - } - - packedData[count++] = property.value.length; - packedData.set(property.value, count); - count += property.value.length; - } - } - - transferableObjects.push(packedData.buffer); - - return { - stringTable : stringTable, - packedData : packedData, - attributeTable : attributeTable - }; - } - - function unpackAttributeLocations(packedAttributeLocations, vaAttributes) { - var stringTable = packedAttributeLocations.stringTable; - var attributeTable = packedAttributeLocations.attributeTable; - var packedData = packedAttributeLocations.packedData; - - var attributeLocations = new Array(packedData[0]); - var attributeLocationsIndex = 0; - var i = 1; - var packedDataLength = packedData.length; - while (i < packedDataLength) { - var instance = {}; - - var hasBoundingSphere = packedData[i++] === 1.0; - if (hasBoundingSphere) { - instance.boundingSphere = BoundingSphere.unpack(packedData, i); - i += BoundingSphere.packedLength; - } - - hasBoundingSphere = packedData[i++] === 1.0; - if (hasBoundingSphere) { - instance.boundingSphereCV = BoundingSphere.unpack(packedData, i); - i += BoundingSphere.packedLength; - } - - var numAttributes = packedData[i++]; - for (var x = 0; x < numAttributes; x++) { - var name = stringTable[packedData[i++]]; - var valid = packedData[i++] === 1.0; - - var indicesLength = packedData[i++]; - var indices = indicesLength > 0 ? new Array(indicesLength) : undefined; - for (var indicesIndex = 0; indicesIndex < indicesLength; indicesIndex++) { - var index = {}; - index.count = packedData[i++]; - index.offset = packedData[i++]; - index.attribute = attributeTable[packedData[i++]]; - indices[indicesIndex] = index; - } - - var valueLength = packedData[i++]; - var value = valid ? ComponentDatatype.createTypedArray(indices[0].attribute.componentDatatype, valueLength) : new Array(valueLength); - for (var valueIndex = 0; valueIndex < valueLength; valueIndex++) { - value[valueIndex] = packedData[i++]; - } - - instance[name] = { - dirty : false, - valid : valid, - indices : indices, - value : value - }; - } - attributeLocations[attributeLocationsIndex++] = instance; - } - - return attributeLocations; - } - /** * @private */ @@ -1065,10 +642,6 @@ define([ var createGeometryResults = packedParameters.createGeometryResults; var length = createGeometryResults.length; var instanceIndex = 0; - - var validInstances = []; - var invalidInstances = []; - var validInstancesIndices = []; var invalidInstancesIndices = []; for (var resultIndex = 0; resultIndex < length; resultIndex++) { @@ -1080,10 +653,7 @@ define([ if (defined(geometry)) { instance.geometry = geometry; - validInstances.push(instance); - validInstancesIndices.push(instanceIndex); } else { - invalidInstances.push(instance); invalidInstancesIndices.push(instanceIndex); } @@ -1095,9 +665,7 @@ define([ var projection = packedParameters.isGeographic ? new GeographicProjection(ellipsoid) : new WebMercatorProjection(ellipsoid); return { - instances : validInstances, - invalidInstances : invalidInstances, - validInstancesIndices : validInstancesIndices, + instances : instances, invalidInstancesIndices : invalidInstancesIndices, ellipsoid : ellipsoid, projection : projection, @@ -1116,16 +684,12 @@ define([ PrimitivePipeline.packCombineGeometryResults = function(results, transferableObjects) { if (defined(results.geometries)) { transferGeometries(results.geometries, transferableObjects); - transferPerInstanceAttributes(results.vaAttributes, transferableObjects); } return { geometries : results.geometries, attributeLocations : results.attributeLocations, - vaAttributes : results.vaAttributes, - packedVaAttributeLocations : packAttributeLocations(results.vaAttributeLocations, transferableObjects), modelMatrix : results.modelMatrix, - validInstancesIndices : results.validInstancesIndices, invalidInstancesIndices : results.invalidInstancesIndices, pickOffsets : results.pickOffsets }; @@ -1138,8 +702,6 @@ define([ return { geometries : packedResult.geometries, attributeLocations : packedResult.attributeLocations, - vaAttributes : packedResult.vaAttributes, - perInstanceAttributeLocations : unpackAttributeLocations(packedResult.packedVaAttributeLocations, packedResult.vaAttributes), modelMatrix : packedResult.modelMatrix, pickOffsets : packedResult.pickOffsets }; From 127d1c806f8fe09cef605fdb18a1d9e98df6dcfc Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 22 Sep 2016 15:35:41 -0400 Subject: [PATCH 11/23] Remove more pack/unpack per instance attribute code. --- Source/Scene/Primitive.js | 3 -- Source/Scene/PrimitivePipeline.js | 76 ++----------------------------- 2 files changed, 3 insertions(+), 76 deletions(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 77438ec61efb..6e988b24262b 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -1034,9 +1034,6 @@ define([ primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); primitive._pickOffsets = result.pickOffsets; - // TODO - //var invalidInstancesIndices = packedResult.invalidInstancesIndices; - if (defined(primitive._geometries)) { primitive._state = PrimitiveState.COMBINED; } else { diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index ed4e31a014a2..66b81cdbb58b 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -505,28 +505,9 @@ define([ return result; }; - // This function was created by simplifying packInstancesForCombine into a count-only operation. - function countInstancesForCombine(instances) { - var length = instances.length; - var count = 1 + (length * 17); - for (var i = 0; i < length; i++) { - var attributes = instances[i].attributes; - for ( var property in attributes) { - if (attributes.hasOwnProperty(property) && defined(attributes[property])) { - var attribute = attributes[property]; - count += 5 + attribute.value.length; - } - } - } - return count; - } - function packInstancesForCombine(instances, transferableObjects) { - var packedData = new Float64Array(countInstancesForCombine(instances)); - var stringHash = {}; - var stringTable = []; - var length = instances.length; + var packedData = new Float64Array(1 + (length * 16)); var count = 0; packedData[count++] = length; for (var i = 0; i < length; i++) { @@ -534,43 +515,14 @@ define([ Matrix4.pack(instance.modelMatrix, packedData, count); count += Matrix4.packedLength; - - var attributes = instance.attributes; - var attributesToWrite = []; - for ( var property in attributes) { - if (attributes.hasOwnProperty(property) && defined(attributes[property])) { - attributesToWrite.push(property); - if (!defined(stringHash[property])) { - stringHash[property] = stringTable.length; - stringTable.push(property); - } - } - } - - packedData[count++] = attributesToWrite.length; - for (var q = 0; q < attributesToWrite.length; q++) { - var name = attributesToWrite[q]; - var attribute = attributes[name]; - packedData[count++] = stringHash[name]; - packedData[count++] = attribute.componentDatatype; - packedData[count++] = attribute.componentsPerAttribute; - packedData[count++] = attribute.normalize; - packedData[count++] = attribute.value.length; - packedData.set(attribute.value, count); - count += attribute.value.length; - } } transferableObjects.push(packedData.buffer); - return { - stringTable : stringTable, - packedData : packedData - }; + return packedData; } function unpackInstancesForCombine(data) { - var packedInstances = data.packedData; - var stringTable = data.stringTable; + var packedInstances = data; var result = new Array(packedInstances[0]); var count = 0; @@ -579,29 +531,7 @@ define([ var modelMatrix = Matrix4.unpack(packedInstances, i); i += Matrix4.packedLength; - var attributes = {}; - var numAttributes = packedInstances[i++]; - for (var x = 0; x < numAttributes; x++) { - var name = stringTable[packedInstances[i++]]; - var componentDatatype = packedInstances[i++]; - var componentsPerAttribute = packedInstances[i++]; - var normalize = packedInstances[i++] !== 0; - var length = packedInstances[i++]; - var value = ComponentDatatype.createTypedArray(componentDatatype, length); - for (var valueIndex = 0; valueIndex < length; valueIndex++) { - value[valueIndex] = packedInstances[i++]; - } - - attributes[name] = { - componentDatatype : componentDatatype, - componentsPerAttribute : componentsPerAttribute, - normalize : normalize, - value : value - }; - } - result[count++] = { - attributes : attributes, modelMatrix : modelMatrix }; } From 3c3febc0014dacb725ae259f9a9fe226687c0480 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 22 Sep 2016 15:57:36 -0400 Subject: [PATCH 12/23] Fix handling invalid geometry. --- Source/Core/GeometryPipeline.js | 2 +- Source/Scene/Primitive.js | 13 ++++------- Source/Scene/PrimitivePipeline.js | 39 +++++++++++++++++-------------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Source/Core/GeometryPipeline.js b/Source/Core/GeometryPipeline.js index ad9079d35a72..95b1027baef9 100644 --- a/Source/Core/GeometryPipeline.js +++ b/Source/Core/GeometryPipeline.js @@ -1033,7 +1033,7 @@ define([ var instance = instances[i]; if (defined(instance.geometry)) { instanceGeometry.push(instance); - } else { + } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { instanceSplitGeometry.push(instance); } } diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 6e988b24262b..0d75bf49d143 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -700,12 +700,12 @@ define([ } function cloneInstance(instance, geometry) { - return new GeometryInstance({ + return { geometry : geometry, modelMatrix : Matrix4.clone(instance.modelMatrix), pickPrimitive : instance.pickPrimitive, id : instance.id - }); + }; } var positionRegex = /attribute\s+vec(?:3|4)\s+(.*)3DHigh;/g; @@ -1034,7 +1034,7 @@ define([ primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); primitive._pickOffsets = result.pickOffsets; - if (defined(primitive._geometries)) { + if (defined(primitive._geometries) && primitive._geometries.length > 0) { primitive._state = PrimitiveState.COMBINED; } else { setReady(primitive, frameState, PrimitiveState.FAILED, undefined); @@ -1066,10 +1066,7 @@ define([ createdGeometry = geometry.constructor.createGeometry(geometry); } - if (defined(createdGeometry)) { - clonedInstances[geometryIndex++] = cloneInstance(instance, createdGeometry); - } - + clonedInstances[geometryIndex++] = cloneInstance(instance, createdGeometry); instanceIds.push(instance.id); } @@ -1095,7 +1092,7 @@ define([ primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); primitive._pickOffsets = result.pickOffsets; - if (defined(primitive._geometries)) { + if (defined(primitive._geometries) && primitive._geometries.length > 0) { primitive._state = PrimitiveState.COMBINED; } else { setReady(primitive, frameState, PrimitiveState.FAILED, undefined); diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index 66b81cdbb58b..eb3e92ce6ac0 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -59,6 +59,9 @@ define([ if (toWorld) { for (i = 0; i < length; ++i) { + if (!defined(instances[i].geometry)) { + continue; + } GeometryPipeline.transformToWorldCoordinates(instances[i]); } } else { @@ -91,7 +94,7 @@ define([ var instance = instances[i]; if (defined(instance.geometry)) { addGeometryBatchId(instance.geometry, i); - } else { + } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { addGeometryBatchId(instance.westHemisphereGeometry, i); addGeometryBatchId(instance.eastHemisphereGeometry, i); } @@ -109,12 +112,19 @@ define([ var i; var geometry; + var primitiveType; var length = instances.length; - var primitiveType = instances[0].geometry.primitiveType; + + for (i = 0 ; i < length; ++i) { + if (defined(instances[i].geometry)) { + primitiveType = instances[i].geometry.primitiveType; + break; + } + } //>>includeStart('debug', pragmas.debug); for (i = 1; i < length; ++i) { - if (instances[i].geometry.primitiveType !== primitiveType) { + if (defined(instances[i].geometry) && instances[i].geometry.primitiveType !== primitiveType) { throw new DeveloperError('All instance geometries must have the same primitiveType.'); } } @@ -126,6 +136,9 @@ define([ // Clip to IDL if (!scene3DOnly) { for (i = 0; i < length; ++i) { + if (!defined(instances[i].geometry)) { + continue; + } GeometryPipeline.splitLongitude(instances[i]); } } @@ -139,7 +152,7 @@ define([ if (defined(instance.geometry)) { GeometryPipeline.reorderForPostVertexCache(instance.geometry); GeometryPipeline.reorderForPreVertexCache(instance.geometry); - } else { + } else if (defined(instance.westHemisphereGeometry) && defined(instance.eastHemisphereGeometry)) { GeometryPipeline.reorderForPostVertexCache(instance.westHemisphereGeometry); GeometryPipeline.reorderForPreVertexCache(instance.westHemisphereGeometry); @@ -268,11 +281,13 @@ define([ if (instances.length > 0) { geometries = geometryPipeline(parameters); - attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); + if (geometries.length > 0) { + attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); + } } var pickOffsets; - if (parameters.createPickOffsets && defined(geometries)) { + if (parameters.createPickOffsets && geometries.length > 0) { pickOffsets = createInstancePickOffsets(instances, geometries); } @@ -280,7 +295,6 @@ define([ geometries : geometries, modelMatrix : parameters.modelMatrix, attributeLocations : attributeLocations, - invalidInstancesIndices : parameters.invalidInstancesIndices, pickOffsets : pickOffsets }; }; @@ -572,7 +586,6 @@ define([ var createGeometryResults = packedParameters.createGeometryResults; var length = createGeometryResults.length; var instanceIndex = 0; - var invalidInstancesIndices = []; for (var resultIndex = 0; resultIndex < length; resultIndex++) { var geometries = PrimitivePipeline.unpackCreateGeometryResults(createGeometryResults[resultIndex]); @@ -580,13 +593,7 @@ define([ for (var geometryIndex = 0; geometryIndex < geometriesLength; geometryIndex++) { var geometry = geometries[geometryIndex]; var instance = instances[instanceIndex]; - - if (defined(geometry)) { - instance.geometry = geometry; - } else { - invalidInstancesIndices.push(instanceIndex); - } - + instance.geometry = geometry; ++instanceIndex; } } @@ -596,7 +603,6 @@ define([ return { instances : instances, - invalidInstancesIndices : invalidInstancesIndices, ellipsoid : ellipsoid, projection : projection, elementIndexUintSupported : packedParameters.elementIndexUintSupported, @@ -620,7 +626,6 @@ define([ geometries : results.geometries, attributeLocations : results.attributeLocations, modelMatrix : results.modelMatrix, - invalidInstancesIndices : results.invalidInstancesIndices, pickOffsets : results.pickOffsets }; }; From 9d7f49f66f14205ee2b62e63be0a8a07723731d8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 22 Sep 2016 16:54:38 -0400 Subject: [PATCH 13/23] Re-add per instance bounding spheres. --- Source/Core/Geometry.js | 2 +- Source/Scene/Primitive.js | 42 ++++++++-------- Source/Scene/PrimitivePipeline.js | 79 +++++++++++++++++++++++++++++-- 3 files changed, 99 insertions(+), 24 deletions(-) diff --git a/Source/Core/Geometry.js b/Source/Core/Geometry.js index 55dd903af05c..c10078c250ef 100644 --- a/Source/Core/Geometry.js +++ b/Source/Core/Geometry.js @@ -158,7 +158,7 @@ define([ /** * @private */ - this.boundingSphereCV = undefined; + this.boundingSphereCV = options.boundingSphereCV; } /** diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 0d75bf49d143..3ecbd1e31ba1 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -355,6 +355,8 @@ define([ this._batchTable = undefined; this._batchTableAttributeIndices = undefined; + this._instanceBoundingSpheres = undefined; + this._instanceBoundingSpheresCV = undefined; } defineProperties(Primitive.prototype, { @@ -1033,6 +1035,8 @@ define([ primitive._attributeLocations = result.attributeLocations; primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); primitive._pickOffsets = result.pickOffsets; + primitive._instanceBoundingSpheres = result.boundingSpheres; + primitive._instanceBoundingSpheresCV = result.boundingSpheresCV; if (defined(primitive._geometries) && primitive._geometries.length > 0) { primitive._state = PrimitiveState.COMBINED; @@ -1091,6 +1095,8 @@ define([ primitive._attributeLocations = result.attributeLocations; primitive.modelMatrix = Matrix4.clone(result.modelMatrix, primitive.modelMatrix); primitive._pickOffsets = result.pickOffsets; + primitive._instanceBoundingSpheres = result.boundingSpheres; + primitive._instanceBoundingSpheresCV = result.boundingSpheresCV; if (defined(primitive._geometries) && primitive._geometries.length > 0) { primitive._state = PrimitiveState.COMBINED; @@ -1553,7 +1559,18 @@ define([ }; } - var readOnlyInstanceAttributesScratch = ['boundingSphere', 'boundingSphereCV']; + function createBoundingSphereProperties(primitive, properties, index) { + properties.boundingSphere = { + get : function() { + return primitive._instanceBoundingSpheres[index]; + } + }; + properties.boundingSphereCV = { + get : function() { + return primitive._instanceBoundingSpheresCV[index]; + } + }; + } /** * Returns the modifiable per-instance attributes for a {@link GeometryInstance}. @@ -1603,28 +1620,16 @@ define([ var perInstanceAttributeIndices = this._batchTableAttributeIndices; attributes = {}; var properties = {}; - var hasProperties = false; for (var name in perInstanceAttributeIndices) { if (perInstanceAttributeIndices.hasOwnProperty(name)) { var attributeIndex = perInstanceAttributeIndices[name]; - - hasProperties = true; properties[name] = { get : createGetFunction(batchTable, index, attributeIndex) }; var createSetter = true; - var readOnlyAttributes = readOnlyInstanceAttributesScratch; - length = readOnlyAttributes.length; - for (var j = 0; j < length; ++j) { - if (name === readOnlyInstanceAttributesScratch[j]) { - createSetter = false; - break; - } - } - - readOnlyAttributes = this._readOnlyInstanceAttributes; + var readOnlyAttributes = this._readOnlyInstanceAttributes; if (createSetter && defined(readOnlyAttributes)) { length = readOnlyAttributes.length; for (var k = 0; k < length; ++k) { @@ -1641,9 +1646,8 @@ define([ } } - if (hasProperties) { - defineProperties(attributes, properties); - } + createBoundingSphereProperties(this, properties, index); + defineProperties(attributes, properties); this._lastPerInstanceAttributeIndex = index; this._perInstanceAttributeCache[index] = attributes; @@ -1705,14 +1709,14 @@ define([ } this._pickIds = undefined; + this._batchTable = this._batchTable && this._batchTable.destroy(); + //These objects may be fairly large and reference other large objects (like Entities) //We explicitly set them to undefined here so that the memory can be freed //even if a reference to the destroyed Primitive has been kept around. this._instanceIds = undefined; this._perInstanceAttributeCache = undefined; - this._perInstanceAttributeLocations = undefined; this._attributeLocations = undefined; - this._dirtyAttributes = undefined; return destroyObject(this); }; diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index eb3e92ce6ac0..b48aa3d2e239 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -278,8 +278,9 @@ define([ var geometries; var attributeLocations; var instances = parameters.instances; + var length = instances.length; - if (instances.length > 0) { + if (length > 0) { geometries = geometryPipeline(parameters); if (geometries.length > 0) { attributeLocations = GeometryPipeline.createAttributeLocations(geometries[0]); @@ -291,11 +292,35 @@ define([ pickOffsets = createInstancePickOffsets(instances, geometries); } + var boundingSpheres = new Array(length); + var boundingSpheresCV = new Array(length); + for (var i = 0; i < length; ++i) { + var instance = instances[i]; + var geometry = instance.geometry; + if (defined(geometry)) { + boundingSpheres[i] = geometry.boundingSphere; + boundingSpheresCV[i] = geometry.boundingSphereCV; + } + + var eastHemisphereGeometry = instance.eastHemisphereGeometry; + var westHemisphereGeometry = instance.westHemisphereGeometry; + if (defined(eastHemisphereGeometry) && defined(westHemisphereGeometry)) { + if (defined(eastHemisphereGeometry.boundingSphere) && defined(westHemisphereGeometry.boundingSphere)) { + boundingSpheres[i] = BoundingSphere.union(eastHemisphereGeometry.boundingSphere, westHemisphereGeometry.boundingSphere); + } + if (defined(eastHemisphereGeometry.boundingSphereCV) && defined(westHemisphereGeometry.boundingSphereCV)) { + boundingSpheresCV[i] = BoundingSphere.union(eastHemisphereGeometry.boundingSphereCV, westHemisphereGeometry.boundingSphereCV); + } + } + } + return { geometries : geometries, modelMatrix : parameters.modelMatrix, attributeLocations : attributeLocations, - pickOffsets : pickOffsets + pickOffsets : pickOffsets, + boundingSpheres : boundingSpheres, + boundingSpheresCV : boundingSpheresCV }; }; @@ -511,6 +536,7 @@ define([ primitiveType : primitiveType, geometryType : geometryType, boundingSphere : boundingSphere, + boundingSphereCV : boundingSphereCV, indices : indices, attributes : attributes }); @@ -614,6 +640,43 @@ define([ }; }; + function packBoundingSpheres(boundingSpheres) { + var length = boundingSpheres.length; + var bufferLength = 1 + (BoundingSphere.packedLength + 1) * length; + var buffer = new Float32Array(bufferLength); + + var bufferIndex = 0; + buffer[bufferIndex++] = length; + + for (var i = 0; i < length; ++i) { + var bs = boundingSpheres[i]; + if (!defined(bs)) { + buffer[bufferIndex++] = 0.0; + } else { + buffer[bufferIndex++] = 1.0; + BoundingSphere.pack(boundingSpheres[i], buffer, bufferIndex); + } + bufferIndex += BoundingSphere.packedLength; + } + + return buffer; + } + + function unpackBoundingSpheres(buffer) { + var result = new Array(buffer[0]); + var count = 0; + + var i = 1; + while (i < buffer.length) { + if(buffer[i++] === 1.0) { + result[count++] = BoundingSphere.unpack(buffer, i); + } + i += BoundingSphere.packedLength; + } + + return result; + } + /** * @private */ @@ -622,11 +685,17 @@ define([ transferGeometries(results.geometries, transferableObjects); } + var packedBoundingSpheres = packBoundingSpheres(results.boundingSpheres); + var packedBoundingSpheresCV = packBoundingSpheres(results.boundingSpheresCV); + transferableObjects.push(packedBoundingSpheres.buffer, packedBoundingSpheresCV.buffer); + return { geometries : results.geometries, attributeLocations : results.attributeLocations, modelMatrix : results.modelMatrix, - pickOffsets : results.pickOffsets + pickOffsets : results.pickOffsets, + boundingSpheres : packedBoundingSpheres, + boundingSpheresCV : packedBoundingSpheresCV }; }; @@ -638,7 +707,9 @@ define([ geometries : packedResult.geometries, attributeLocations : packedResult.attributeLocations, modelMatrix : packedResult.modelMatrix, - pickOffsets : packedResult.pickOffsets + pickOffsets : packedResult.pickOffsets, + boundingSpheres : unpackBoundingSpheres(packedResult.boundingSpheres), + boundingSpheresCV : unpackBoundingSpheres(packedResult.boundingSpheresCV) }; }; From 28f3b986b710d3e0ba63356f3b36dc3273700fde Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 22 Sep 2016 17:06:32 -0400 Subject: [PATCH 14/23] Fix GroundPrimitives. --- Source/Scene/GroundPrimitive.js | 21 ++++++++++++++------- Source/Scene/Primitive.js | 16 ++++++++++------ Source/Shaders/ShadowVolumeVS.glsl | 1 + 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Source/Scene/GroundPrimitive.js b/Source/Scene/GroundPrimitive.js index b60a7d8213df..99cd3548d4e2 100644 --- a/Source/Scene/GroundPrimitive.js +++ b/Source/Scene/GroundPrimitive.js @@ -740,8 +740,10 @@ define([ var context = frameState.context; var vs = ShadowVolumeVS; + vs = primitive._primitive._batchTable.getVertexShaderCallback()(vs); vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); vs = Primitive._appendShowToShader(primitive._primitive, vs); + vs = Primitive._updateColorAttribute(primitive._primitive, vs); var fs = ShadowVolumeFS; var attributeLocations = primitive._primitive._attributeLocations; @@ -755,6 +757,9 @@ define([ }); if (primitive._primitive.allowPicking) { + var vsPick = ShaderSource.createPickVertexShaderSource(vs); + vsPick = Primitive._updatePickColorAttribute(vsPick); + var pickFS = new ShaderSource({ sources : [fs], pickColorQualifier : 'varying' @@ -762,7 +767,7 @@ define([ primitive._spPick = ShaderProgram.replaceCache({ context : context, shaderProgram : primitive._spPick, - vertexShaderSource : ShaderSource.createPickVertexShaderSource(vs), + vertexShaderSource : vsPick, fragmentShaderSource : pickFS, attributeLocations : attributeLocations }); @@ -782,6 +787,7 @@ define([ colorCommands.length = length; var vaIndex = 0; + var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); for (var i = 0; i < length; i += 3) { var vertexArray = primitive._va[vaIndex++]; @@ -798,7 +804,7 @@ define([ command.vertexArray = vertexArray; command.renderState = groundPrimitive._rsStencilPreloadPass; command.shaderProgram = groundPrimitive._sp; - command.uniformMap = groundPrimitive._uniformMap; + command.uniformMap = uniformMap; command.pass = Pass.GROUND; // stencil depth command @@ -813,7 +819,7 @@ define([ command.vertexArray = vertexArray; command.renderState = groundPrimitive._rsStencilDepthPass; command.shaderProgram = groundPrimitive._sp; - command.uniformMap = groundPrimitive._uniformMap; + command.uniformMap = uniformMap; command.pass = Pass.GROUND; // color command @@ -828,7 +834,7 @@ define([ command.vertexArray = vertexArray; command.renderState = groundPrimitive._rsColorPass; command.shaderProgram = groundPrimitive._sp; - command.uniformMap = groundPrimitive._uniformMap; + command.uniformMap = uniformMap; command.pass = Pass.GROUND; } } @@ -840,6 +846,7 @@ define([ pickCommands.length = length; var pickIndex = 0; + var uniformMap = primitive._batchTable.getUniformMapCallback()(groundPrimitive._uniformMap); for (var j = 0; j < length; j += 3) { var pickOffset = pickOffsets[pickIndex++]; @@ -862,7 +869,7 @@ define([ command.count = count; command.renderState = groundPrimitive._rsStencilPreloadPass; command.shaderProgram = groundPrimitive._sp; - command.uniformMap = groundPrimitive._uniformMap; + command.uniformMap = uniformMap; command.pass = Pass.GROUND; // stencil depth command @@ -879,7 +886,7 @@ define([ command.count = count; command.renderState = groundPrimitive._rsStencilDepthPass; command.shaderProgram = groundPrimitive._sp; - command.uniformMap = groundPrimitive._uniformMap; + command.uniformMap = uniformMap; command.pass = Pass.GROUND; // color command @@ -896,7 +903,7 @@ define([ command.count = count; command.renderState = groundPrimitive._rsPickPass; command.shaderProgram = groundPrimitive._spPick; - command.uniformMap = groundPrimitive._uniformMap; + command.uniformMap = uniformMap; command.pass = Pass.GROUND; } } diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 3ecbd1e31ba1..8955e6e6795a 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -803,7 +803,7 @@ define([ return renamedVS + '\n' + showMain; }; - function updateColorAttribute(primitive, vertexShaderSource) { + Primitive._updateColorAttribute = function(primitive, vertexShaderSource) { // some appearances have a color attribute for per vertex color. // only remove if color is a per instance attribute. if (!defined(primitive._batchTableAttributeIndices.color)) { @@ -818,7 +818,13 @@ define([ modifiedVS = modifiedVS.replace(/attribute\s+vec4\s+color;/g, ''); modifiedVS = modifiedVS.replace(/(\b)color(\b)/g, '$1czm_batchTable_color(batchId)$2'); return modifiedVS; - } + }; + + Primitive._updatePickColorAttribute = function(source) { + var vsPick = source.replace(/attribute\s+vec4\s+pickColor;/g, ''); + vsPick = vsPick.replace(/(\b)pickColor(\b)/g, '$1czm_batchTable_pickColor(batchId)$2'); + return vsPick; + }; function modifyForEncodedNormals(primitive, vertexShaderSource) { if (!primitive.compressVertices) { @@ -1214,16 +1220,14 @@ define([ var vs = primitive._batchTable.getVertexShaderCallback()(appearance.vertexShaderSource); vs = Primitive._modifyShaderPosition(primitive, vs, frameState.scene3DOnly); vs = Primitive._appendShowToShader(primitive, vs); - vs = updateColorAttribute(primitive, vs); + vs = Primitive._updateColorAttribute(primitive, vs); vs = modifyForEncodedNormals(primitive, vs); var fs = appearance.getFragmentShaderSource(); // Create pick program if (primitive.allowPicking) { var vsPick = ShaderSource.createPickVertexShaderSource(vs); - - vsPick = vsPick.replace(/attribute\s+vec4\s+pickColor;/g, ''); - vsPick = vsPick.replace(/(\b)pickColor(\b)/g, '$1czm_batchTable_pickColor(batchId)$2'); + vsPick = Primitive._updatePickColorAttribute(vsPick); primitive._pickSP = ShaderProgram.replaceCache({ context : context, diff --git a/Source/Shaders/ShadowVolumeVS.glsl b/Source/Shaders/ShadowVolumeVS.glsl index 81b3c90294c6..a97b96c1752b 100644 --- a/Source/Shaders/ShadowVolumeVS.glsl +++ b/Source/Shaders/ShadowVolumeVS.glsl @@ -1,6 +1,7 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec4 color; +attribute float batchId; // emulated noperspective varying float v_WindowZ; From 7579b43256062b55868f96706f2ee94890a03894 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 22 Sep 2016 17:27:08 -0400 Subject: [PATCH 15/23] Fix DebugAppearance and its tests. --- Source/Scene/DebugAppearance.js | 12 +++++++-- Specs/Scene/DebugAppearanceSpec.js | 42 ++++++++++++++++++++---------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/Source/Scene/DebugAppearance.js b/Source/Scene/DebugAppearance.js index 5de436b25ac4..70047a7fd72a 100644 --- a/Source/Scene/DebugAppearance.js +++ b/Source/Scene/DebugAppearance.js @@ -26,6 +26,7 @@ define([ * * @param {Object} options Object with the following properties: * @param {String} options.attributeName The name of the attribute to visualize. + * @param {Boolean} options.perInstanceAttribute Boolean that determines whether this attribute is a per-instance geometry attribute. * @param {String} [options.glslDatatype='vec3'] The GLSL datatype of the attribute. Supported datatypes are float, vec2, vec3, and vec4. * @param {String} [options.vertexShaderSource] Optional GLSL vertex shader source to override the default vertex shader. * @param {String} [options.fragmentShaderSource] Optional GLSL fragment shader source to override the default fragment shader. @@ -44,11 +45,15 @@ define([ function DebugAppearance(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); var attributeName = options.attributeName; + var perInstanceAttribute = options.perInstanceAttribute; //>>includeStart('debug', pragmas.debug); if (!defined(attributeName)) { throw new DeveloperError('options.attributeName is required.'); } + if (!defined(perInstanceAttribute)) { + throw new DeveloperError('options.perInstanceAttribute is required.'); + } //>>includeEnd('debug'); var glslDatatype = defaultValue(options.glslDatatype, 'vec3'); @@ -85,12 +90,15 @@ define([ var vs = 'attribute vec3 position3DHigh;\n' + 'attribute vec3 position3DLow;\n' + - 'attribute ' + glslDatatype + ' ' + attributeName + ';\n' + + 'attribute float batchId;\n' + + (perInstanceAttribute ? '' : 'attribute ' + glslDatatype + ' ' + attributeName + ';\n') + 'varying ' + glslDatatype + ' ' + varyingName + ';\n' + 'void main()\n' + '{\n' + 'vec4 p = czm_translateRelativeToEye(position3DHigh, position3DLow);\n' + - varyingName + ' = ' + attributeName + ';\n' + + (perInstanceAttribute ? + varyingName + ' = czm_batchTable_' + attributeName + '(batchId);\n' : + varyingName + ' = ' + attributeName + ';\n') + 'gl_Position = czm_modelViewProjectionRelativeToEye * p;\n' + '}'; var fs = diff --git a/Specs/Scene/DebugAppearanceSpec.js b/Specs/Scene/DebugAppearanceSpec.js index 591fa791a495..229e31d72582 100644 --- a/Specs/Scene/DebugAppearanceSpec.js +++ b/Specs/Scene/DebugAppearanceSpec.js @@ -67,7 +67,8 @@ defineSuite([ it('default construct with normal, binormal, or tangent attribute name', function() { var a = new DebugAppearance({ - attributeName : 'normal' + attributeName : 'normal', + perInstanceAttribute : false }); expect(a.vertexShaderSource).toBeDefined(); @@ -87,7 +88,8 @@ defineSuite([ it('default construct with st attribute name', function() { var a = new DebugAppearance({ - attributeName : 'st' + attributeName : 'st', + perInstanceAttribute : false }); expect(a.vertexShaderSource).toBeDefined(); @@ -108,7 +110,8 @@ defineSuite([ it('debug appearance with float attribute name', function() { var a = new DebugAppearance({ attributeName : 'rotation', - glslDatatype : 'float' + glslDatatype : 'float', + perInstanceAttribute : true }); expect(a.vertexShaderSource).toBeDefined(); @@ -129,7 +132,8 @@ defineSuite([ it('debug appearance with vec3 attribute name', function() { var a = new DebugAppearance({ attributeName : 'str', - glslDatatype : 'vec3' + glslDatatype : 'vec3', + perInstanceAttribute : false }); expect(a.vertexShaderSource).toBeDefined(); @@ -150,7 +154,8 @@ defineSuite([ it('debug appearance with vec4 attribute name', function() { var a = new DebugAppearance({ attributeName : 'quaternion', - glslDatatype : 'vec4' + glslDatatype : 'vec4', + perInstanceAttribute : true }); expect(a.vertexShaderSource).toBeDefined(); @@ -172,7 +177,8 @@ defineSuite([ expect(function() { return new DebugAppearance({ attributeName : 'invalid_datatype', - glslDatatype : 'invalid' + glslDatatype : 'invalid', + perInstanceAttribute : true }); }).toThrowDeveloperError(); }); @@ -185,7 +191,8 @@ defineSuite([ primitive = new Primitive({ geometryInstances : createInstance(vertexFormat), appearance : new DebugAppearance({ - attributeName : 'normal' + attributeName : 'normal', + perInstanceAttribute : false }), asynchronous : false, compressVertices : false @@ -206,7 +213,8 @@ defineSuite([ primitive = new Primitive({ geometryInstances : createInstance(vertexFormat), appearance : new DebugAppearance({ - attributeName : 'binormal' + attributeName : 'binormal', + perInstanceAttribute : false }), asynchronous : false, compressVertices : false @@ -227,7 +235,8 @@ defineSuite([ primitive = new Primitive({ geometryInstances : createInstance(vertexFormat), appearance : new DebugAppearance({ - attributeName : 'tangent' + attributeName : 'tangent', + perInstanceAttribute : false }), asynchronous : false, compressVertices : false @@ -247,7 +256,8 @@ defineSuite([ primitive = new Primitive({ geometryInstances : createInstance(vertexFormat), appearance : new DebugAppearance({ - attributeName : 'st' + attributeName : 'st', + perInstanceAttribute : false }), asynchronous : false, compressVertices : false @@ -272,7 +282,8 @@ defineSuite([ geometryInstances : rectangleInstance, appearance : new DebugAppearance({ attributeName : 'debug', - glslDatatype : 'float' + glslDatatype : 'float', + perInstanceAttribute : true }), asynchronous : false }); @@ -296,7 +307,8 @@ defineSuite([ geometryInstances : rectangleInstance, appearance : new DebugAppearance({ attributeName : 'debug', - glslDatatype : 'vec2' + glslDatatype : 'vec2', + perInstanceAttribute : true }), asynchronous : false }); @@ -320,7 +332,8 @@ defineSuite([ geometryInstances : rectangleInstance, appearance : new DebugAppearance({ attributeName : 'debug', - glslDatatype : 'vec3' + glslDatatype : 'vec3', + perInstanceAttribute : true }), asynchronous : false }); @@ -344,7 +357,8 @@ defineSuite([ geometryInstances : rectangleInstance, appearance : new DebugAppearance({ attributeName : 'debug', - glslDatatype : 'vec4' + glslDatatype : 'vec4', + perInstanceAttribute : true }), asynchronous : false }); From c6b7c56038d3cf588646d23f48f983e3da19e8d2 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 22 Sep 2016 20:03:09 -0400 Subject: [PATCH 16/23] Fix debug camera primitive tests --- Specs/Scene/DebugCameraPrimitiveSpec.js | 4 ++-- Specs/Scene/ShadowMapSpec.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Specs/Scene/DebugCameraPrimitiveSpec.js b/Specs/Scene/DebugCameraPrimitiveSpec.js index c8e1b9522f3b..2d3d9b00c5d9 100644 --- a/Specs/Scene/DebugCameraPrimitiveSpec.js +++ b/Specs/Scene/DebugCameraPrimitiveSpec.js @@ -86,9 +86,9 @@ defineSuite([ camera : camera })); scene.renderForSpecs(); - var primitive = p._primitive; + var primitive = p._outlinePrimitive; scene.renderForSpecs(); - expect(p._primitive).not.toBe(primitive); + expect(p._outlinePrimitive).not.toBe(primitive); }); it('does not update when updateOnChange is false', function() { diff --git a/Specs/Scene/ShadowMapSpec.js b/Specs/Scene/ShadowMapSpec.js index bf20df19a9a6..dfd14519819c 100644 --- a/Specs/Scene/ShadowMapSpec.js +++ b/Specs/Scene/ShadowMapSpec.js @@ -861,11 +861,11 @@ defineSuite([ it('enable debugShow for cascaded shadow map', function() { createCascadedShadowMap(); - // Shadow overlay command, shadow volume outline, camera outline, and four cascade outlines + // Shadow overlay command, shadow volume outline, camera outline, four cascade outlines, four cascade planes scene.shadowMap.debugShow = true; scene.shadowMap.debugFreezeFrame = true; render(); - expect(scene.frameState.commandList.length).toBe(7); + expect(scene.frameState.commandList.length).toBe(13); scene.shadowMap.debugShow = false; render(); @@ -875,10 +875,10 @@ defineSuite([ it('enable debugShow for fixed shadow map', function() { createShadowMapForDirectionalLight(); - // Overlay command and shadow volume outline + // Overlay command, shadow volume outline, shadow volume planes scene.shadowMap.debugShow = true; render(); - expect(scene.frameState.commandList.length).toBe(2); + expect(scene.frameState.commandList.length).toBe(3); scene.shadowMap.debugShow = false; render(); From 72c7f4af1c0f4fdb2e5daec941b920be513a3078 Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Thu, 22 Sep 2016 21:01:31 -0400 Subject: [PATCH 17/23] Removed deprecated castShadows and receiveShadows --- CHANGES.md | 2 + Source/DataSources/CzmlDataSource.js | 2 - Source/DataSources/ModelGraphics.js | 28 ----------- Source/DataSources/ModelVisualizer.js | 11 +---- Source/Scene/Globe.js | 42 ---------------- Source/Scene/Model.js | 54 +-------------------- Source/Scene/Primitive.js | 50 +------------------ Source/Widgets/CesiumWidget/CesiumWidget.js | 10 +--- Source/Widgets/Viewer/Viewer.js | 9 +--- 9 files changed, 7 insertions(+), 201 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8d1c21265b6b..83e1e22f0fc3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,8 @@ Change Log * Breaking changes * Vertex texture fetch is now required to be supported to render polylines. Maximum vertex texture image units must be greater than zero. + * Removed `castShadows` and `receiveShadows` properties from `Model`, `Primitive`, and `Globe`. Use `shadows` instead with the `ShadowMode` enum, e.g. `model.shadows = ShadowMode.ENABLED`. + * `Viewer.terrainShadows` now uses the `ShadowMode` enum instead of a Boolean, e.g. `viewer.terrainShadows = ShadowMode.RECEIVE_ONLY`. * Fixed billboard rotation when sized in meters. [#3979](https://github.com/AnalyticalGraphicsInc/cesium/issues/3979) * Added `DebugCameraPrimitive` to visualize the view frustum of a camera. * Fixed touch events for the timeline [#4305](https://github.com/AnalyticalGraphicsInc/cesium/pull/4305) diff --git a/Source/DataSources/CzmlDataSource.js b/Source/DataSources/CzmlDataSource.js index 706049c9fc25..c0e24b9180d8 100644 --- a/Source/DataSources/CzmlDataSource.js +++ b/Source/DataSources/CzmlDataSource.js @@ -1409,8 +1409,6 @@ define([ processPacketData(Number, model, 'maximumScale', modelData.maximumScale, interval, sourceUri, entityCollection); processPacketData(Boolean, model, 'incrementallyLoadTextures', modelData.incrementallyLoadTextures, interval, sourceUri, entityCollection); processPacketData(Boolean, model, 'runAnimations', modelData.runAnimations, interval, sourceUri, entityCollection); - processPacketData(Boolean, model, 'castShadows', modelData.castShadows, interval, sourceUri, entityCollection); - processPacketData(Boolean, model, 'receiveShadows', modelData.receiveShadows, interval, sourceUri, entityCollection); processPacketData(ShadowMode, model, 'shadows', modelData.shadows, interval, sourceUri, entityCollection); processPacketData(HeightReference, model, 'heightReference', modelData.heightReference, interval, sourceUri, entityCollection); diff --git a/Source/DataSources/ModelGraphics.js b/Source/DataSources/ModelGraphics.js index e0b5ceb10794..992cebf0c09e 100644 --- a/Source/DataSources/ModelGraphics.js +++ b/Source/DataSources/ModelGraphics.js @@ -47,8 +47,6 @@ define([ * @param {Property} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. * @param {Property} [options.runAnimations=true] A boolean Property specifying if glTF animations specified in the model should be started. * @param {Property} [options.nodeTransformations] An object, where keys are names of nodes, and values are {@link TranslationRotationScale} Properties describing the transformation to apply to that node. - * @param {Property} [options.castShadows=true] Deprecated, use options.shadows instead. A boolean Property specifying whether the model casts shadows from each light source. - * @param {Property} [options.receiveShadows=true] Deprecated, use options.shadows instead. A boolean Property specifying whether the model receives shadows from shadow casters in the scene. * @param {Property} [options.shadows=ShadowMode.ENABLED] An enum Property specifying whether the model casts or receives shadows from each light source. * @param {Property} [options.heightReference=HeightReference.NONE] A Property specifying what the height is relative to. * @@ -66,10 +64,6 @@ define([ this._maximumScaleSubscription = undefined; this._incrementallyLoadTextures = undefined; this._incrementallyLoadTexturesSubscription = undefined; - this._castShadows = undefined; - this._castShadowsSubscription = undefined; - this._receiveShadows = undefined; - this._receiveShadowsSubscription = undefined; this._shadows = undefined; this._shadowsSubscription = undefined; this._uri = undefined; @@ -144,24 +138,6 @@ define([ */ incrementallyLoadTextures : createPropertyDescriptor('incrementallyLoadTextures'), - /** - * Get or sets the boolean Property specifying whether the model - * casts shadows from each light source. - * @memberof ModelGraphics.prototype - * @type {Property} - * @deprecated - */ - castShadows : createPropertyDescriptor('castShadows'), - - /** - * Get or sets the boolean Property specifying whether the model - * receives shadows from shadow casters in the scene. - * @memberof ModelGraphics.prototype - * @type {Property} - * @deprecated - */ - receiveShadows : createPropertyDescriptor('receiveShadows'), - /** * Get or sets the enum Property specifying whether the model * casts or receives shadows from each light source. @@ -218,8 +194,6 @@ define([ result.minimumPixelSize = this.minimumPixelSize; result.maximumScale = this.maximumScale; result.incrementallyLoadTextures = this.incrementallyLoadTextures; - result.castShadows = this.castShadows; - result.receiveShadows = this.receiveShadows; result.shadows = this.shadows; result.uri = this.uri; result.runAnimations = this.runAnimations; @@ -247,8 +221,6 @@ define([ this.minimumPixelSize = defaultValue(this.minimumPixelSize, source.minimumPixelSize); this.maximumScale = defaultValue(this.maximumScale, source.maximumScale); this.incrementallyLoadTextures = defaultValue(this.incrementallyLoadTextures, source.incrementallyLoadTextures); - this.castShadows = defaultValue(this.castShadows, source.castShadows); - this.receiveShadows = defaultValue(this.receiveShadows, source.receiveShadows); this.shadows = defaultValue(this.shadows, source.shadows); this.uri = defaultValue(this.uri, source.uri); this.runAnimations = defaultValue(this.runAnimations, source.runAnimations); diff --git a/Source/DataSources/ModelVisualizer.js b/Source/DataSources/ModelVisualizer.js index fde2fedcb7f8..1f8487eb12b6 100644 --- a/Source/DataSources/ModelVisualizer.js +++ b/Source/DataSources/ModelVisualizer.js @@ -131,21 +131,12 @@ define([ modelHash[entity.id] = modelData; } - var shadows = defaultShadows; - if (defined(modelGraphics._shadows)) { - shadows = Property.getValueOrDefault(modelGraphics._shadows, time, defaultShadows); - } else if (defined(modelGraphics._castShadows) || defined(modelGraphics._receiveShadows)) { - var castShadows = Property.getValueOrDefault(modelGraphics._castShadows, time, true); - var receiveShadows = Property.getValueOrDefault(modelGraphics.receiveShadows, time, true); - shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows); - } - model.show = true; model.scale = Property.getValueOrDefault(modelGraphics._scale, time, defaultScale); model.minimumPixelSize = Property.getValueOrDefault(modelGraphics._minimumPixelSize, time, defaultMinimumPixelSize); model.maximumScale = Property.getValueOrUndefined(modelGraphics._maximumScale, time); model.modelMatrix = Matrix4.clone(modelMatrix, model.modelMatrix); - model.shadows = shadows; + model.shadows = Property.getValueOrDefault(modelGraphics._shadows, time, defaultShadows); model.heightReference = Property.getValueOrDefault(modelGraphics._heightReference, time, defaultHeightReference); if (model.ready) { diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index e16b87fba3bc..e84b483997b0 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -7,7 +7,6 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/deprecationWarning', '../Core/destroyObject', '../Core/DeveloperError', '../Core/Ellipsoid', @@ -38,7 +37,6 @@ define([ defaultValue, defined, defineProperties, - deprecationWarning, destroyObject, DeveloperError, Ellipsoid, @@ -281,46 +279,6 @@ define([ get: function() { return this._surface.tileLoadProgressEvent; } - }, - - /** - * Determines whether the globe casts shadows from each light source. - * - * @memberof Globe.prototype - * @type {Boolean} - * @deprecated - */ - castShadows : { - get : function() { - deprecationWarning('Globe.castShadows', 'Globe.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.'); - return ShadowMode.castShadows(this.shadows); - }, - set : function(value) { - deprecationWarning('Globe.castShadows', 'Globe.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.'); - var castShadows = value; - var receiveShadows = ShadowMode.receiveShadows(this.shadows); - this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows); - } - }, - - /** - * Determines whether the globe receives shadows from shadow casters in the scene. - * - * @memberof Globe.prototype - * @type {Boolean} - * @deprecated - */ - receiveShadows : { - get : function() { - deprecationWarning('Globe.receiveShadows', 'Globe.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.'); - return ShadowMode.receiveShadows(this.shadows); - }, - set : function(value) { - deprecationWarning('Globe.receiveShadows', 'Globe.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Globe.shadows instead.'); - var castShadows = ShadowMode.castShadows(this.shadows); - var receiveShadows = value; - this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows); - } } }); diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 5644c433eb83..e0f77da3afda 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -11,7 +11,6 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/deprecationWarning', '../Core/destroyObject', '../Core/DeveloperError', '../Core/FeatureDetection', @@ -71,7 +70,6 @@ define([ defaultValue, defined, defineProperties, - deprecationWarning, destroyObject, DeveloperError, FeatureDetection, @@ -315,8 +313,6 @@ define([ * @param {Boolean} [options.allowPicking=true] When true, each glTF mesh and primitive is pickable with {@link Scene#pick}. * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded. * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded. - * @param {Boolean} [options.castShadows=true] Deprecated, use options.shadows instead. Determines whether the model casts shadows from each light source. - * @param {Boolean} [options.receiveShadows=true] Deprecated, use options.shadows instead. Determines whether the model receives shadows from shadow casters in the scene. * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from each light source. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model. * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. @@ -507,10 +503,6 @@ define([ this._incrementallyLoadTextures = defaultValue(options.incrementallyLoadTextures, true); this._asynchronous = defaultValue(options.asynchronous, true); - // Deprecated options - var castShadows = defaultValue(options.castShadows, true); - var receiveShadows = defaultValue(options.receiveShadows, true); - /** * Determines whether the model casts or receives shadows from each light source. * @@ -518,7 +510,7 @@ define([ * * @default ShadowMode.ENABLED */ - this.shadows = defaultValue(options.shadows, ShadowMode.fromCastReceive(castShadows, receiveShadows)); + this.shadows = defaultValue(options.shadows, ShadowMode.ENABLED); this._shadows = this.shadows; /** @@ -867,50 +859,6 @@ define([ get : function() { return this._dirty; } - }, - - /** - * Determines whether the model casts shadows from each light source. - * - * @memberof Model.prototype - * - * @type {Boolean} - * - * @deprecated - */ - castShadows : { - get : function() { - deprecationWarning('Model.castShadows', 'Model.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.'); - return ShadowMode.castShadows(this.shadows); - }, - set : function(value) { - deprecationWarning('Model.castShadows', 'Model.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.'); - var castShadows = value; - var receiveShadows = ShadowMode.receiveShadows(this.shadows); - this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows); - } - }, - - /** - * Determines whether the model receives shadows from shadow casters in the scene. - * - * @memberof Model.prototype - * - * @type {Boolean} - * - * @deprecated - */ - receiveShadows : { - get : function() { - deprecationWarning('Model.receiveShadows', 'Model.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.'); - return ShadowMode.receiveShadows(this.shadows); - }, - set : function(value) { - deprecationWarning('Model.receiveShadows', 'Model.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Model.shadows instead.'); - var castShadows = ShadowMode.castShadows(this.shadows); - var receiveShadows = value; - this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows); - } } }); diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 995078d0fe1b..b939397d79c0 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -9,7 +9,6 @@ define([ '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', - '../Core/deprecationWarning', '../Core/destroyObject', '../Core/DeveloperError', '../Core/FeatureDetection', @@ -46,7 +45,6 @@ define([ defaultValue, defined, defineProperties, - deprecationWarning, destroyObject, DeveloperError, FeatureDetection, @@ -112,8 +110,6 @@ define([ * @param {Boolean} [options.cull=true] When true, the renderer frustum culls and horizon culls the primitive's commands based on their bounding volume. Set this to false for a small performance gain if you are manually culling the primitive. * @param {Boolean} [options.asynchronous=true] Determines if the primitive will be created asynchronously or block until ready. * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Determines if this primitive's commands' bounding spheres are shown. - * @param {Boolean} [options.castShadows=true] Deprecated, use options.shadows instead. Determines whether the primitive casts shadows from each light source. - * @param {Boolean} [options.receiveShadows=true] Deprecated, use options.shadows instead. Determines whether the primitive receives shadows from shadow casters in the scene. * @param {ShadowMode} [options.shadows=ShadowMode.DISABLED] Determines whether this primitive casts or receives shadows from each light source. * * @example @@ -288,10 +284,6 @@ define([ } //>>includeEnd('debug'); - // Deprecated options - var castShadows = defaultValue(options.castShadows, false); - var receiveShadows = defaultValue(options.receiveShadows, false); - /** * Determines whether this primitive casts or receives shadows from each light source. * @@ -299,7 +291,7 @@ define([ * * @default ShadowMode.DISABLED */ - this.shadows = defaultValue(options.shadows, ShadowMode.fromCastReceive(castShadows, receiveShadows)); + this.shadows = defaultValue(options.shadows, ShadowMode.DISABLED); this._translucent = undefined; @@ -475,46 +467,6 @@ define([ get : function() { return this._readyPromise.promise; } - }, - - /** - * Determines whether the primitive casts shadows from each light source. - * - * @memberof Primitive.prototype - * @type {Boolean} - * @deprecated - */ - castShadows : { - get : function() { - deprecationWarning('Primitive.castShadows', 'Primitive.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.'); - return ShadowMode.castShadows(this.shadows); - }, - set : function(value) { - deprecationWarning('Primitive.castShadows', 'Primitive.castShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.'); - var castShadows = value; - var receiveShadows = ShadowMode.receiveShadows(this.shadows); - this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows); - } - }, - - /** - * Determines whether the primitive receives shadows from shadow casters in the scene. - * - * @memberof Primitive.prototype - * @type {Boolean} - * @deprecated - */ - receiveShadows : { - get : function() { - deprecationWarning('Primitive.receiveShadows', 'Primitive.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.'); - return ShadowMode.receiveShadows(this.shadows); - }, - set : function(value) { - deprecationWarning('Primitive.receiveShadows', 'Primitive.receiveShadows was deprecated in Cesium 1.25. It will be removed in 1.26. Use Primitive.shadows instead.'); - var castShadows = ShadowMode.castShadows(this.shadows); - var receiveShadows = value; - this.shadows = ShadowMode.fromCastReceive(castShadows, receiveShadows); - } } }); diff --git a/Source/Widgets/CesiumWidget/CesiumWidget.js b/Source/Widgets/CesiumWidget/CesiumWidget.js index 2e6c6f6e38ff..8e2da0c334a3 100644 --- a/Source/Widgets/CesiumWidget/CesiumWidget.js +++ b/Source/Widgets/CesiumWidget/CesiumWidget.js @@ -282,15 +282,7 @@ define([ } if (globe !== false) { scene.globe = globe; - // If the passed in value is a boolean, convert to the ShadowMode enum. - var terrainShadows = options.terrainShadows; - if (terrainShadows === true) { - scene.globe.shadows = ShadowMode.ENABLED; - } else if (terrainShadows === false) { - scene.globe.shadows = ShadowMode.RECEIVE_ONLY; - } else { - scene.globe.shadows = defaultValue(terrainShadows, ShadowMode.RECEIVE_ONLY); - } + scene.globe.shadows = defaultValue(options.terrainShadows, ShadowMode.RECEIVE_ONLY); } var skyBox = options.skyBox; diff --git a/Source/Widgets/Viewer/Viewer.js b/Source/Widgets/Viewer/Viewer.js index 8bf59948fc4f..3b780eae4d53 100644 --- a/Source/Widgets/Viewer/Viewer.js +++ b/Source/Widgets/Viewer/Viewer.js @@ -974,14 +974,7 @@ Either specify options.terrainProvider instead or set options.baseLayerPicker to return this.scene.globe.shadows; }, set : function(value) { - // If the passed in value is a boolean, convert to the ShadowMode enum. - if (value === true) { - this.scene.globe.shadows = ShadowMode.ENABLED; - } else if (value === false) { - this.scene.globe.shadows = ShadowMode.RECEIVE_ONLY; - } else { - this.scene.globe.shadows = value; - } + this.scene.globe.shadows = value; } }, From aad9a76f2e35beeac049a3ade17956837aa324ff Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 26 Sep 2016 13:45:49 -0400 Subject: [PATCH 18/23] Do not update batch table if there are no per instance attributes. --- Source/Scene/Primitive.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index dba68d57d381..9ed02fb1606f 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -1422,7 +1422,9 @@ define([ if (!defined(this._batchTable)) { createBatchTable(this, frameState.context); } - this._batchTable.update(frameState); + if (this._batchTable.attributes.length > 0) { + this._batchTable.update(frameState); + } if (this._state !== PrimitiveState.COMPLETE && this._state !== PrimitiveState.COMBINED) { if (this.asynchronous) { From 14d50211dbc27c5f3dffe70a1fad0c1550a86920 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 26 Sep 2016 15:23:00 -0400 Subject: [PATCH 19/23] Updates from review. --- Source/Scene/PrimitivePipeline.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Source/Scene/PrimitivePipeline.js b/Source/Scene/PrimitivePipeline.js index b48aa3d2e239..a09a764f06e2 100644 --- a/Source/Scene/PrimitivePipeline.js +++ b/Source/Scene/PrimitivePipeline.js @@ -59,10 +59,9 @@ define([ if (toWorld) { for (i = 0; i < length; ++i) { - if (!defined(instances[i].geometry)) { - continue; + if (defined(instances[i].geometry)) { + GeometryPipeline.transformToWorldCoordinates(instances[i]); } - GeometryPipeline.transformToWorldCoordinates(instances[i]); } } else { // Leave geometry in local coordinate system; auto update model-matrix. @@ -136,10 +135,9 @@ define([ // Clip to IDL if (!scene3DOnly) { for (i = 0; i < length; ++i) { - if (!defined(instances[i].geometry)) { - continue; + if (defined(instances[i].geometry)) { + GeometryPipeline.splitLongitude(instances[i]); } - GeometryPipeline.splitLongitude(instances[i]); } } @@ -668,7 +666,7 @@ define([ var i = 1; while (i < buffer.length) { - if(buffer[i++] === 1.0) { + if (buffer[i++] === 1.0) { result[count++] = BoundingSphere.unpack(buffer, i); } i += BoundingSphere.packedLength; From 3c48667db89e06ae20f78f3a42272dd0ed6993ea Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 26 Sep 2016 16:44:50 -0400 Subject: [PATCH 20/23] Throw RuntimeErrors when trying to create a batch table but VTF isn't supported. --- Source/Scene/PolylineCollection.js | 7 +++++++ Source/Scene/Primitive.js | 11 +++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 10869066594e..e33212d656e7 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -18,8 +18,10 @@ define([ '../Core/Math', '../Core/Matrix4', '../Core/Plane', + '../Core/RuntimeError', '../Renderer/Buffer', '../Renderer/BufferUsage', + '../Renderer/ContextLimits', '../Renderer/DrawCommand', '../Renderer/RenderState', '../Renderer/ShaderProgram', @@ -53,8 +55,10 @@ define([ CesiumMath, Matrix4, Plane, + RuntimeError, Buffer, BufferUsage, + ContextLimits, DrawCommand, RenderState, ShaderProgram, @@ -409,6 +413,9 @@ define([ var properties = this._propertiesChanged; if (this._createBatchTable) { + if (ContextLimits.maximumVertexTextureImageUnits === 0) { + throw new RuntimeError('Vertex texture fetch support is required to render polylines. The maximum number of vertex texture image units must be greater than zero.'); + } createBatchTable(this, context); this._createBatchTable = false; } diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index 9ed02fb1606f..d0b933a0b2a0 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -21,10 +21,12 @@ define([ '../Core/GeometryInstanceAttribute', '../Core/isArray', '../Core/Matrix4', + '../Core/RuntimeError', '../Core/subdivideArray', '../Core/TaskProcessor', '../Renderer/Buffer', '../Renderer/BufferUsage', + '../Renderer/ContextLimits', '../Renderer/DrawCommand', '../Renderer/RenderState', '../Renderer/ShaderProgram', @@ -60,10 +62,12 @@ define([ GeometryInstanceAttribute, isArray, Matrix4, + RuntimeError, subdivideArray, TaskProcessor, Buffer, BufferUsage, + ContextLimits, DrawCommand, RenderState, ShaderProgram, @@ -1419,10 +1423,14 @@ define([ return; } + var context = frameState.context; if (!defined(this._batchTable)) { - createBatchTable(this, frameState.context); + createBatchTable(this, context); } if (this._batchTable.attributes.length > 0) { + if (ContextLimits.maximumVertexTextureImageUnits === 0) { + throw new RuntimeError('Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero.'); + } this._batchTable.update(frameState); } @@ -1464,7 +1472,6 @@ define([ createRS = true; } - var context = frameState.context; if (defined(this._material)) { this._material.update(context); } From a1d0f2e7727a733a3607f1c3be37b4413793cafa Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 26 Sep 2016 17:51:36 -0400 Subject: [PATCH 21/23] Document runtime exceptions. --- Source/Scene/PolylineCollection.js | 9 ++++++++- Source/Scene/Primitive.js | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index e33212d656e7..42dc138af54b 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -396,7 +396,14 @@ define([ } /** - * @private + * Called when {@link Viewer} or {@link CesiumWidget} render the scene to + * get the draw commands needed to render this primitive. + *

+ * Do not call this function directly. This is documented just to + * list the exceptions that may be propagated when the scene is rendered: + *

+ * + * @exception {RuntimeError} Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero. */ PolylineCollection.prototype.update = function(frameState) { removePolylines(this); diff --git a/Source/Scene/Primitive.js b/Source/Scene/Primitive.js index d0b933a0b2a0..cbdf724d6e3a 100644 --- a/Source/Scene/Primitive.js +++ b/Source/Scene/Primitive.js @@ -1401,6 +1401,7 @@ define([ * @exception {DeveloperError} All instance geometries must have the same primitiveType. * @exception {DeveloperError} Appearance and material have a uniform with the same name. * @exception {DeveloperError} Primitive.modelMatrix is only supported in 3D mode. + * @exception {RuntimeError} Vertex texture fetch support is required to render primitives with per-instance attributes. The maximum number of vertex texture image units must be greater than zero. */ Primitive.prototype.update = function(frameState) { if (((!defined(this.geometryInstances)) && (this._va.length === 0)) || From 4745bce18f97db7ffc56326d9de1534b42426c73 Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Tue, 27 Sep 2016 12:46:22 -0400 Subject: [PATCH 22/23] Reorder CHANGES.md for 1.26 --- CHANGES.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 83e1e22f0fc3..83cba9819fc3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,13 +5,13 @@ Change Log * Breaking changes * Vertex texture fetch is now required to be supported to render polylines. Maximum vertex texture image units must be greater than zero. - * Removed `castShadows` and `receiveShadows` properties from `Model`, `Primitive`, and `Globe`. Use `shadows` instead with the `ShadowMode` enum, e.g. `model.shadows = ShadowMode.ENABLED`. + * Removed `castShadows` and `receiveShadows` properties from `Model`, `Primitive`, and `Globe`. Instead, use `shadows` with the `ShadowMode` enum, e.g. `model.shadows = ShadowMode.ENABLED`. * `Viewer.terrainShadows` now uses the `ShadowMode` enum instead of a Boolean, e.g. `viewer.terrainShadows = ShadowMode.RECEIVE_ONLY`. +* Removed the default gamma correction for Bing Maps aerial imagery, because it is no longer an improvement to current versions of the tiles. To restore the previous look, set the `defaultGamma` property of your `BingMapsImageryProvider` instance to 1.3. * Fixed billboard rotation when sized in meters. [#3979](https://github.com/AnalyticalGraphicsInc/cesium/issues/3979) -* Added `DebugCameraPrimitive` to visualize the view frustum of a camera. -* Fixed touch events for the timeline [#4305](https://github.com/AnalyticalGraphicsInc/cesium/pull/4305) -* Removed the default gamma correction for Bing Maps aerial imagery, because we no longer think it is an improvement in current versions of the tiles. To restore the previous look, set the `defaultGamma` property of your `BingMapsImageryProvider` instance to 1.3. +* Fixed timeline touch events. [#4305](https://github.com/AnalyticalGraphicsInc/cesium/pull/4305) * Fixed a bug that could lead to incorrect terrain heights when using `HeightmapTerrainData` with an encoding in which actual heights were equal to the minimum representable height. +* Added `DebugCameraPrimitive` to visualize the view frustum of a camera. ### 1.25 - 2016-09-01 From 2813522f93d824fcd2acb2d079236d1cccfcbfa8 Mon Sep 17 00:00:00 2001 From: greenkeeperio-bot Date: Tue, 27 Sep 2016 19:29:34 -0400 Subject: [PATCH 23/23] chore(package): update aws-sdk to version 2.6.5 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 441ccced29f6..0a52f55c4dc5 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "almond": "0.3.3", - "aws-sdk": "2.6.3", + "aws-sdk": "2.6.5", "bluebird": "3.4.6", "compressible": "2.0.8", "compression": "1.6.2",