From bbafe3e4c7d5d5ff2e3efc6926cfa0637368720a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 15 Feb 2013 15:02:22 -0500 Subject: [PATCH 001/114] Render polylines in a single pass (no outline). --- Source/Scene/PolylineCollection.js | 191 ++++++----------------------- 1 file changed, 35 insertions(+), 156 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index c668a36fa810..e0b9934c1965 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -20,9 +20,7 @@ define([ './SceneMode', './Polyline', '../Shaders/PolylineVS', - '../Shaders/PolylineFS', - '../Renderer/StencilFunction', - '../Renderer/StencilOperation' + '../Shaders/PolylineFS' ], function( DeveloperError, combine, @@ -44,9 +42,7 @@ define([ SceneMode, Polyline, PolylineVS, - PolylineFS, - StencilFunction, - StencilOperation) { + PolylineFS) { "use strict"; var SHOW_INDEX = Polyline.SHOW_INDEX; @@ -139,6 +135,8 @@ define([ this.modelMatrix = Matrix4.IDENTITY.clone(); this._modelMatrix = Matrix4.IDENTITY.clone(); this._sp = undefined; + this._rs = undefined; + this._rsPick = undefined; this._boundingVolume = undefined; this._boundingVolume2D = undefined; @@ -476,19 +474,30 @@ define([ var command; polylineBuckets = this._polylineBuckets; var sp = this._sp; + var useDepthTest = (this.morphTime !== 0.0); this._commandLists.removeAll(); if (typeof polylineBuckets !== 'undefined') { if (pass.color) { + if (typeof this._rs === 'undefined') { + this._rs = context.createRenderState({ + blending : BlendingState.ALPHA_BLEND + }); + } + + this._rs.depthMask = !useDepthTest; + this._rs.depthTest.enabled = useDepthTest; + this._rs.lineWidth = clampWidth(context, this.width); + length = this._colorVertexArrays.length; commands = this._commandLists.colorList; for ( var m = 0; m < length; ++m) { var vaColor = this._colorVertexArrays[m]; - var vaOutlineColor = this._outlineColorVertexArrays[m]; + //var vaOutlineColor = this._outlineColorVertexArrays[m]; buckets = this._colorVertexArrays[m].buckets; bucketLength = buckets.length; var p = commands.length; - commands.length += bucketLength * 3; - for ( var n = 0; n < bucketLength; ++n, p += 3) { + commands.length += bucketLength; + for ( var n = 0; n < bucketLength; ++n, ++p) { bucketLocator = buckets[n]; command = commands[p]; @@ -496,21 +505,6 @@ define([ command = commands[p] = new DrawCommand(); } - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.LINES; - command.count = bucketLocator.count; - command.offset = bucketLocator.offset; - command.shaderProgram = sp; - command.uniformMap = this._uniforms; - command.vertexArray = vaOutlineColor.va; - command.renderState = bucketLocator.rsOne; - - command = commands[p + 1]; - if (typeof command === 'undefined') { - command = commands[p + 1] = new DrawCommand(); - } - command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; command.primitiveType = PrimitiveType.LINES; @@ -519,26 +513,19 @@ define([ command.shaderProgram = sp; command.uniformMap = this._uniforms; command.vertexArray = vaColor.va; - command.renderState = bucketLocator.rsTwo; - - command = commands[p + 2]; - if (typeof command === 'undefined') { - command = commands[p + 2] = new DrawCommand(); - } - - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.LINES; - command.count = bucketLocator.count; - command.offset = bucketLocator.offset; - command.shaderProgram = sp; - command.uniformMap = this._uniforms; - command.vertexArray = vaOutlineColor.va; - command.renderState = bucketLocator.rsThree; + command.renderState = this._rs; } } } if (pass.pick) { + if (typeof this._rsPick === 'undefined') { + this._rsPick = context.createRenderState(); + } + + this._rsPick.depthMask = !useDepthTest; + this._rsPick.depthTest.enabled = useDepthTest; + this._rsPick.lineWidth = clampWidth(context, this.width); + length = this._pickColorVertexArrays.length; commands = this._commandLists.pickList; for ( var a = 0; a < length; ++a) { @@ -562,7 +549,7 @@ define([ command.shaderProgram = sp; command.uniformMap = this._uniforms; command.vertexArray = vaPickColor.va; - command.renderState = bucketLocator.rsPick; + command.renderState = this._rsPick; } } } @@ -615,6 +602,13 @@ define([ return destroyObject(this); }; + function clampWidth(context, value) { + var min = context.getMinimumAliasedLineWidth(); + var max = context.getMaximumAliasedLineWidth(); + + return Math.min(Math.max(value, min), max); + } + PolylineCollection.prototype._computeNewBuffersUsage = function() { var buffersUsage = this._buffersUsage; var usageChanged = false; @@ -660,7 +654,6 @@ define([ var vertexBufferOffset = [0]; totalIndices.push(indices); var offset = 0; - var useDepthTest = (this.morphTime !== 0.0); var vertexArrayBuckets = [[]]; var totalLength = 0; var polylineBuckets = this._polylineBuckets; @@ -669,7 +662,6 @@ define([ for (x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; - bucket.updateRenderState(context, useDepthTest); totalLength += bucket.lengthOfPositions; } } @@ -987,10 +979,6 @@ define([ function VertexArrayBucketLocator(count, offset, bucket) { this.count = count; this.offset = offset; - this.rsOne = bucket.rsOne; - this.rsTwo = bucket.rsTwo; - this.rsThree = bucket.rsThree; - this.rsPick = bucket.rsPick; } /** @@ -1001,10 +989,6 @@ define([ this.outlineWidth = outlineWidth; this.polylines = []; this.lengthOfPositions = 0; - this.rsOne = undefined; - this.rsTwo = undefined; - this.rsThree = undefined; - this.rsPick = undefined; this.mode = mode; this.projection = projection; this.ellipsoid = projection.getEllipsoid(); @@ -1022,101 +1006,6 @@ define([ p._bucket = this; }; - /** - * @private - */ - PolylineBucket.prototype.updateRenderState = function(context, useDepthTest) { - var width = this._clampWidth(context, this.width); - var outlineWidth = this._clampWidth(context, this.outlineWidth); - var rsOne = this.rsOne || context.createRenderState({ - colorMask : { - red : false, - green : false, - blue : false, - alpha : false - }, - lineWidth : 1, - blending : BlendingState.ALPHA_BLEND, - stencilTest : { - enabled : true, - frontFunction : StencilFunction.ALWAYS, - backFunction : StencilFunction.ALWAYS, - reference : 0, - mask : ~0, - frontOperation : { - fail : StencilOperation.REPLACE, - zFail : StencilOperation.REPLACE, - zPass : StencilOperation.REPLACE - }, - backOperation : { - fail : StencilOperation.REPLACE, - zFail : StencilOperation.REPLACE, - zPass : StencilOperation.REPLACE - } - } - }); - rsOne.depthMask = !useDepthTest; - rsOne.depthTest.enabled = useDepthTest; - rsOne.lineWidth = outlineWidth; - this.rsOne = rsOne; - var rsTwo = this.rsTwo || context.createRenderState({ - lineWidth : 1, - depthMask : false, - blending : BlendingState.ALPHA_BLEND, - stencilTest : { - enabled : true, - frontFunction : StencilFunction.ALWAYS, - backFunction : StencilFunction.ALWAYS, - reference : 1, - mask : ~0, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.REPLACE - }, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.REPLACE - } - } - }); - rsTwo.depthTest.enabled = useDepthTest; - rsTwo.lineWidth = width; - this.rsTwo = rsTwo; - var rsThree = this.rsThree || context.createRenderState({ - lineWidth : 1, - depthMask : false, - blending : BlendingState.ALPHA_BLEND, - stencilTest : { - enabled : true, - frontFunction : StencilFunction.NOT_EQUAL, - backFunction : StencilFunction.NOT_EQUAL, - reference : 1, - mask : ~0, - frontOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.KEEP - }, - backOperation : { - fail : StencilOperation.KEEP, - zFail : StencilOperation.KEEP, - zPass : StencilOperation.KEEP - } - } - }); - rsThree.lineWidth = this.outlineWidth; - rsThree.depthTest.enabled = useDepthTest; - this.rsThree = rsThree; - - var rsPick = this.rsPick || context.createRenderState(); - rsPick.depthTest.enabled = useDepthTest; - rsPick.lineWidth = outlineWidth; - rsPick.depthMask = !useDepthTest; - this.rsPick = rsPick; - }; - function intersectsIDL(polyline) { return Cartesian3.dot(Cartesian3.UNIT_X, polyline._boundingVolume.center) < 0 || polyline._boundingVolume.intersect(Cartesian4.UNIT_Y) === Intersect.INTERSECTING; @@ -1213,16 +1102,6 @@ define([ } }; - /** - * @private - */ - PolylineBucket.prototype._clampWidth = function(context, value) { - var min = context.getMinimumAliasedLineWidth(); - var max = context.getMaximumAliasedLineWidth(); - - return Math.min(Math.max(value, min), max); - }; - /** * @private */ From 19cfc47de51d1f463f78467054adc0308fc44768 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Feb 2013 15:00:48 -0500 Subject: [PATCH 002/114] Start adding polyline width. --- Source/Scene/Polyline.js | 70 +---- Source/Scene/PolylineCollection.js | 475 ++++++++++++++--------------- Source/Shaders/PolylineVS.glsl | 19 +- 3 files changed, 255 insertions(+), 309 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 576c9ba0f0ec..996604e25940 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -30,7 +30,6 @@ define([ this._show = defaultValue(description.show, true); this._width = defaultValue(description.width, 1.0); - this._outlineWidth = defaultValue(description.outlineWidth, 1.0); this._color = Color.clone(defaultValue(description.color, Color.WHITE)); this._outlineColor = Color.clone(defaultValue(description.outlineColor, Color.WHITE)); @@ -53,14 +52,11 @@ define([ this._boundingVolume2D = new BoundingSphere(); // modified in PolylineCollection }; - var SHOW_INDEX = Polyline.SHOW_INDEX = 0; + var MISC = Polyline.MISC = 0; var POSITION_INDEX = Polyline.POSITION_INDEX = 1; var COLOR_INDEX = Polyline.COLOR_INDEX = 2; - var OUTLINE_COLOR_INDEX = Polyline.OUTLINE_COLOR_INDEX = 3; - var WIDTH_INDEX = Polyline.WIDTH_INDEX = 4; - var OUTLINE_WIDTH_INDEX = Polyline.OUTLINE_WIDTH_INDEX = 5; - var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 6; - var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 7; + var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 3; + var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 4; function makeDirty(polyline, propertyChanged) { ++polyline._propertiesChanged[propertyChanged]; @@ -104,7 +100,7 @@ define([ if (value !== this._show) { this._show = value; - makeDirty(this, SHOW_INDEX); + makeDirty(this, MISC); } }; @@ -240,60 +236,7 @@ define([ var width = this._width; if (value !== width) { this._width = value; - makeDirty(this, WIDTH_INDEX); - } - }; - - - /** - * Gets the outline width of the polyline. - * The actual width used is clamped to the minimum and maximum width supported by - * the WebGL implementation. These can be queried with - * {@link Context#getMinimumAliasedLineWidth} and {@link Context#getMaximumAliasedLineWidth}. - * - * @return {Number} The outline width of the polyline. - * - * @see Polyline#setOutlineWidth - * @see Context#getMinimumAliasedLineWidth - * @see Context#getMaximumAliasedLineWidth - * - * @example - * // 3 pixel total width, 1 pixel interior width - * polyline.width = 1.0; - * polyline.outlineWidth = 3.0; - */ - Polyline.prototype.getOutlineWidth = function() { - return this._outlineWidth; - }; - - /** - * Sets the outline width of the polyline. - * The actual width used is clamped to the minimum and maximum width supported by - * the WebGL implementation. These can be queried with - * {@link Context#getMinimumAliasedLineWidth} and {@link Context#getMaximumAliasedLineWidth}. - * - * @param {Number} value The outline width of the polyline. - * - * @exception {DeveloperError} value is required. - * - * @see Polyline#getOutlineWidth - * @see Context#getMinimumAliasedLineWidth - * @see Context#getMaximumAliasedLineWidth - * - * @example - * // 3 pixel total width, 1 pixel interior width - * polyline.width = 1.0; - * polyline.outlineWidth = 3.0; - */ - Polyline.prototype.setOutlineWidth = function(value) { - if (typeof value === 'undefined') { - throw new DeveloperError('value is required.'); - } - - var outlineWidth = this._outlineWidth; - if (value !== outlineWidth) { - this._outlineWidth = value; - makeDirty(this, OUTLINE_WIDTH_INDEX); + makeDirty(this, MISC); } }; @@ -329,7 +272,7 @@ define([ var outlineColor = this._outlineColor; if (!Color.equals(outlineColor, value)) { Color.clone(value, outlineColor); - makeDirty(this, OUTLINE_COLOR_INDEX); + makeDirty(this, COLOR_INDEX); } }; @@ -413,7 +356,6 @@ define([ typeof other !== 'undefined' && this._show === other._show && this._width === other._width && - this._outlineWidth === other._outlineWidth && this._horizontalOrigin === other._horizontalOrigin && cartesian3ArrayEquals(this._positions, other._positions) && Color.equals(this._color, other._color) && diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index e0b9934c1965..76cb9d663437 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -45,12 +45,18 @@ define([ PolylineFS) { "use strict"; - var SHOW_INDEX = Polyline.SHOW_INDEX; + // TODO: + // outline color + // picking + // better name than 'misc' for tex coord, expansion direction, show and width attribute + // materials + // separate by materials + // adjacency info in 2d at idl + // update without creating a new buffer + + var MISC_INDEX = Polyline.MISC; var POSITION_INDEX = Polyline.POSITION_INDEX; var COLOR_INDEX = Polyline.COLOR_INDEX; - var OUTLINE_COLOR_INDEX = Polyline.OUTLINE_COLOR_INDEX; - var WIDTH_INDEX = Polyline.WIDTH_INDEX; - var OUTLINE_WIDTH_INDEX = Polyline.OUTLINE_WIDTH_INDEX; //POSITION_SIZE_INDEX is needed for when the polyline's position array changes size. //When it does, we need to recreate the indicesBuffer. var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX; @@ -62,9 +68,10 @@ define([ position3DLow : 1, position2DHigh : 2, position2DLow : 3, - color : 4, - pickColor : 5, - show : 6 + prev : 4, + next : 5, + color : 6, + misc : 7 }; /** @@ -152,12 +159,9 @@ define([ // The buffer usage for each attribute is determined based on the usage of the attribute over time. this._buffersUsage = [ - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0},// SHOW_INDEX + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // MISC {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // POSITION_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // COLOR_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // OUTLINE_COLOR_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // WIDTH_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0} // OUTLINE_WIDTH_INDEX + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0} // COLOR_INDEX ]; this._mode = undefined; @@ -171,13 +175,10 @@ define([ this._polylinesToUpdate = []; this._colorVertexArrays = []; - this._outlineColorVertexArrays = []; - this._pickColorVertexArrays = []; this._positionBuffer = undefined; - this._outlineColorBuffer = undefined; + this._adjacencyBuffer = undefined; this._colorBuffer = undefined; - this._pickColorBuffer = undefined; - this._showBuffer = undefined; + this._miscBuffer = undefined; }; /** @@ -416,9 +417,11 @@ define([ } } //if a polyline's positions size changes, we need to recreate the vertex arrays and vertex buffers because the indices will be different. - if (properties[POSITION_SIZE_INDEX] || properties[WIDTH_INDEX] || properties[OUTLINE_WIDTH_INDEX] || createVertexArrays) { + if (properties[POSITION_SIZE_INDEX] || properties[MISC_INDEX] || createVertexArrays) { this._createVertexArrays(context); } else { + // TODO + /* length = polylinesToUpdate.length; polylineBuckets = this._polylineBuckets; for ( var ii = 0; ii < length; ++ii) { @@ -430,16 +433,13 @@ define([ if (polylineBuckets.hasOwnProperty(x)) { if (polylineBuckets[x] === bucket) { if (properties[POSITION_INDEX]) { - bucket.writePositionsUpdate(index, polyline, this._positionBuffer); + bucket.writePositionsUpdate(index, polyline, this._positionBuffer, this._adjacencyBuffer); } if (properties[COLOR_INDEX]) { bucket.writeColorUpdate(index, polyline, this._colorBuffer); } - if (properties[OUTLINE_COLOR_INDEX]) { - bucket.writeColorUpdate(index, polyline, this._outlineColorBuffer); - } - if (properties[SHOW_INDEX]) { - bucket.writeShowUpdate(index, polyline, this._showBuffer); + if (properties[MISC_INDEX]) { + bucket.writeMiscUpdate(index, polyline, this._miscBuffer); } break; } @@ -448,6 +448,7 @@ define([ } polyline._clean(); } + */ } polylinesToUpdate.length = 0; this._polylinesUpdated = false; @@ -486,13 +487,11 @@ define([ this._rs.depthMask = !useDepthTest; this._rs.depthTest.enabled = useDepthTest; - this._rs.lineWidth = clampWidth(context, this.width); length = this._colorVertexArrays.length; commands = this._commandLists.colorList; for ( var m = 0; m < length; ++m) { var vaColor = this._colorVertexArrays[m]; - //var vaOutlineColor = this._outlineColorVertexArrays[m]; buckets = this._colorVertexArrays[m].buckets; bucketLength = buckets.length; var p = commands.length; @@ -507,7 +506,7 @@ define([ command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.LINES; + command.primitiveType = PrimitiveType.TRIANGLES; command.count = bucketLocator.count; command.offset = bucketLocator.offset; command.shaderProgram = sp; @@ -517,6 +516,7 @@ define([ } } } + if (pass.pick) { if (typeof this._rsPick === 'undefined') { this._rsPick = context.createRenderState(); @@ -524,13 +524,12 @@ define([ this._rsPick.depthMask = !useDepthTest; this._rsPick.depthTest.enabled = useDepthTest; - this._rsPick.lineWidth = clampWidth(context, this.width); - length = this._pickColorVertexArrays.length; + length = this._colorVertexArrays.length; commands = this._commandLists.pickList; for ( var a = 0; a < length; ++a) { - var vaPickColor = this._pickColorVertexArrays[a]; - buckets = vaPickColor.buckets; + var vaColor = this._colorVertexArrays[a]; + buckets = this._colorVertexArrays[a].buckets; bucketLength = buckets.length; commands.length += bucketLength; for ( var b = 0; b < bucketLength; ++b) { @@ -543,12 +542,12 @@ define([ command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.LINES; + command.primitiveType = PrimitiveType.TRIANGLES; command.count = bucketLocator.count; command.offset = bucketLocator.offset; command.shaderProgram = sp; command.uniformMap = this._uniforms; - command.vertexArray = vaPickColor.va; + command.vertexArray = vaColor.va; command.renderState = this._rsPick; } } @@ -602,13 +601,6 @@ define([ return destroyObject(this); }; - function clampWidth(context, value) { - var min = context.getMinimumAliasedLineWidth(); - var max = context.getMaximumAliasedLineWidth(); - - return Math.min(Math.max(value, min), max); - } - PolylineCollection.prototype._computeNewBuffersUsage = function() { var buffersUsage = this._buffersUsage; var usageChanged = false; @@ -666,30 +658,31 @@ define([ } } if (totalLength > 0) { - var positionArray = new Float32Array(2 * totalLength * 3); - var outlineColorArray = new Uint8Array(totalLength * 4); - var colorArray = new Uint8Array(totalLength * 4); - var pickColorArray = new Uint8Array(totalLength * 4); - var showArray = new Uint8Array(totalLength); + var positionArray = new Float32Array(2 * totalLength * 3 * 2); + var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); + var colorArray = new Uint8Array(totalLength * 4 * 2); + var miscArray = new Float32Array(totalLength * 4 * 2); var position3DArray; var positionIndex = 0; + var adjacencyIndex = 0; var colorIndex = 0; - var showIndex = 0; + var miscIndex = 0; for (x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; - bucket.write(positionArray, colorArray, outlineColorArray, pickColorArray, showArray, positionIndex, showIndex, colorIndex, context); + bucket.write(positionArray, adjacencyArray, colorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context); if (this._mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { - position3DArray = new Float32Array(2 * totalLength * 3); + position3DArray = new Float32Array(2 * totalLength * 3 * 2); } - bucket.writeForMorph(position3DArray, positionIndex); + bucket.writeForMorph(position3DArray, adjacencyArray, positionIndex, adjacencyIndex); } var bucketLength = bucket.lengthOfPositions; - positionIndex += 2 * bucketLength * 3; - showIndex += bucketLength; - colorIndex += bucketLength * 4; + positionIndex += 2 * bucketLength * 3 * 2; + adjacencyIndex += 2 * bucketLength * 4 * 2; + colorIndex += bucketLength * 4 * 2; + miscIndex += bucketLength * 4 * 2; offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); } } @@ -698,12 +691,13 @@ define([ if (typeof position3DArray !== 'undefined') { position3DBuffer = context.createVertexBuffer(position3DArray, this._buffersUsage[POSITION_INDEX].bufferUsage); } - this._outlineColorBuffer = context.createVertexBuffer(outlineColorArray, this._buffersUsage[OUTLINE_COLOR_INDEX].bufferUsage); + this._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, this._buffersUsage[POSITION_INDEX].bufferUsage); this._colorBuffer = context.createVertexBuffer(colorArray, this._buffersUsage[COLOR_INDEX].bufferUsage); - this._pickColorBuffer = context.createVertexBuffer(pickColorArray, BufferUsage.STATIC_DRAW); - this._showBuffer = context.createVertexBuffer(showArray, this._buffersUsage[SHOW_INDEX].bufferUsage); + this._miscBuffer = context.createVertexBuffer(miscArray, this._buffersUsage[MISC_INDEX].bufferUsage); var colorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; + var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; + var miscSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var vbo = 0; var numberOfIndicesArrays = totalIndices.length; for ( var k = 0; k < numberOfIndicesArrays; ++k) { @@ -715,8 +709,10 @@ define([ vbo += vertexBufferOffset[k]; var positionHighOffset = 2 * (k * (positionSizeInBytes * SIXTYFOURK) - vbo * positionSizeInBytes);//componentsPerAttribute(3) * componentDatatype(4) var positionLowOffset = positionSizeInBytes + positionHighOffset; + var prevOffset = 2 * (k * (adjacencySizeInBytes * SIXTYFOURK) - vbo * adjacencySizeInBytes); + var nextOffset = adjacencySizeInBytes + prevOffset; var vertexColorBufferOffset = k * (colorSizeInBytes * SIXTYFOURK) - vbo * colorSizeInBytes; - var vertexShowBufferOffset = k * SIXTYFOURK - vbo; + var vertexMiscBufferOffset = k * (miscSizeInBytes * SIXTYFOURK) - vbo * miscSizeInBytes; var attributes = [{ index : attributeIndices.position3DHigh, componentsPerAttribute : 3, @@ -742,96 +738,32 @@ define([ offsetInBytes : positionLowOffset, strideInBytes : 2 * positionSizeInBytes }, { - index : attributeIndices.color, + index : attributeIndices.prev, componentsPerAttribute : 4, - normalize : true, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - vertexBuffer : this._colorBuffer, - offsetInBytes : vertexColorBufferOffset - }, { - index : attributeIndices.show, - componentsPerAttribute : 1, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - vertexBuffer : this._showBuffer, - offsetInBytes : vertexShowBufferOffset - }]; - - var attributesOutlineColor = [{ - index : attributeIndices.position3DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position3DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position2DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position2DLow, - componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes + vertexBuffer : this._adjacencyBuffer, + offsetInBytes : prevOffset, + strideInBytes : 2 * adjacencySizeInBytes }, { - index : attributeIndices.color, + index : attributeIndices.next, componentsPerAttribute : 4, - normalize : true, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - vertexBuffer : this._outlineColorBuffer, - offsetInBytes : vertexColorBufferOffset - }, { - index : attributeIndices.show, - componentsPerAttribute : 1, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - vertexBuffer : this._showBuffer, - offsetInBytes : vertexShowBufferOffset - }]; - - var attributesPickColor = [{ - index : attributeIndices.position3DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position3DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position2DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position2DLow, - componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes + vertexBuffer : this._adjacencyBuffer, + offsetInBytes : nextOffset, + strideInBytes : 2 * adjacencySizeInBytes }, { index : attributeIndices.color, componentsPerAttribute : 4, normalize : true, componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - vertexBuffer : this._pickColorBuffer, + vertexBuffer : this._colorBuffer, offsetInBytes : vertexColorBufferOffset }, { - index : attributeIndices.show, - componentsPerAttribute : 1, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - vertexBuffer : this._showBuffer, - offsetInBytes : vertexShowBufferOffset + index : attributeIndices.misc, + componentsPerAttribute : 2, + componentDatatype : ComponentDatatype.FLOAT, + vertexBuffer : this._miscBuffer, + offsetInBytes : vertexMiscBufferOffset }]; if (this._mode === SceneMode.SCENE3D) { @@ -839,57 +771,23 @@ define([ attributes[1].vertexBuffer = this._positionBuffer; attributes[2].value = [0.0, 0.0, 0.0]; attributes[3].value = [0.0, 0.0, 0.0]; - attributesOutlineColor[0].vertexBuffer = this._positionBuffer; - attributesOutlineColor[1].vertexBuffer = this._positionBuffer; - attributesOutlineColor[2].value = [0.0, 0.0, 0.0]; - attributesOutlineColor[3].value = [0.0, 0.0, 0.0]; - attributesPickColor[0].vertexBuffer = this._positionBuffer; - attributesPickColor[1].vertexBuffer = this._positionBuffer; - attributesPickColor[2].value = [0.0, 0.0, 0.0]; - attributesPickColor[3].value = [0.0, 0.0, 0.0]; } else if (this._mode === SceneMode.SCENE2D || this._mode === SceneMode.COLUMBUS_VIEW) { attributes[0].value = [0.0, 0.0, 0.0]; attributes[1].value = [0.0, 0.0, 0.0]; attributes[2].vertexBuffer = this._positionBuffer; attributes[3].vertexBuffer = this._positionBuffer; - attributesOutlineColor[0].value = [0.0, 0.0, 0.0]; - attributesOutlineColor[1].value = [0.0, 0.0, 0.0]; - attributesOutlineColor[2].vertexBuffer = this._positionBuffer; - attributesOutlineColor[3].vertexBuffer = this._positionBuffer; - attributesPickColor[0].value = [0.0, 0.0, 0.0]; - attributesPickColor[1].value = [0.0, 0.0, 0.0]; - attributesPickColor[2].vertexBuffer = this._positionBuffer; - attributesPickColor[3].vertexBuffer = this._positionBuffer; } else { attributes[0].vertexBuffer = position3DBuffer; attributes[1].vertexBuffer = position3DBuffer; attributes[2].vertexBuffer = this._positionBuffer; attributes[3].vertexBuffer = this._positionBuffer; - attributesOutlineColor[0].vertexBuffer = position3DBuffer; - attributesOutlineColor[1].vertexBuffer = position3DBuffer; - attributesOutlineColor[2].vertexBuffer = this._positionBuffer; - attributesOutlineColor[3].vertexBuffer = this._positionBuffer; - attributesPickColor[0].vertexBuffer = position3DBuffer; - attributesPickColor[1].vertexBuffer = position3DBuffer; - attributesPickColor[2].vertexBuffer = this._positionBuffer; - attributesPickColor[3].vertexBuffer = this._positionBuffer; } - var va = context.createVertexArray(attributes, indexBuffer); - var vaOutlineColor = context.createVertexArray(attributesOutlineColor, indexBuffer); - var vaPickColor = context.createVertexArray(attributesPickColor, indexBuffer); + var va = context.createVertexArray(attributes, indexBuffer); this._colorVertexArrays.push({ va : va, buckets : vertexArrayBuckets[k] }); - this._outlineColorVertexArrays.push({ - va : vaOutlineColor, - buckets : vertexArrayBuckets[k] - }); - this._pickColorVertexArrays.push({ - va : vaPickColor, - buckets : vertexArrayBuckets[k] - }); } } } @@ -901,12 +799,12 @@ define([ var length = polylines.length; for ( var i = 0; i < length; ++i) { var p = polylines[i]; - var outlineWidth = p.getOutlineWidth(); var width = p.getWidth(); - var hash = 'OL' + outlineWidth + 'W' + width; + // TODO separate by material + var hash = 'W' + width; var value = polylineBuckets[hash]; if (typeof value === 'undefined') { - value = polylineBuckets[hash] = new PolylineBucket(outlineWidth, width, this._mode, this._projection, this._modelMatrix); + value = polylineBuckets[hash] = new PolylineBucket(width, this._mode, this._projection, this._modelMatrix); } value.addPolyline(p); } @@ -949,12 +847,8 @@ define([ var length = this._colorVertexArrays.length; for ( var t = 0; t < length; ++t) { this._colorVertexArrays[t].va.destroy(); - this._pickColorVertexArrays[t].va.destroy(); - this._outlineColorVertexArrays[t].va.destroy(); } this._colorVertexArrays.length = 0; - this._pickColorVertexArrays.length = 0; - this._outlineColorVertexArrays.length = 0; }; PolylineCollection.prototype._updatePolyline = function(polyline, propertyChanged) { @@ -976,7 +870,7 @@ define([ /** * @private */ - function VertexArrayBucketLocator(count, offset, bucket) { + function VertexArrayBucketLocator(count, offset) { this.count = count; this.offset = offset; } @@ -984,9 +878,8 @@ define([ /** * @private */ - var PolylineBucket = function(outlineWidth, width, mode, projection, modelMatrix) { + var PolylineBucket = function(width, mode, projection, modelMatrix) { this.width = width; - this.outlineWidth = outlineWidth; this.polylines = []; this.lengthOfPositions = 0; this.mode = mode; @@ -1022,20 +915,57 @@ define([ return polyline._setSegments(segments); }; + var computeAdjacencyAnglesPosition = new Cartesian3(); + + function computeAdjacencyAngles(position, index, positions, result, modelMatrix) { + // TODO handle cross idl + var currentPosition = position; + if (typeof result === 'undefined') { + result = new Cartesian4(); + } + + var prev = computeAdjacencyAnglesPosition; + if (index === 0) { + prev = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[1], prev) : Matrix4.multiplyByPoint(modelMatrix, positions[1], prev); + Cartesian3.subtract(prev, currentPosition, prev); + Cartesian3.negate(prev, prev); + } else { + prev = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[index - 1], prev) : Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); + Cartesian3.subtract(prev, position, prev); + } + Cartesian3.normalize(prev, prev); + result.x = Math.acos(prev.z); + result.y = Math.atan2(prev.y, prev.x); + + var next = computeAdjacencyAnglesPosition; + if (index === positions.length - 1) { + Cartesian3.negate(prev, next); + } else { + next = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[index + 1], next) : Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); + Cartesian3.subtract(next, position, next); + } + Cartesian3.normalize(next, next); + result.z = Math.acos(next.z); + result.w = Math.atan2(next.y, next.x); + + return result; + } + var scratchWritePosition = new Cartesian3(); + var scratchAdjacency = new Cartesian4(); /** * @private */ - PolylineBucket.prototype.write = function(positionArray, colorArray, outlineColorArray, pickColorArray, showArray, positionIndex, showIndex, colorIndex, context) { + PolylineBucket.prototype.write = function(positionArray, adjacencyArray, colorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { var polylines = this.polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { var polyline = polylines[i]; var color = polyline.getColor(); + var width = polyline.getWidth(); var show = polyline.getShow(); - var outlineColor = polyline.getOutlineColor(); - var pickColor = polyline.getPickId(context).unnormalizedRgb; + //var pickColor = polyline.getPickId(context).unnormalizedRgb; var positions = this._getPositions(polyline); var positionsLength = positions.length; for ( var j = 0; j < positionsLength; ++j) { @@ -1043,22 +973,39 @@ define([ scratchWritePosition.x = position.x; scratchWritePosition.y = position.y; scratchWritePosition.z = (this.mode !== SceneMode.SCENE2D) ? position.z : 0.0; - EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); - outlineColorArray[colorIndex] = Color.floatToByte(outlineColor.red); - outlineColorArray[colorIndex + 1] = Color.floatToByte(outlineColor.green); - outlineColorArray[colorIndex + 2] = Color.floatToByte(outlineColor.blue); - outlineColorArray[colorIndex + 3] = Color.floatToByte(outlineColor.alpha); - colorArray[colorIndex] = Color.floatToByte(color.red); - colorArray[colorIndex + 1] = Color.floatToByte(color.green); - colorArray[colorIndex + 2] = Color.floatToByte(color.blue); - colorArray[colorIndex + 3] = Color.floatToByte(color.alpha); - pickColorArray[colorIndex] = pickColor.red; - pickColorArray[colorIndex + 1] = pickColor.green; - pickColorArray[colorIndex + 2] = pickColor.blue; - pickColorArray[colorIndex + 3] = 255; - showArray[showIndex++] = show; - positionIndex += 6; - colorIndex += 4; + + var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchAdjacency); + + for (var k = 0; k < 2; ++k) { + EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); + + if (this.mode === SceneMode.SCENE3D) { + adjacencyArray[adjacencyIndex] = adjacencyAngles.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + } else { + adjacencyArray[adjacencyIndex + 2] = adjacencyAngles.x; + adjacencyArray[adjacencyIndex + 3] = adjacencyAngles.y; + adjacencyArray[adjacencyIndex + 6] = adjacencyAngles.z; + adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; + } + + colorArray[colorIndex] = Color.floatToByte(color.red); + colorArray[colorIndex + 1] = Color.floatToByte(color.green); + colorArray[colorIndex + 2] = Color.floatToByte(color.blue); + colorArray[colorIndex + 3] = Color.floatToByte(color.alpha); + + miscArray[miscIndex] = j / positionsLength; // s tex coord + miscArray[miscIndex + 1] = k; // expand direction + miscArray[miscIndex + 2] = width; + miscArray[miscIndex + 3] = show; + + positionIndex += 6; + adjacencyIndex += 8; + colorIndex += 4; + miscIndex += 4; + } } } }; @@ -1066,7 +1013,7 @@ define([ /** * @private */ - PolylineBucket.prototype.writeForMorph = function(positionArray, positionIndex) { + PolylineBucket.prototype.writeForMorph = function(positionArray, adjacencyArray, positionIndex, adjacencyIndex) { var modelMatrix = this.modelMatrix; var position; var polylines = this.polylines; @@ -1077,6 +1024,7 @@ define([ var numberOfSegments; var j; + var k; if (intersectsIDL(polyline)) { var segments = polyline._getSegments(); numberOfSegments = segments.length; @@ -1084,10 +1032,23 @@ define([ var segment = segments[j]; var segmentLength = segment.length; for ( var n = 0; n < segmentLength; ++n) { - position = positions[segment[n].index]; + var index = segment[n].index; + position = positions[index]; position = modelMatrix.multiplyByPoint(position); - EncodedCartesian3.writeElements(position, positionArray, positionIndex); - positionIndex += 6; + + var adjacencyAngles = computeAdjacencyAngles(position, index, positions, scratchAdjacency, modelMatrix); + + for (k = 0; k < 2; ++k) { + EncodedCartesian3.writeElements(position, positionArray, positionIndex); + + adjacencyArray[adjacencyIndex] = adjacencyAngles.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + + positionIndex += 6; + adjacencyIndex += 8; + } } } } else { @@ -1095,8 +1056,20 @@ define([ for ( j = 0; j < numberOfSegments; ++j) { position = positions[j]; position = modelMatrix.multiplyByPoint(position); - EncodedCartesian3.writeElements(position, positionArray, positionIndex); - positionIndex += 6; + + var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchAdjacency, modelMatrix); + + for (k = 0; k < 2; ++k) { + EncodedCartesian3.writeElements(position, positionArray, positionIndex); + + adjacencyArray[adjacencyIndex] = adjacencyAngles.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + + positionIndex += 6; + adjacencyIndex += 8; + } } } } @@ -1107,7 +1080,7 @@ define([ */ PolylineBucket.prototype._updateIndices3D = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { var vaCount = vertexArrayBuckets.length - 1; - var bucketLocator = new VertexArrayBucketLocator(0, offset, this); + var bucketLocator = new VertexArrayBucketLocator(0, offset); vertexArrayBuckets[vaCount].push(bucketLocator); var count = 0; var indices = totalIndices[totalIndices.length - 1]; @@ -1124,34 +1097,37 @@ define([ if (positions.length > 0) { for ( var j = 0; j < positionsLength; ++j) { if (j !== positionsLength - 1) { - if (indicesCount === SIXTYFOURK - 1) { - vertexBufferOffset.push(1); + if (indicesCount + 3 >= SIXTYFOURK - 1) { + vertexBufferOffset.push(2); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count; + bucketLocator.count = count + 2; count = 0; offset = 0; bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } - count += 2; - offset += 2; - indices.push(indicesCount++); - indices.push(indicesCount); + + indices.push(indicesCount, indicesCount + 2, indicesCount + 1); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + + count += 6; + offset += 6; + indicesCount += 2; } } - if (indicesCount < SIXTYFOURK - 1) { - indicesCount++; + if (indicesCount + 3 < SIXTYFOURK - 1) { + indicesCount += 2; } else { vertexBufferOffset.push(0); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count; + bucketLocator.count = count + 2; offset = 0; count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); + bucketLocator = new VertexArrayBucketLocator(0, 0); vertexArrayBuckets[++vaCount] = [bucketLocator]; } } @@ -1166,13 +1142,13 @@ define([ */ PolylineBucket.prototype._updateIndices2D = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { var vaCount = vertexArrayBuckets.length - 1; - var bucketLocator = new VertexArrayBucketLocator(0, offset, this); + var bucketLocator = new VertexArrayBucketLocator(0, offset); vertexArrayBuckets[vaCount].push(bucketLocator); var count = 0; var indices = totalIndices[totalIndices.length - 1]; var indicesCount = 0; if (indices.length > 0) { - indicesCount = indices[indices.length - 1] + 1; + indicesCount = indices[indices.length - 1] + 2; } var polylines = this.polylines; var length = polylines.length; @@ -1185,78 +1161,89 @@ define([ for ( var k = 0; k < numberOfSegments; ++k) { var segment = segments[k]; var segmentLength = segment.length; - for ( var n = 0; n < segmentLength; ++n) { - if (n !== segmentLength - 1) { - if (indicesCount === SIXTYFOURK - 1) { - vertexBufferOffset.push(1); + for ( var n = 0; n < segmentLength - 1; ++n) { + if (n !== segmentLength - 2) { + if (indicesCount + 3 >= SIXTYFOURK - 1) { + vertexBufferOffset.push(2); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count; + bucketLocator.count = count + 2; count = 0; offset = 0; bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } + + indices.push(indicesCount, indicesCount + 2, indicesCount + 1); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + count += 2; offset += 2; - indices.push(indicesCount++); - indices.push(indicesCount); + indicesCount += 2; } } if (k !== numberOfSegments - 1) { - indicesCount++; + count += 2; + offset += 2; + indicesCount += 4; } } - if (indicesCount < SIXTYFOURK - 1) { - indicesCount++; + if (indicesCount + 3 < SIXTYFOURK - 1) { + count += 2; + offset += 2; + indicesCount += 4; } else { vertexBufferOffset.push(0); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count; + bucketLocator.count = count + 2; offset = 0; count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); + bucketLocator = new VertexArrayBucketLocator(0, 0); vertexArrayBuckets[++vaCount] = [bucketLocator]; } } } else { var positions = polyline.getPositions(); var positionsLength = positions.length; - for ( var j = 0; j < positionsLength; ++j) { - if (j !== positionsLength - 1) { - if (indicesCount === SIXTYFOURK - 1) { - vertexBufferOffset.push(1); + for ( var j = 0; j < positionsLength - 1; ++j) { + if (j !== positionsLength - 2) { + if (indicesCount + 3 >= SIXTYFOURK - 1) { + vertexBufferOffset.push(2); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count; + bucketLocator.count = count + 2; count = 0; offset = 0; bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } + + indices.push(indicesCount, indicesCount + 2, indicesCount + 1); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + count += 2; offset += 2; - indices.push(indicesCount++); - indices.push(indicesCount); + indicesCount += 2; } } - - if (indicesCount < SIXTYFOURK - 1) { - indicesCount++; + if (indicesCount + 3 < SIXTYFOURK - 1) { + count += 2; + offset += 2; + indicesCount += 4; } else { vertexBufferOffset.push(0); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count; + bucketLocator.count = count + 2; offset = 0; count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); + bucketLocator = new VertexArrayBucketLocator(0, 0); vertexArrayBuckets[++vaCount] = [bucketLocator]; } } @@ -1288,7 +1275,7 @@ define([ if (p === polyline) { break; } - positionIndex += p._actualLength; + positionIndex += p._actualLength * 2; } return positionIndex; }; @@ -1342,6 +1329,8 @@ define([ return newPositions; }; + // TODO + /** * @private */ diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 781dddc8ed43..9428d2e69a90 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -2,8 +2,10 @@ attribute vec3 position3DHigh; attribute vec3 position3DLow; attribute vec3 position2DHigh; attribute vec3 position2DLow; +attribute vec4 prev; +attribute vec4 next; attribute vec4 color; -attribute float show; +attribute vec4 misc; varying vec4 v_color; @@ -11,6 +13,11 @@ uniform float u_morphTime; void main() { + float texCoord = misc.x; + float expandDir = misc.y; + float width = misc.z; + float show = misc.w; + vec4 p; if (u_morphTime == 1.0) @@ -28,7 +35,15 @@ void main() czm_translateRelativeToEye(position3DHigh, position3DLow), u_morphTime); } + + p.z += expandDir * 100000.0; + vec4 positionEC = czm_modelViewRelativeToEye * p; + //positionEC.xyz *= show; + + vec4 positionWC = czm_eyeToWindowCoordinates(positionEC); + //positionWC.xy += (vec2(0.0, width * expandDir) * czm_highResolutionSnapScale); - gl_Position = czm_modelViewProjectionRelativeToEye * p * show; // position in clip coordinates + gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); + v_color = color; } From 91120e600f3edb327d8615f939f9772cc3d1992c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Feb 2013 17:51:34 -0500 Subject: [PATCH 003/114] Polyline width tweaks. --- Apps/Sandcastle/gallery/Polylines.html | 3 +- Source/Scene/PolylineCollection.js | 52 ++++++++++++-------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index 6bda5677d4d2..d025529095dc 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -73,8 +73,7 @@ Cesium.Cartographic.fromDegrees(-105.0, 35.0), Cesium.Cartographic.fromDegrees(-100.0, 32.0) ])); - widePolyline.setWidth(5); // Request 5 pixels interior - widePolyline.setOutlineWidth(10); // Request 10 pixels total + widePolyline.setWidth(10); widePolyline.setOutlineColor({ red : 1.0, green : 0.0, diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 76cb9d663437..72406d9381b4 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -997,9 +997,9 @@ define([ colorArray[colorIndex + 3] = Color.floatToByte(color.alpha); miscArray[miscIndex] = j / positionsLength; // s tex coord - miscArray[miscIndex + 1] = k; // expand direction + miscArray[miscIndex + 1] = 2 * k - 1; // expand direction miscArray[miscIndex + 2] = width; - miscArray[miscIndex + 3] = show; + //miscArray[miscIndex + 3] = show; // TODO positionIndex += 6; adjacencyIndex += 8; @@ -1102,7 +1102,7 @@ define([ indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count + 2; + bucketLocator.count = count; count = 0; offset = 0; bucketLocator = new VertexArrayBucketLocator(0, 0, this); @@ -1110,7 +1110,7 @@ define([ } indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount, indicesCount + 2, indicesCount + 3); count += 6; offset += 6; @@ -1124,7 +1124,7 @@ define([ indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count + 2; + bucketLocator.count = count; offset = 0; count = 0; bucketLocator = new VertexArrayBucketLocator(0, 0); @@ -1148,7 +1148,7 @@ define([ var indices = totalIndices[totalIndices.length - 1]; var indicesCount = 0; if (indices.length > 0) { - indicesCount = indices[indices.length - 1] + 2; + indicesCount = indices[indices.length - 1] + 1; } var polylines = this.polylines; var length = polylines.length; @@ -1161,14 +1161,14 @@ define([ for ( var k = 0; k < numberOfSegments; ++k) { var segment = segments[k]; var segmentLength = segment.length; - for ( var n = 0; n < segmentLength - 1; ++n) { - if (n !== segmentLength - 2) { + for ( var n = 0; n < segmentLength; ++n) { + if (n !== segmentLength - 1) { if (indicesCount + 3 >= SIXTYFOURK - 1) { vertexBufferOffset.push(2); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count + 2; + bucketLocator.count = count; count = 0; offset = 0; bucketLocator = new VertexArrayBucketLocator(0, 0, this); @@ -1176,30 +1176,26 @@ define([ } indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount, indicesCount + 2, indicesCount + 3); - count += 2; - offset += 2; + count += 6; + offset += 6; indicesCount += 2; } } if (k !== numberOfSegments - 1) { - count += 2; - offset += 2; - indicesCount += 4; + indicesCount += 2; } } if (indicesCount + 3 < SIXTYFOURK - 1) { - count += 2; - offset += 2; - indicesCount += 4; + indicesCount += 2; } else { vertexBufferOffset.push(0); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count + 2; + bucketLocator.count = count; offset = 0; count = 0; bucketLocator = new VertexArrayBucketLocator(0, 0); @@ -1209,14 +1205,14 @@ define([ } else { var positions = polyline.getPositions(); var positionsLength = positions.length; - for ( var j = 0; j < positionsLength - 1; ++j) { - if (j !== positionsLength - 2) { + for ( var j = 0; j < positionsLength; ++j) { + if (j !== positionsLength - 1) { if (indicesCount + 3 >= SIXTYFOURK - 1) { vertexBufferOffset.push(2); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count + 2; + bucketLocator.count = count; count = 0; offset = 0; bucketLocator = new VertexArrayBucketLocator(0, 0, this); @@ -1224,23 +1220,21 @@ define([ } indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount, indicesCount + 2, indicesCount + 3); - count += 2; - offset += 2; + count += 6; + offset += 6; indicesCount += 2; } } if (indicesCount + 3 < SIXTYFOURK - 1) { - count += 2; - offset += 2; - indicesCount += 4; + indicesCount += 2; } else { vertexBufferOffset.push(0); indices = []; totalIndices.push(indices); indicesCount = 0; - bucketLocator.count = count + 2; + bucketLocator.count = count; offset = 0; count = 0; bucketLocator = new VertexArrayBucketLocator(0, 0); From b7b9177050ba29465b1dc711df2ccabcc87b77d8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Feb 2013 13:26:34 -0500 Subject: [PATCH 004/114] Displace polyline vertices in the vertex shader to add width. --- Source/Scene/PolylineCollection.js | 10 ++++---- Source/Shaders/PolylineVS.glsl | 37 ++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 72406d9381b4..16eac9f35d1a 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -760,7 +760,7 @@ define([ offsetInBytes : vertexColorBufferOffset }, { index : attributeIndices.misc, - componentsPerAttribute : 2, + componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, vertexBuffer : this._miscBuffer, offsetInBytes : vertexMiscBufferOffset @@ -999,7 +999,7 @@ define([ miscArray[miscIndex] = j / positionsLength; // s tex coord miscArray[miscIndex + 1] = 2 * k - 1; // expand direction miscArray[miscIndex + 2] = width; - //miscArray[miscIndex + 3] = show; // TODO + miscArray[miscIndex + 3] = show; positionIndex += 6; adjacencyIndex += 8; @@ -1110,7 +1110,7 @@ define([ } indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); count += 6; offset += 6; @@ -1176,7 +1176,7 @@ define([ } indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); count += 6; offset += 6; @@ -1220,7 +1220,7 @@ define([ } indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); count += 6; offset += 6; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 9428d2e69a90..774d78aa2e0b 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -11,6 +11,15 @@ varying vec4 v_color; uniform float u_morphTime; +vec3 sphericalToCartesian(vec2 latLon) +{ + float sinTheta = sin(latLon.x); + float x = sinTheta * cos(latLon.y); + float y = sinTheta * sin(latLon.y); + float z = cos(latLon.x); + return vec3(x, y, z); +} + void main() { float texCoord = misc.x; @@ -19,30 +28,48 @@ void main() float show = misc.w; vec4 p; + vec4 prevDir; + vec4 nextDir; if (u_morphTime == 1.0) { p = vec4(czm_translateRelativeToEye(position3DHigh, position3DLow), 1.0); + prevDir = vec4(sphericalToCartesian(prev.xy), 0.0); + nextDir = vec4(sphericalToCartesian(next.xy), 0.0); } else if (u_morphTime == 0.0) { p = vec4(czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), 1.0); + prevDir = vec4(sphericalToCartesian(prev.zw), 0.0); + nextDir = vec4(sphericalToCartesian(next.zw), 0.0); } else { p = czm_columbusViewMorph( - czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), + czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), czm_translateRelativeToEye(position3DHigh, position3DLow), u_morphTime); + prevDir = czm_columbusViewMorph(sphericalToCartesian(prev.xy), sphericalToCartesian(prev.zw), u_morphTime); + nextDir = czm_columbusViewMorph(sphericalToCartesian(next.xy), sphericalToCartesian(next.zw), u_morphTime); + + prevDir.w = 0.0; + nextDir.w = 0.0; } - p.z += expandDir * 100000.0; vec4 positionEC = czm_modelViewRelativeToEye * p; - //positionEC.xyz *= show; - vec4 positionWC = czm_eyeToWindowCoordinates(positionEC); - //positionWC.xy += (vec2(0.0, width * expandDir) * czm_highResolutionSnapScale); + + vec4 prevEC = czm_modelView * prevDir; + vec4 nextEC = czm_modelView * nextDir; + vec4 directionEC = vec4((prevEC.xyz + nextEC.xyz) * 0.5, 0.0); + vec4 directionWC = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + directionEC.xyz, 1.0)); + directionWC.xy = normalize(directionWC.xy - positionWC.xy); + + vec2 direction = expandDir * directionWC.xy; + + positionWC.xy += direction * width * 0.5; + gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); v_color = color; From 50ef16eba476da5317061534fe9d799ecde97f56 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Feb 2013 14:10:59 -0500 Subject: [PATCH 005/114] Tweak displacement magnitude in polyline vertex shader. --- Source/Shaders/PolylineVS.glsl | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 774d78aa2e0b..9b34480cc31d 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -24,7 +24,7 @@ void main() { float texCoord = misc.x; float expandDir = misc.y; - float width = misc.z; + float width = misc.z * 0.5; float show = misc.w; vec4 p; @@ -61,14 +61,20 @@ void main() vec4 prevEC = czm_modelView * prevDir; vec4 nextEC = czm_modelView * nextDir; - - vec4 directionEC = vec4((prevEC.xyz + nextEC.xyz) * 0.5, 0.0); - vec4 directionWC = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + directionEC.xyz, 1.0)); - directionWC.xy = normalize(directionWC.xy - positionWC.xy); - vec2 direction = expandDir * directionWC.xy; + vec4 prevWC = czm_eyeToWindowCoordinates(vec4(prevEC.xyz + positionEC.xyz, 1.0)); + prevWC.xy = normalize(prevWC.xy - positionWC.xy); + vec4 nextWC = czm_eyeToWindowCoordinates(vec4(nextEC.xyz + positionEC.xyz, 1.0)); + nextWC.xy = normalize(nextWC.xy - positionWC.xy); + + float angle = acos(dot(prevWC.xy, nextWC.xy)); + float height = width / tan(angle * 0.5); + + vec2 direction = normalize((prevWC.xy + nextWC.xy) * 0.5); + direction *= length(vec2(width, height)); + direction *= expandDir; - positionWC.xy += direction * width * 0.5; + positionWC.xy += direction; gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); From 9e635ca1920302b0f6a84bc9f3839ebf540bed26 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Feb 2013 15:17:55 -0500 Subject: [PATCH 006/114] Fix polyline endpoints. --- Source/Shaders/PolylineVS.glsl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 9b34480cc31d..5ccab29561b9 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -68,13 +68,21 @@ void main() nextWC.xy = normalize(nextWC.xy - positionWC.xy); float angle = acos(dot(prevWC.xy, nextWC.xy)); - float height = width / tan(angle * 0.5); - vec2 direction = normalize((prevWC.xy + nextWC.xy) * 0.5); - direction *= length(vec2(width, height)); - direction *= expandDir; + vec2 direction; + if (abs(angle - czm_pi) < czm_epsilon1) + { + mat2 rotation = mat2(cos(czm_piOverTwo), sin(czm_piOverTwo), -sin(czm_piOverTwo), cos(czm_piOverTwo)); + direction = rotation * nextWC.xy; + direction *= width; + } + else + { + direction = normalize((prevWC.xy + nextWC.xy) * 0.5); + direction *= width / sin(angle * 0.5); + } - positionWC.xy += direction; + positionWC.xy += direction * expandDir; gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); From 1c2113979f0fd14ff0db6595fac8dbcc39fc0f65 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Feb 2013 15:47:08 -0500 Subject: [PATCH 007/114] Fix line flickering across the viewport. --- Source/Shaders/PolylineVS.glsl | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 5ccab29561b9..be5d1caa735c 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -67,19 +67,24 @@ void main() vec4 nextWC = czm_eyeToWindowCoordinates(vec4(nextEC.xyz + positionEC.xyz, 1.0)); nextWC.xy = normalize(nextWC.xy - positionWC.xy); - float angle = acos(dot(prevWC.xy, nextWC.xy)); + float angle = acos(dot(prevWC.xy, nextWC.xy)) * 0.5; vec2 direction; - if (abs(angle - czm_pi) < czm_epsilon1) + if (abs(angle - czm_piOverTwo) < czm_epsilon3) { mat2 rotation = mat2(cos(czm_piOverTwo), sin(czm_piOverTwo), -sin(czm_piOverTwo), cos(czm_piOverTwo)); direction = rotation * nextWC.xy; direction *= width; } + else if (abs(angle) < czm_epsilon3) + { + direction = normalize((prevWC.xy + nextWC.xy) * 0.5); + direction *= width; + } else { direction = normalize((prevWC.xy + nextWC.xy) * 0.5); - direction *= width / sin(angle * 0.5); + direction *= width / sin(angle); } positionWC.xy += direction * expandDir; From 712e3470fb1f0f391227be9abf58fedccefb36ae Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Feb 2013 17:48:31 -0500 Subject: [PATCH 008/114] Update buffers instead of creating new ones. --- Source/DynamicScene/DynamicPathVisualizer.js | 9 --- .../DynamicScene/DynamicPolylineVisualizer.js | 9 --- Source/Scene/PolylineCollection.js | 69 +++++++++++++------ 3 files changed, 47 insertions(+), 40 deletions(-) diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 655dcc50149a..f8693db44efd 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -137,7 +137,6 @@ define([ // CZML_TODO Determine official defaults polyline.setColor(Color.WHITE); polyline.setOutlineColor(Color.BLACK); - polyline.setOutlineWidth(1); polyline.setWidth(1); } else { polyline = this._polylineCollection.get(pathVisualizerIndex); @@ -156,14 +155,6 @@ define([ polyline.setOutlineColor(property.getValue(time, polyline.getOutlineColor())); } - property = dynamicPath.outlineWidth; - if (typeof property !== 'undefined') { - var outlineWidth = property.getValue(time); - if (typeof outlineWidth !== 'undefined') { - polyline.setOutlineWidth(outlineWidth); - } - } - property = dynamicPath.width; if (typeof property !== 'undefined') { var width = property.getValue(time); diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index d48429aa8bab..d7030543dfae 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -208,7 +208,6 @@ define([ // CZML_TODO Determine official defaults polyline.setColor(Color.WHITE); polyline.setOutlineColor(Color.BLACK); - polyline.setOutlineWidth(1); polyline.setWidth(1); } else { polyline = this._polylineCollection.get(polylineVisualizerIndex); @@ -232,14 +231,6 @@ define([ polyline.setOutlineColor(property.getValue(time, polyline.getOutlineColor())); } - property = dynamicPolyline.outlineWidth; - if (typeof property !== 'undefined') { - var outlineWidth = property.getValue(time); - if (typeof outlineWidth !== 'undefined') { - polyline.setOutlineWidth(outlineWidth); - } - } - property = dynamicPolyline.width; if (typeof property !== 'undefined') { var width = property.getValue(time); diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 16eac9f35d1a..df21a9845d29 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -52,7 +52,6 @@ define([ // materials // separate by materials // adjacency info in 2d at idl - // update without creating a new buffer var MISC_INDEX = Polyline.MISC; var POSITION_INDEX = Polyline.POSITION_INDEX; @@ -420,8 +419,6 @@ define([ if (properties[POSITION_SIZE_INDEX] || properties[MISC_INDEX] || createVertexArrays) { this._createVertexArrays(context); } else { - // TODO - /* length = polylinesToUpdate.length; polylineBuckets = this._polylineBuckets; for ( var ii = 0; ii < length; ++ii) { @@ -448,7 +445,6 @@ define([ } polyline._clean(); } - */ } polylinesToUpdate.length = 0; this._polylinesUpdated = false; @@ -1105,7 +1101,7 @@ define([ bucketLocator.count = count; count = 0; offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); + bucketLocator = new VertexArrayBucketLocator(0, 0); vertexArrayBuckets[++vaCount] = [bucketLocator]; } @@ -1171,7 +1167,7 @@ define([ bucketLocator.count = count; count = 0; offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); + bucketLocator = new VertexArrayBucketLocator(0, 0); vertexArrayBuckets[++vaCount] = [bucketLocator]; } @@ -1215,7 +1211,7 @@ define([ bucketLocator.count = count; count = 0; offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); + bucketLocator = new VertexArrayBucketLocator(0, 0); vertexArrayBuckets[++vaCount] = [bucketLocator]; } @@ -1269,7 +1265,7 @@ define([ if (p === polyline) { break; } - positionIndex += p._actualLength * 2; + positionIndex += p._actualLength; } return positionIndex; }; @@ -1323,28 +1319,48 @@ define([ return newPositions; }; - // TODO - /** * @private */ - PolylineBucket.prototype.writePositionsUpdate = function(positionIndex, polyline, buffer) { + PolylineBucket.prototype.writePositionsUpdate = function(positionIndex, polyline, positionBuffer, adjacencyBuffer) { var positionsLength = polyline._actualLength; if (positionsLength) { positionIndex += this._getPolylineStartIndex(polyline); - var positionArray = new Float32Array(2 * positionsLength * 3); + var positionArray = new Float32Array(2 * positionsLength * 3 * 2); + var adjacencyArray = new Float32Array(2 * positionsLength * 4 * 2); var index = 0; + var adjacencyIndex = 0; var positions = this._getPositions(polyline); for ( var i = 0; i < positionsLength; ++i) { var position = positions[i]; scratchWritePosition.x = position.x; scratchWritePosition.y = position.y; scratchWritePosition.z = (this.mode !== SceneMode.SCENE2D) ? position.z : 0.0; - EncodedCartesian3.writeElements(scratchWritePosition, positionArray, index); - index += 6; + + var adjacencyAngles = computeAdjacencyAngles(position, i, positions, scratchAdjacency); + + for (var j = 0; j < 2; ++j) { + EncodedCartesian3.writeElements(scratchWritePosition, positionArray, index); + + if (this.mode === SceneMode.SCENE3D) { + adjacencyArray[adjacencyIndex] = adjacencyAngles.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + } else { + adjacencyArray[adjacencyIndex + 2] = adjacencyAngles.x; + adjacencyArray[adjacencyIndex + 3] = adjacencyAngles.y; + adjacencyArray[adjacencyIndex + 6] = adjacencyAngles.z; + adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; + } + + index += 6; + adjacencyIndex += 8; + } } - buffer.copyFromArrayView(positionArray, 2 * 12 * positionIndex); + positionBuffer.copyFromArrayView(positionArray, 2 * 3 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); + adjacencyBuffer.copyFromArrayView(adjacencyArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); } }; @@ -1362,31 +1378,40 @@ define([ var green = Color.floatToByte(color.green); var blue = Color.floatToByte(color.blue); var alpha = Color.floatToByte(color.alpha); - var colorsArray = new Uint8Array(positionsLength * 4); - for ( var j = 0; j < positionsLength; ++j) { + var colorsArray = new Uint8Array(4 * positionsLength * 2); + for ( var j = 0; j < positionsLength * 2; ++j) { colorsArray[index] = red; colorsArray[index + 1] = green; colorsArray[index + 2] = blue; colorsArray[index + 3] = alpha; index += 4; } - buffer.copyFromArrayView(colorsArray, 4 * positionIndex); + buffer.copyFromArrayView(colorsArray, 4 * positionIndex * 2); } }; /** * @private */ - PolylineBucket.prototype.writeShowUpdate = function(positionIndex, polyline, buffer) { + PolylineBucket.prototype.writeMiscUpdate = function(positionIndex, polyline, buffer) { var positionsLength = polyline._actualLength; if (positionsLength) { positionIndex += this._getPolylineStartIndex(polyline); var show = polyline.getShow(); - var showArray = new Uint8Array(positionsLength); + var width = polyline.getWidth(); + var miscArray = new Float32Array(4 * positionsLength * 2); + var miscIndex = 0; for ( var j = 0; j < positionsLength; ++j) { - showArray[j] = show; + for (var k = 0; k < 2; ++k) { + miscArray[miscIndex] = j / positionsLength; // s tex coord + miscArray[miscIndex + 1] = 2 * k - 1; // expand direction + miscArray[miscIndex + 2] = width; + miscArray[miscIndex + 3] = show; + + miscIndex += 4; + } } - buffer.copyFromArrayView(showArray, positionIndex); + buffer.copyFromArrayView(miscArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); } }; From 3e09b856e22cd40658ccb84c04ad8f641183f0b2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Feb 2013 14:13:10 -0500 Subject: [PATCH 009/114] Tweak polyline position direction. Move function to convert from spherical to cartesian coordinates to built-in functions. --- Source/Shaders/BuiltinFunctions.glsl | 12 +++++++++ Source/Shaders/PolylineVS.glsl | 38 +++++++++++++++------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index cc805cc32fa4..ddbdf823ecdd 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -935,6 +935,18 @@ vec3 czm_translateRelativeToEye(vec3 high, vec3 low) return highDifference + lowDifference; } +/** + * TODO + */ +vec3 czm_sphericalToCartesianCoordinates(vec2 latLon) +{ + float sinTheta = sin(latLon.x); + float x = sinTheta * cos(latLon.y); + float y = sinTheta * sin(latLon.y); + float z = cos(latLon.x); + return vec3(x, y, z); +} + /** * @private */ diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index be5d1caa735c..3b9ce85eee04 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -11,15 +11,6 @@ varying vec4 v_color; uniform float u_morphTime; -vec3 sphericalToCartesian(vec2 latLon) -{ - float sinTheta = sin(latLon.x); - float x = sinTheta * cos(latLon.y); - float y = sinTheta * sin(latLon.y); - float z = cos(latLon.x); - return vec3(x, y, z); -} - void main() { float texCoord = misc.x; @@ -34,23 +25,29 @@ void main() if (u_morphTime == 1.0) { p = vec4(czm_translateRelativeToEye(position3DHigh, position3DLow), 1.0); - prevDir = vec4(sphericalToCartesian(prev.xy), 0.0); - nextDir = vec4(sphericalToCartesian(next.xy), 0.0); + prevDir = vec4(czm_sphericalToCartesianCoordinates(prev.xy), 0.0); + nextDir = vec4(czm_sphericalToCartesianCoordinates(next.xy), 0.0); } else if (u_morphTime == 0.0) { p = vec4(czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), 1.0); - prevDir = vec4(sphericalToCartesian(prev.zw), 0.0); - nextDir = vec4(sphericalToCartesian(next.zw), 0.0); + prevDir = vec4(czm_sphericalToCartesianCoordinates(prev.zw), 0.0); + nextDir = vec4(czm_sphericalToCartesianCoordinates(next.zw), 0.0); } else { p = czm_columbusViewMorph( - czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), - czm_translateRelativeToEye(position3DHigh, position3DLow), - u_morphTime); - prevDir = czm_columbusViewMorph(sphericalToCartesian(prev.xy), sphericalToCartesian(prev.zw), u_morphTime); - nextDir = czm_columbusViewMorph(sphericalToCartesian(next.xy), sphericalToCartesian(next.zw), u_morphTime); + czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), + czm_translateRelativeToEye(position3DHigh, position3DLow), + u_morphTime); + prevDir = czm_columbusViewMorph( + czm_sphericalToCartesianCoordinates(prev.xy), + czm_sphericalToCartesianCoordinates(prev.zw), + u_morphTime); + nextDir = czm_columbusViewMorph( + czm_sphericalToCartesianCoordinates(next.xy), + czm_sphericalToCartesianCoordinates(next.zw), + u_morphTime); prevDir.w = 0.0; nextDir.w = 0.0; @@ -87,6 +84,11 @@ void main() direction *= width / sin(angle); } + if (direction.x < 0.0) + { + expandDir *= -1.0; + } + positionWC.xy += direction * expandDir; gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); From ad35a7968333b817b48052c23427a8e2fec6f1da Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Feb 2013 16:01:21 -0500 Subject: [PATCH 010/114] Modify polyline vertex position in eye coordinates instead of window coordinates. --- Source/Renderer/ShaderProgram.js | 17 +++++++++ Source/Renderer/UniformState.js | 11 ++++++ Source/Scene/FrameState.js | 7 +++- Source/Scene/OrthographicFrustum.js | 4 +- Source/Scene/PerspectiveOffCenterFrustum.js | 4 +- Source/Scene/Scene.js | 2 + Source/Shaders/PolylineFS.glsl | 2 + Source/Shaders/PolylineVS.glsl | 42 ++++++++------------- 8 files changed, 58 insertions(+), 31 deletions(-) diff --git a/Source/Renderer/ShaderProgram.js b/Source/Renderer/ShaderProgram.js index e3d186b68820..825b38ba3f2e 100644 --- a/Source/Renderer/ShaderProgram.js +++ b/Source/Renderer/ShaderProgram.js @@ -1223,6 +1223,23 @@ define([ } }, + /** + * TODO + */ + czm_pixelSize : { + getSize : function() { + return 1; + }, + + getDatatype : function() { + return UniformDatatype.FLOAT; + }, + + getValue : function(uniformState) { + return uniformState.getPixelSize(); + } + }, + /** * An automatic GLSL uniform representing the normalized direction to the sun in eye coordinates. * This is commonly used for directional lighting computations. diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index 68c03d129f7c..c6a248551b58 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -52,6 +52,7 @@ define([ this._projection = Matrix4.IDENTITY.clone(); this._infiniteProjection = Matrix4.IDENTITY.clone(); this._entireFrustum = new Cartesian2(); + this._pixelSize = 0.0; this._frameNumber = 1.0; this._time = undefined; @@ -237,6 +238,9 @@ define([ setSunAndMoonDirections(this, frameState); + var pixelSize = camera.frustum.getPixelSize(frameState.canvasDimensions); + this._pixelSize = Math.max(pixelSize.x, pixelSize.y); + this._entireFrustum.x = camera.frustum.near; this._entireFrustum.y = camera.frustum.far; this.updateFrustum(camera.frustum); @@ -884,6 +888,13 @@ define([ return this._entireFrustum; }; + /** + * TODO + */ + UniformState.prototype.getPixelSize = function() { + return this._pixelSize; + }; + /** * Returns a normalized vector to the sun in 3D world coordinates at the current scene time. Even in 2D or * Columbus View mode, this returns the position of the sun in the 3D scene. diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js index 3761eb271711..59b3b3cdcbb8 100644 --- a/Source/Scene/FrameState.js +++ b/Source/Scene/FrameState.js @@ -1,5 +1,5 @@ /*global define*/ -define([], function() { +define(['../Core/Cartesian2'], function(Cartesian2) { "use strict"; /** @@ -63,6 +63,11 @@ define([], function() { */ this.occluder = undefined; + /** + * TODO + */ + this.canvasDimensions = new Cartesian2(); + this.passes = { /** * true if the primitive should update for a color pass, false otherwise. diff --git a/Source/Scene/OrthographicFrustum.js b/Source/Scene/OrthographicFrustum.js index c7fb78914fbe..dcf5e7fc7aa6 100644 --- a/Source/Scene/OrthographicFrustum.js +++ b/Source/Scene/OrthographicFrustum.js @@ -289,11 +289,11 @@ define([ var height = canvasDimensions.y; if (width <= 0) { - throw new DeveloperError('canvasDimensions.x must be grater than zero.'); + throw new DeveloperError('canvasDimensions.x must be greater than zero.'); } if (height <= 0) { - throw new DeveloperError('canvasDimensions.y must be grater than zero.'); + throw new DeveloperError('canvasDimensions.y must be greater than zero.'); } var frustumWidth = this.right - this.left; diff --git a/Source/Scene/PerspectiveOffCenterFrustum.js b/Source/Scene/PerspectiveOffCenterFrustum.js index d03212b06acc..7eb988610973 100644 --- a/Source/Scene/PerspectiveOffCenterFrustum.js +++ b/Source/Scene/PerspectiveOffCenterFrustum.js @@ -335,11 +335,11 @@ define([ var height = canvasDimensions.y; if (width <= 0) { - throw new DeveloperError('canvasDimensions.x must be grater than zero.'); + throw new DeveloperError('canvasDimensions.x must be greater than zero.'); } if (height <= 0) { - throw new DeveloperError('canvasDimensions.y must be grater than zero.'); + throw new DeveloperError('canvasDimensions.y must be greater than zero.'); } distance = defaultValue(distance, this.near); diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 83244bb5ca54..b92ee7ad91c5 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -253,6 +253,8 @@ define([ frameState.camera = camera; frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.getPositionWC(), camera.getDirectionWC(), camera.getUpWC()); frameState.occluder = undefined; + frameState.canvasDimensions.x = scene._canvas.clientWidth; + frameState.canvasDimensions.y = scene._canvas.clientHeight; // TODO: The occluder is the top-level central body. When we add // support for multiple central bodies, this should be the closest one. diff --git a/Source/Shaders/PolylineFS.glsl b/Source/Shaders/PolylineFS.glsl index e436318bc6cd..ee6b734ed5a8 100644 --- a/Source/Shaders/PolylineFS.glsl +++ b/Source/Shaders/PolylineFS.glsl @@ -1,4 +1,6 @@ varying vec4 v_color; +varying vec4 v_outlineColor; +varying float v_textureCoordinate; void main() { diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 3b9ce85eee04..5bfaca2dc82a 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -8,6 +8,8 @@ attribute vec4 color; attribute vec4 misc; varying vec4 v_color; +varying vec4 v_outlineColor; +varying float v_textureCoordinate; uniform float u_morphTime; @@ -54,44 +56,32 @@ void main() } vec4 positionEC = czm_modelViewRelativeToEye * p; - vec4 positionWC = czm_eyeToWindowCoordinates(positionEC); - vec4 prevEC = czm_modelView * prevDir; vec4 nextEC = czm_modelView * nextDir; - vec4 prevWC = czm_eyeToWindowCoordinates(vec4(prevEC.xyz + positionEC.xyz, 1.0)); - prevWC.xy = normalize(prevWC.xy - positionWC.xy); - vec4 nextWC = czm_eyeToWindowCoordinates(vec4(nextEC.xyz + positionEC.xyz, 1.0)); - nextWC.xy = normalize(nextWC.xy - positionWC.xy); - - float angle = acos(dot(prevWC.xy, nextWC.xy)) * 0.5; + vec3 direction = (prevEC.xyz + nextEC.xyz) * 0.5; + direction.z = 0.0; + direction = normalize(direction); - vec2 direction; - if (abs(angle - czm_piOverTwo) < czm_epsilon3) - { - mat2 rotation = mat2(cos(czm_piOverTwo), sin(czm_piOverTwo), -sin(czm_piOverTwo), cos(czm_piOverTwo)); - direction = rotation * nextWC.xy; - direction *= width; - } - else if (abs(angle) < czm_epsilon3) - { - direction = normalize((prevWC.xy + nextWC.xy) * 0.5); - direction *= width; - } - else + if (direction.x < 0.0) { - direction = normalize((prevWC.xy + nextWC.xy) * 0.5); - direction *= width / sin(angle); + expandDir *= -1.0; } - if (direction.x < 0.0) + float angle = acos(dot(direction, nextEC.xyz)); + if (abs(angle - czm_piOverTwo) > czm_epsilon1) { - expandDir *= -1.0; + width = width / sin(angle); } - positionWC.xy += direction * expandDir; + float pixelSize = czm_pixelSize * abs(positionEC.z); + direction = direction * expandDir * width * pixelSize; + + vec4 positionWC = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + direction, 1.0)); gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); v_color = color; + v_outlineColor = color; // TODO; + v_textureCoordinate = texCoord; } From 3fc3ce6ca4a1d77cc40a2cc460c2827667cc40e3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Feb 2013 17:02:24 -0500 Subject: [PATCH 011/114] Add doc. Fix/add tests. --- Apps/Sandcastle/gallery/Polylines.html | 5 ++-- Source/Renderer/ShaderProgram.js | 17 +++++++++++- Source/Renderer/UniformState.js | 8 +++++- Source/Scene/FrameState.js | 3 ++- Source/Shaders/BuiltinFunctions.glsl | 27 ++++++++++++++----- .../DynamicScene/DynamicPathVisualizerSpec.js | 2 -- .../DynamicPolylineVisualizerSpec.js | 2 -- Specs/Renderer/AutomaticUniformSpec.js | 13 +++++++++ Specs/Renderer/BuiltinFunctionsSpec.js | 27 +++++++++++++++++++ Specs/createFrameState.js | 2 ++ 10 files changed, 90 insertions(+), 16 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index d025529095dc..3d1b8804c46f 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -63,8 +63,7 @@ alpha : 0.75 }); - // Set a polyline's width and outline width - // (Note that wide lines don't work with ANGLE enabled) + // Set a polyline's width var widePolyline = polylines.add(); Sandcastle.declare(widePolyline); // For highlighting on mouseover in Sandcastle. widePolyline.setPositions(ellipsoid.cartographicArrayToCartesianArray([ @@ -73,7 +72,7 @@ Cesium.Cartographic.fromDegrees(-105.0, 35.0), Cesium.Cartographic.fromDegrees(-100.0, 32.0) ])); - widePolyline.setWidth(10); + widePolyline.setWidth(5); widePolyline.setOutlineColor({ red : 1.0, green : 0.0, diff --git a/Source/Renderer/ShaderProgram.js b/Source/Renderer/ShaderProgram.js index 825b38ba3f2e..c2d2ef262043 100644 --- a/Source/Renderer/ShaderProgram.js +++ b/Source/Renderer/ShaderProgram.js @@ -1224,7 +1224,22 @@ define([ }, /** - * TODO + * An automatic GLSL uniform representing the size of a pixel in meters at a distance of one meter + * from the camera. The pixel size is linearly proportional to the distance from the camera. + *

+ * Like all automatic uniforms, czm_pixelSize does not need to be explicitly declared. + * However, it can be explicitly declared when a shader is also used by other applications such + * as a third-party authoring tool. + * + * @alias czm_pixelSize + * @glslUniform + * + * @example + * // GLSL declaration + * uniform float czm_pixelSize; + * + * // Example: the pixel size at a position in eye coordinates + * float pixelSize = czm_pixelSize * positionEC.z; */ czm_pixelSize : { getSize : function() { diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index c6a248551b58..ebbecf7bff7d 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -889,7 +889,13 @@ define([ }; /** - * TODO + * Returns the size of a pixel in meters at a distance of one meter from the camera. + * + * @memberof UniformState + * + * @return {Number} Returns the size of a pixel in meters at a distance of one meter from the camera. + * + * @see czm_pixelSize */ UniformState.prototype.getPixelSize = function() { return this._pixelSize; diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js index 59b3b3cdcbb8..45b7fa44bd4b 100644 --- a/Source/Scene/FrameState.js +++ b/Source/Scene/FrameState.js @@ -64,7 +64,8 @@ define(['../Core/Cartesian2'], function(Cartesian2) { this.occluder = undefined; /** - * TODO + * The dimensions of the canvas. + * @type {Cartesian2} */ this.canvasDimensions = new Cartesian2(); diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index ddbdf823ecdd..dde4976c8fc0 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -936,14 +936,29 @@ vec3 czm_translateRelativeToEye(vec3 high, vec3 low) } /** - * TODO + * Converts from spherical coordinates to cartesian coordinates. + * + * @name czm_sphericalToCartesianCoordinates + * @glslFunction + * + * @param {vec2} spherical The spherical coordinates. The x property is the angle in + * the xy-plane from the positive x-axis. The y property is the angle from the positive z-axis. + * @returns {vec3} The cartesian coordinates + * + * @example + * // normal in spherical coordinates to cartesian coordinates + * vec3 normal = normalize(czm_sphericalToCartesianCoordinates(normalSpherical)); + * + * // position in spherical coordinates to cartesian coordinates + * vec3 position = normalize(czm_sphericalToCartesianCoordinates(positionSpherical)); + * position *= radius; */ -vec3 czm_sphericalToCartesianCoordinates(vec2 latLon) +vec3 czm_sphericalToCartesianCoordinates(vec2 spherical) { - float sinTheta = sin(latLon.x); - float x = sinTheta * cos(latLon.y); - float y = sinTheta * sin(latLon.y); - float z = cos(latLon.x); + float sinTheta = sin(spherical.x); + float x = sinTheta * cos(spherical.y); + float y = sinTheta * sin(spherical.y); + float z = cos(spherical.x); return vec3(x, y, z); } diff --git a/Specs/DynamicScene/DynamicPathVisualizerSpec.js b/Specs/DynamicScene/DynamicPathVisualizerSpec.js index f35882c76c0c..200641c4ef96 100644 --- a/Specs/DynamicScene/DynamicPathVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPathVisualizerSpec.js @@ -132,7 +132,6 @@ defineSuite([ expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); expect(primitive.getColor()).toEqual(testObject.path.color.getValue(time)); expect(primitive.getOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); - expect(primitive.getOutlineWidth()).toEqual(testObject.path.outlineWidth.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); testObject.position = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); @@ -146,7 +145,6 @@ defineSuite([ expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); expect(primitive.getColor()).toEqual(testObject.path.color.getValue(time)); expect(primitive.getOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); - expect(primitive.getOutlineWidth()).toEqual(testObject.path.outlineWidth.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); path.show = new MockProperty(false); diff --git a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js index c9244f990522..85550fd0b074 100644 --- a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js @@ -133,7 +133,6 @@ defineSuite([ expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); expect(primitive.getColor()).toEqual(testObject.polyline.color.getValue(time)); expect(primitive.getOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); - expect(primitive.getOutlineWidth()).toEqual(testObject.polyline.outlineWidth.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); testObject.vertexPositions = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); @@ -147,7 +146,6 @@ defineSuite([ expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); expect(primitive.getColor()).toEqual(testObject.polyline.color.getValue(time)); expect(primitive.getOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); - expect(primitive.getOutlineWidth()).toEqual(testObject.polyline.outlineWidth.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); polyline.show = new MockProperty(false); diff --git a/Specs/Renderer/AutomaticUniformSpec.js b/Specs/Renderer/AutomaticUniformSpec.js index d9c1186a8ed6..806f2f036abf 100644 --- a/Specs/Renderer/AutomaticUniformSpec.js +++ b/Specs/Renderer/AutomaticUniformSpec.js @@ -3,6 +3,7 @@ defineSuite([ 'Specs/createContext', 'Specs/destroyContext', 'Specs/createFrameState', + 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Matrix4', 'Core/PrimitiveType', @@ -12,6 +13,7 @@ defineSuite([ createContext, destroyContext, createFrameState, + Cartesian2, Cartesian3, Matrix4, PrimitiveType, @@ -50,6 +52,9 @@ defineSuite([ }, computeCullingVolume : function() { return undefined; + }, + getPixelSize : function() { + return new Cartesian2(1.0, 0.1); } }, position : defaultValue(position, Cartesian3.ZERO.clone()), @@ -681,6 +686,14 @@ defineSuite([ verifyDraw(fs); }); + it('has czm_pixelSize', function() { + var us = context.getUniformState(); + us.update(createFrameState(createMockCamera())); + + var fs = 'void main() { gl_FragColor = vec4(czm_pixelSize == 1.0); }'; + verifyDraw(fs); + }); + it('has czm_sunDirectionEC', function() { var us = context.getUniformState(); us.update(createFrameState(createMockCamera())); diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index e88390108f97..00dd9d0911f0 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -8,6 +8,7 @@ defineSuite([ 'Core/Math', 'Core/Matrix4', 'Core/PrimitiveType', + 'Core/Cartesian2', 'Core/Cartesian3', 'Core/EncodedCartesian3', 'Renderer/BufferUsage' @@ -20,6 +21,7 @@ defineSuite([ CesiumMath, Matrix4, PrimitiveType, + Cartesian2, Cartesian3, EncodedCartesian3, BufferUsage) { @@ -173,4 +175,29 @@ defineSuite([ verifyDraw(fs, uniformMap); }); + + it('has czm_sphericalToCartesianCoordinates', function() { + var normal = new Cartesian3(1.0, 1.0, 1.0).normalize(); + var latLon = new Cartesian2(Math.acos(normal.z), Math.atan2(normal.y, normal.x)); + + var uniformMap = { + u_latLon : function() { + return latLon; + }, + u_normal : function() { + return normal; + } + }; + + var fs = + 'uniform vec2 u_latLon;' + + 'uniform vec3 u_normal;' + + 'void main() {' + + ' vec3 cartesian = czm_sphericalToCartesianCoordinates(u_latLon);' + + ' vec3 diff = abs(u_normal - cartesian);' + + ' gl_FragColor = vec4(all(lessThan(diff, vec3(czm_epsilon6))));' + + '}'; + + verifyDraw(fs, uniformMap); + }); }, 'WebGL'); \ No newline at end of file diff --git a/Specs/createFrameState.js b/Specs/createFrameState.js index 4c9a5253d80e..71cedbc82a4f 100644 --- a/Specs/createFrameState.js +++ b/Specs/createFrameState.js @@ -36,6 +36,8 @@ define([ })); frameState.camera = camera; frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.position, camera.direction, camera.up); + frameState.canvasDimensions.x = 1.0; + frameState.canvasDimensions.y = 1.0; frameState.passes.color = true; frameState.passes.overlay = true; From e4fa590007088cbda41c8c8efeb968b47800dd8c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Feb 2013 20:13:19 -0500 Subject: [PATCH 012/114] Start adding encoded colors to polylines. There is still an issue with color components of 1.0, but not less than 1.0. --- Source/Core/Color.js | 18 ++++++++++++ Source/Scene/PolylineCollection.js | 46 ++++++++++++++---------------- Source/Shaders/PolylineFS.glsl | 3 ++ Source/Shaders/PolylineVS.glsl | 21 ++++++++++++-- 4 files changed, 62 insertions(+), 26 deletions(-) diff --git a/Source/Core/Color.js b/Source/Core/Color.js index eb455fc0e8a9..fb17c228d3c1 100644 --- a/Source/Core/Color.js +++ b/Source/Core/Color.js @@ -2,10 +2,12 @@ define([ './defaultValue', './freezeObject', + './Cartesian4', './DeveloperError' ], function( defaultValue, freezeObject, + Cartesian4, DeveloperError) { "use strict"; @@ -211,6 +213,22 @@ define([ return number === 1.0 ? 255.0 : (number * 256.0) | 0; }; + var scale = new Cartesian4(1.0, 1.0 / Math.pow(2, 8), 1.0 / Math.pow(2, 16), 1.0 / Math.pow(2, 24)); + var scratch = new Cartesian4(); + + /** + * TODO + * @param color + * @returns + */ + Color.encode = function(color) { + scratch.x = Color.floatToByte(color.red); + scratch.y = Color.floatToByte(color.green); + scratch.z = Color.floatToByte(color.blue); + scratch.w = Color.floatToByte(color.alpha); + return Cartesian4.dot(scratch, scale); + }; + /** * Duplicates a Color. * @memberof Color diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index df21a9845d29..963f10c916e3 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -656,7 +656,7 @@ define([ if (totalLength > 0) { var positionArray = new Float32Array(2 * totalLength * 3 * 2); var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); - var colorArray = new Uint8Array(totalLength * 4 * 2); + var colorArray = new Float32Array(totalLength * 3 * 2); var miscArray = new Float32Array(totalLength * 4 * 2); var position3DArray; @@ -677,7 +677,7 @@ define([ var bucketLength = bucket.lengthOfPositions; positionIndex += 2 * bucketLength * 3 * 2; adjacencyIndex += 2 * bucketLength * 4 * 2; - colorIndex += bucketLength * 4 * 2; + colorIndex += bucketLength * 3 * 2; miscIndex += bucketLength * 4 * 2; offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); } @@ -690,7 +690,7 @@ define([ this._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, this._buffersUsage[POSITION_INDEX].bufferUsage); this._colorBuffer = context.createVertexBuffer(colorArray, this._buffersUsage[COLOR_INDEX].bufferUsage); this._miscBuffer = context.createVertexBuffer(miscArray, this._buffersUsage[MISC_INDEX].bufferUsage); - var colorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; + var colorSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var miscSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; @@ -749,9 +749,8 @@ define([ strideInBytes : 2 * adjacencySizeInBytes }, { index : attributeIndices.color, - componentsPerAttribute : 4, - normalize : true, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, vertexBuffer : this._colorBuffer, offsetInBytes : vertexColorBufferOffset }, { @@ -958,10 +957,11 @@ define([ var length = polylines.length; for ( var i = 0; i < length; ++i) { var polyline = polylines[i]; - var color = polyline.getColor(); var width = polyline.getWidth(); var show = polyline.getShow(); - //var pickColor = polyline.getPickId(context).unnormalizedRgb; + var color = polyline.getColor(); + var outlineColor = polyline.getOutlineColor(); + //var pickColor = polyline.getPickId(context).normalizedRgb; var positions = this._getPositions(polyline); var positionsLength = positions.length; for ( var j = 0; j < positionsLength; ++j) { @@ -987,10 +987,10 @@ define([ adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; } - colorArray[colorIndex] = Color.floatToByte(color.red); - colorArray[colorIndex + 1] = Color.floatToByte(color.green); - colorArray[colorIndex + 2] = Color.floatToByte(color.blue); - colorArray[colorIndex + 3] = Color.floatToByte(color.alpha); + colorArray[colorIndex] = Color.encode(color); + colorArray[colorIndex + 1] = Color.encode(outlineColor); + //colorArray[colorIndex + 2] = Color.encode(pickColor); + colorArray[colorIndex + 2] = 0.0; miscArray[miscIndex] = j / positionsLength; // s tex coord miscArray[miscIndex + 1] = 2 * k - 1; // expand direction @@ -999,7 +999,7 @@ define([ positionIndex += 6; adjacencyIndex += 8; - colorIndex += 4; + colorIndex += 3; miscIndex += 4; } } @@ -1374,19 +1374,17 @@ define([ var index = 0; var color = polyline.getColor(); - var red = Color.floatToByte(color.red); - var green = Color.floatToByte(color.green); - var blue = Color.floatToByte(color.blue); - var alpha = Color.floatToByte(color.alpha); - var colorsArray = new Uint8Array(4 * positionsLength * 2); + var outlineColor = polyline.getOutlineColor(); + //var pickColor = polyline.getPickId(context).normalizedRgb; + var colorsArray = new Float32Array(3 * positionsLength * 2); for ( var j = 0; j < positionsLength * 2; ++j) { - colorsArray[index] = red; - colorsArray[index + 1] = green; - colorsArray[index + 2] = blue; - colorsArray[index + 3] = alpha; - index += 4; + colorsArray[index] = Color.encode(color); + colorsArray[index + 1] = Color.encode(outlineColor); + //colorsArray[index + 2] = Color.encode(pickColor); + colorsArray[index + 2] = 0.0; + index += 3; } - buffer.copyFromArrayView(colorsArray, 4 * positionIndex * 2); + buffer.copyFromArrayView(colorsArray, 3 * positionIndex * 2); } }; diff --git a/Source/Shaders/PolylineFS.glsl b/Source/Shaders/PolylineFS.glsl index ee6b734ed5a8..3ac46df8174a 100644 --- a/Source/Shaders/PolylineFS.glsl +++ b/Source/Shaders/PolylineFS.glsl @@ -2,7 +2,10 @@ varying vec4 v_color; varying vec4 v_outlineColor; varying float v_textureCoordinate; +varying vec4 v_pickColor; + void main() { gl_FragColor = v_color; + //gl_FragColor = v_outlineColor; } \ No newline at end of file diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 5bfaca2dc82a..2ad58242bf2d 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -11,8 +11,24 @@ varying vec4 v_color; varying vec4 v_outlineColor; varying float v_textureCoordinate; +varying vec4 v_pickColor; + uniform float u_morphTime; +vec4 czm_decodeColor(float encoded) +{ + const float bias = -0.55 / 255.0; + const vec4 scale = vec4(1.0, 256.0, 65536.0, 16777216.0); + vec4 decoded = scale * encoded; + float r = floor(decoded.x) / 255.0; + float g = fract(decoded.x) + bias; + float b = fract(decoded.y) + bias; + //float a = fract(decoded.z) + bias; + float a = 1.0; + + return vec4(r, g, b, a); +} + void main() { float texCoord = misc.x; @@ -81,7 +97,8 @@ void main() gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); - v_color = color; - v_outlineColor = color; // TODO; v_textureCoordinate = texCoord; + v_color = czm_decodeColor(color.x); + v_outlineColor = czm_decodeColor(color.y); + v_pickColor = czm_decodeColor(color.z); } From b63067b2d67e1445dd8fb8c5b09534c36af44e44 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Feb 2013 14:55:53 -0500 Subject: [PATCH 013/114] A 32 bit floating point can only encode the 8 bits for the red, green, and blue components. Add doc and tests. --- Source/Core/Color.js | 26 +++++++++++++++--------- Source/Shaders/BuiltinFunctions.glsl | 28 ++++++++++++++++++++++++++ Source/Shaders/PolylineVS.glsl | 20 +++--------------- Specs/Core/ColorSpec.js | 14 +++++++++++++ Specs/Renderer/BuiltinFunctionsSpec.js | 27 +++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 26 deletions(-) diff --git a/Source/Core/Color.js b/Source/Core/Color.js index fb17c228d3c1..28d8b1b2fc64 100644 --- a/Source/Core/Color.js +++ b/Source/Core/Color.js @@ -2,12 +2,12 @@ define([ './defaultValue', './freezeObject', - './Cartesian4', + './Cartesian3', './DeveloperError' ], function( defaultValue, freezeObject, - Cartesian4, + Cartesian3, DeveloperError) { "use strict"; @@ -213,20 +213,28 @@ define([ return number === 1.0 ? 255.0 : (number * 256.0) | 0; }; - var scale = new Cartesian4(1.0, 1.0 / Math.pow(2, 8), 1.0 / Math.pow(2, 16), 1.0 / Math.pow(2, 24)); - var scratch = new Cartesian4(); + var scale = new Cartesian3(1.0, 1.0 / Math.pow(2, 8), 1.0 / Math.pow(2, 16)); + var scratch = new Cartesian3(); /** - * TODO - * @param color - * @returns + * Encodes the red, green, and blue components of a color into a 32 bit floating point number. + * + * @param {Color} color The color to be encoded. + * @returns {Number} A floating point number representing the encoded red, green, and blue values of the color. + * + * @exception {DeveloperError} color is required. + * + * @see czm_decodeColor */ Color.encode = function(color) { + if (typeof color === 'undefined') { + throw new DeveloperError('color is required.'); + } + scratch.x = Color.floatToByte(color.red); scratch.y = Color.floatToByte(color.green); scratch.z = Color.floatToByte(color.blue); - scratch.w = Color.floatToByte(color.alpha); - return Cartesian4.dot(scratch, scale); + return Cartesian3.dot(scratch, scale); }; /** diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index dde4976c8fc0..feb380d650bf 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -548,6 +548,34 @@ vec3 czm_multiplyWithColorBalance(vec3 left, vec3 right) return ((leftLuminance + rightLuminance) / (2.0 * targetLuminance)) * target; } +/** + * Unpacks an encoded color from a floating point number to an RGB vector. + * + * @name czm_decodeColor + * @glslFunction + * + * @param {float} The encoded color. + * + * @returns {vec3} The decoded color. + * + * @example + * attribute float encodedColor; + * //... + * varying vec4 v_color; + * //... + * v_color = vec4(czm_decodeColor(encodedColor), 1.0); + */ +vec3 czm_decodeColor(float encoded) +{ + const vec3 scale = vec3(1.0, 256.0, 65536.0); + vec3 decoded = scale * encoded; + float r = floor(decoded.r) / 256.0; + float g = fract(decoded.r); + float b = fract(decoded.g); + + return vec3(r, g, b); +} + /////////////////////////////////////////////////////////////////////////////// /** diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 2ad58242bf2d..3a9531598d8e 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -15,20 +15,6 @@ varying vec4 v_pickColor; uniform float u_morphTime; -vec4 czm_decodeColor(float encoded) -{ - const float bias = -0.55 / 255.0; - const vec4 scale = vec4(1.0, 256.0, 65536.0, 16777216.0); - vec4 decoded = scale * encoded; - float r = floor(decoded.x) / 255.0; - float g = fract(decoded.x) + bias; - float b = fract(decoded.y) + bias; - //float a = fract(decoded.z) + bias; - float a = 1.0; - - return vec4(r, g, b, a); -} - void main() { float texCoord = misc.x; @@ -98,7 +84,7 @@ void main() gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); v_textureCoordinate = texCoord; - v_color = czm_decodeColor(color.x); - v_outlineColor = czm_decodeColor(color.y); - v_pickColor = czm_decodeColor(color.z); + v_color = vec4(czm_decodeColor(color.x), 1.0); + v_outlineColor = vec4(czm_decodeColor(color.y), 1.0); + v_pickColor = vec4(czm_decodeColor(color.z), 1.0); } diff --git a/Specs/Core/ColorSpec.js b/Specs/Core/ColorSpec.js index 753d99135673..783224d3852a 100644 --- a/Specs/Core/ColorSpec.js +++ b/Specs/Core/ColorSpec.js @@ -61,6 +61,20 @@ defineSuite(['Core/Color', expect(Color.floatToByte(127 / 255)).toEqual(127); }); + it('encodes a color', function() { + var color = new Color(0.75, 0.5, 0.25); + var encoded = Color.encode(color); + + var red = Math.floor(encoded) / 256.0; + var green = encoded - Math.floor(encoded); + var blue = encoded * 256.0; + blue = blue - Math.floor(blue); + + expect(red).toEqualEpsilon(color.red, CesiumMath.EPSILON3); + expect(green).toEqualEpsilon(color.green, CesiumMath.EPSILON3); + expect(blue).toEqualEpsilon(color.blue, CesiumMath.EPSILON3); + }); + it('clone with no parameters returns a new identical copy.', function() { var v = new Color(0.1, 0.2, 0.3, 0.4); var v2 = v.clone(); diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index 00dd9d0911f0..fa95865f5ddf 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -5,6 +5,7 @@ defineSuite([ 'Specs/createCamera', 'Specs/createFrameState', 'Core/BoundingRectangle', + 'Core/Color', 'Core/Math', 'Core/Matrix4', 'Core/PrimitiveType', @@ -18,6 +19,7 @@ defineSuite([ createCamera, createFrameState, BoundingRectangle, + Color, CesiumMath, Matrix4, PrimitiveType, @@ -200,4 +202,29 @@ defineSuite([ verifyDraw(fs, uniformMap); }); + + it('has czm_decodeColor', function() { + var color = new Color(0.75, 0.5, 0.25, 1.0); + var encoded = Color.encode(color); + + var uniformMap = { + u_encoded : function() { + return encoded; + }, + u_color : function() { + return color; + } + }; + + var fs = + 'uniform float u_encoded;' + + 'uniform vec4 u_color;' + + 'void main() {' + + ' vec3 color = czm_decodeColor(u_encoded);' + + ' vec3 diff = abs(color - u_color.rgb);' + + ' gl_FragColor = vec4(all(lessThan(diff, vec3(czm_epsilon3))));' + + '}'; + + verifyDraw(fs, uniformMap); + }); }, 'WebGL'); \ No newline at end of file From 959ae9f6300dbe54c0e5d91a894d294581780496 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Feb 2013 15:11:36 -0500 Subject: [PATCH 014/114] Encode polyline color alphas separately. --- Source/Scene/PolylineCollection.js | 30 ++++++++++++++++++++++-------- Source/Shaders/PolylineVS.glsl | 8 +++++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 963f10c916e3..4b51df626946 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -656,7 +656,7 @@ define([ if (totalLength > 0) { var positionArray = new Float32Array(2 * totalLength * 3 * 2); var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); - var colorArray = new Float32Array(totalLength * 3 * 2); + var colorArray = new Float32Array(totalLength * 4 * 2); var miscArray = new Float32Array(totalLength * 4 * 2); var position3DArray; @@ -677,7 +677,7 @@ define([ var bucketLength = bucket.lengthOfPositions; positionIndex += 2 * bucketLength * 3 * 2; adjacencyIndex += 2 * bucketLength * 4 * 2; - colorIndex += bucketLength * 3 * 2; + colorIndex += bucketLength * 4 * 2; miscIndex += bucketLength * 4 * 2; offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); } @@ -690,7 +690,7 @@ define([ this._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, this._buffersUsage[POSITION_INDEX].bufferUsage); this._colorBuffer = context.createVertexBuffer(colorArray, this._buffersUsage[COLOR_INDEX].bufferUsage); this._miscBuffer = context.createVertexBuffer(miscArray, this._buffersUsage[MISC_INDEX].bufferUsage); - var colorSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; + var colorSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var miscSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; @@ -749,7 +749,7 @@ define([ strideInBytes : 2 * adjacencySizeInBytes }, { index : attributeIndices.color, - componentsPerAttribute : 3, + componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, vertexBuffer : this._colorBuffer, offsetInBytes : vertexColorBufferOffset @@ -948,6 +948,7 @@ define([ var scratchWritePosition = new Cartesian3(); var scratchAdjacency = new Cartesian4(); + var scratchColor = new Color(); /** * @private @@ -987,10 +988,15 @@ define([ adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; } + scratchColor.red = color.alpha; + scratchColor.green = outlineColor.alpha; + //scratchColor.blue = pickColor.alpha; + colorArray[colorIndex] = Color.encode(color); colorArray[colorIndex + 1] = Color.encode(outlineColor); //colorArray[colorIndex + 2] = Color.encode(pickColor); colorArray[colorIndex + 2] = 0.0; + colorArray[colorIndex + 3] = Color.encode(scratchColor); miscArray[miscIndex] = j / positionsLength; // s tex coord miscArray[miscIndex + 1] = 2 * k - 1; // expand direction @@ -999,7 +1005,7 @@ define([ positionIndex += 6; adjacencyIndex += 8; - colorIndex += 3; + colorIndex += 4; miscIndex += 4; } } @@ -1364,6 +1370,8 @@ define([ } }; + var scratchColorAlpha = new Color(); + /** * @private */ @@ -1376,15 +1384,21 @@ define([ var color = polyline.getColor(); var outlineColor = polyline.getOutlineColor(); //var pickColor = polyline.getPickId(context).normalizedRgb; - var colorsArray = new Float32Array(3 * positionsLength * 2); + var colorsArray = new Float32Array(4 * positionsLength * 2); for ( var j = 0; j < positionsLength * 2; ++j) { + scratchColorAlpha.red = color.alpha; + scratchColorAlpha.green = outlineColor.alpha; + //scratchColorAlpha.blue = pickColor.alpha; + colorsArray[index] = Color.encode(color); colorsArray[index + 1] = Color.encode(outlineColor); //colorsArray[index + 2] = Color.encode(pickColor); colorsArray[index + 2] = 0.0; - index += 3; + colorsArray[index + 3] = Color.encode(scratchColorAlpha); + + index += 4; } - buffer.copyFromArrayView(colorsArray, 3 * positionIndex * 2); + buffer.copyFromArrayView(colorsArray, 4 * positionIndex * 2); } }; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 3a9531598d8e..cec3a261433e 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -84,7 +84,9 @@ void main() gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); v_textureCoordinate = texCoord; - v_color = vec4(czm_decodeColor(color.x), 1.0); - v_outlineColor = vec4(czm_decodeColor(color.y), 1.0); - v_pickColor = vec4(czm_decodeColor(color.z), 1.0); + + vec3 alphas = czm_decodeColor(color.a); + v_color = vec4(czm_decodeColor(color.r), alphas.r); + v_outlineColor = vec4(czm_decodeColor(color.g), alphas.g); + v_pickColor = vec4(czm_decodeColor(color.b), alphas.b); } From c9105e6fb0930a662cf5ca147dcf6eb17c682a9d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Feb 2013 15:34:53 -0500 Subject: [PATCH 015/114] Add another Color test. --- Specs/Core/ColorSpec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Specs/Core/ColorSpec.js b/Specs/Core/ColorSpec.js index 783224d3852a..44aa1a6bb67c 100644 --- a/Specs/Core/ColorSpec.js +++ b/Specs/Core/ColorSpec.js @@ -75,6 +75,12 @@ defineSuite(['Core/Color', expect(blue).toEqualEpsilon(color.blue, CesiumMath.EPSILON3); }); + it('encode throws without a color', function() { + expect(function() { + return Color.encode(); + }).toThrow(); + }); + it('clone with no parameters returns a new identical copy.', function() { var v = new Color(0.1, 0.2, 0.3, 0.4); var v2 = v.clone(); From 6c090ee39df7d58b97ae27dd860f6678d74e033d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Feb 2013 16:38:57 -0500 Subject: [PATCH 016/114] Add per-vertex color and outline color to polylines. --- Apps/Sandcastle/gallery/Polylines.html | 4 +- Source/Scene/Polyline.js | 151 ++++++++++++++++++++++--- Source/Scene/PolylineCollection.js | 88 +++++++++++--- 3 files changed, 205 insertions(+), 38 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index 3d1b8804c46f..fb482d6d65ff 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -56,7 +56,7 @@ Cesium.Cartographic.fromDegrees(-95.0, 30.0), Cesium.Cartographic.fromDegrees(-85.0, 40.0) ])); - coloredPolyline.setColor({ + coloredPolyline.setDefaultColor({ red : 1.0, green : 1.0, blue : 0.0, @@ -73,7 +73,7 @@ Cesium.Cartographic.fromDegrees(-100.0, 32.0) ])); widePolyline.setWidth(5); - widePolyline.setOutlineColor({ + widePolyline.setDefaultOutlineColor({ red : 1.0, green : 0.0, blue : 0.0, diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 996604e25940..001f88b4d382 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -32,6 +32,8 @@ define([ this._width = defaultValue(description.width, 1.0); this._color = Color.clone(defaultValue(description.color, Color.WHITE)); this._outlineColor = Color.clone(defaultValue(description.outlineColor, Color.WHITE)); + this._perVertexColors = undefined; + this._perVertexOutlineColors = undefined; var positions = description.positions; if (typeof positions === 'undefined') { @@ -109,6 +111,8 @@ define([ * * @memberof Polyline * + * @return {Array} The polyline's positions. + * * @see Polyline#setPositions */ Polyline.prototype.getPositions = function() { @@ -151,30 +155,36 @@ define([ }; /** - * Returns the color of the polyline. + * Returns the default color of the polyline. This color is used if per-vertex + * colors are not defined. * * @memberof Polyline * - * @return {Color} The color of the polyline. + * @return {Color} The default color of the polyline. * - * @see Polyline#setColor + * @see Polyline#setDefaultColor + * @see Polyline#getColors + * @see Polyline#setColors */ - Polyline.prototype.getColor = function() { + Polyline.prototype.getDefaultColor = function() { return this._color; }; /** - * Sets the color of the polyline. + * Sets the default color of the polyline. This color is used if per-vertex + * colors are not defined. * * @memberof Polyline * - * @param {Color} value The color of the polyline. + * @param {Color} value The default color of the polyline. * * @exception {DeveloperError} value is required. * - * @see Polyline#getColor + * @see Polyline#getDefaultColor + * @see Polyline#getColors + * @see Polyline#setColors */ - Polyline.prototype.setColor = function(value) { + Polyline.prototype.setDefaultColor = function(value) { if (typeof value === 'undefined') { throw new DeveloperError('value is required.'); } @@ -186,6 +196,46 @@ define([ } }; + /** + * Returns the polyline's color at each position. + * + * @return {Array} The polyline's color at each position. + * + * @see Polyline#setColors + * @see Polyline#getDefaultColor + * @see Polyline#SetDefaultColor + */ + Polyline.prototype.getColors = function() { + return this._perVertexColors; + }; + + /** + * Defines the color of the polyline at each position. + * + * @memberof Polyline + * + * @param {Array} colors The colors of the polyline at each position. + * + * @exception {DeveloperError} colors is required. + * @exception {DeveloperError} colors must have the same number of elements as the positions. + * + * @see Polyline#getColors + * @see Polyline#getDefaultColor + * @see Polyline#SetDefaultColor + */ + Polyline.prototype.setColors = function(colors) { + if (typeof colors === 'undefined') { + throw new DeveloperError('colors is required.'); + } + + if (typeof colors.length === 'undefined' || colors.length !== this._positions.length) { + throw new DeveloperError('colors must have the same number of elements as the positions.'); + } + + this._perVertexColors = colors; + makeDirty(this, COLOR_INDEX); + }; + /** * Gets the width of the polyline. * The actual width used is clamped to the minimum and maximum width supported by @@ -241,30 +291,36 @@ define([ }; /** - * Gets the outline color of the polyline. + * Gets the default outline color of the polyline. This color is used if per-vertex + * outline colors are not defined. * * @memberof Polyline * - * @return {Color} The outline color of the polyline. + * @return {Color} The default outline color of the polyline. * - * @see Polyline#setOutlineColor + * @see Polyline#setDefaultOutlineColor + * @see Polyline#getOutlineColors + * @see Polyline#setOutlineColors */ - Polyline.prototype.getOutlineColor = function() { + Polyline.prototype.getDefaultOutlineColor = function() { return this._outlineColor; }; /** - * Sets the outline color of the polyline. + * Sets the default outline color of the polyline. This color is used if per-vertex + * outline colors are not defined. * * @memberof Polyline * - * @param {Color} value The outline color of the polyline. + * @param {Color} value The default outline color of the polyline. * * @exception {DeveloperError} value is required. * - * @see Polyline#getOutlineColor + * @see Polyline#getDefaultOutlineColor + * @see Polyline#getOutlineColors + * @see Polyline#setOutlineColors */ - Polyline.prototype.setOutlineColor = function(value) { + Polyline.prototype.setDefaultOutlineColor = function(value) { if (typeof value === 'undefined') { throw new DeveloperError('value is required.'); } @@ -276,6 +332,46 @@ define([ } }; + /** + * Returns the polyline's outline color at each position. + * + * @return {Array} The polyline's outline color at each position. + * + * @see Polyline#setOutlineColors + * @see Polyline#getDefaultOutlineColor + * @see Polyline#SetDefaultOutlineColor + */ + Polyline.prototype.getOutlineColors = function() { + return this._perVertexOutlineColors; + }; + + /** + * Defines the outline color of the polyline at each position. + * + * @memberof Polyline + * + * @param {Array} colors The outline colors of the polyline at each position. + * + * @exception {DeveloperError} colors is required. + * @exception {DeveloperError} colors must have the same number of elements as the positions. + * + * @see Polyline#getOutlineColors + * @see Polyline#getDefaultOutlineColor + * @see Polyline#SetDefaultOutlineColor + */ + Polyline.prototype.setOutlineColors = function(colors) { + if (typeof colors === 'undefined') { + throw new DeveloperError('colors is required.'); + } + + if (typeof colors.length === 'undefined' || colors.length !== this._positions.length) { + throw new DeveloperError('colors must have the same number of elements as the positions.'); + } + + this._perVertexOutlineColors = colors; + makeDirty(this, COLOR_INDEX); + }; + Polyline.prototype.getPickId = function(context) { this._pickId = this._pickId || context.createPickId(this._pickIdThis || this); return this._pickId; @@ -356,10 +452,11 @@ define([ typeof other !== 'undefined' && this._show === other._show && this._width === other._width && - this._horizontalOrigin === other._horizontalOrigin && cartesian3ArrayEquals(this._positions, other._positions) && Color.equals(this._color, other._color) && - Color.equals(this._outlineColor, other._outlineColor); + Color.equals(this._outlineColor, other._outlineColor) && + colorArrayEquals(this._perVertexColors, this._positions.length, other._perVertexColors, other._positions.length) && + colorArrayEquals(this._perVertexOutlineColors, this._positions.length, other._perVertexOutlineColors, other._positions.length); }; function cartesian3ArrayEquals(a, b) { @@ -374,6 +471,24 @@ define([ return true; } + function colorArrayEquals(a, aPositionsLength, bPositionsLength) { + if (typeof a === 'undefined' && typeof b === 'undefined') { + return true; + } + if (a.length !== aPositionsLength && b.length !== bPositionsLength) { + return true; + } + if (a.length !== b.length) { + return false; + } + for ( var i = 0, len = a.length; i < len; ++i) { + if (!Color.equals(a[i], b[i])) { + return false; + } + } + return true; + } + Polyline.prototype._destroy = function() { this._pickId = this._pickId && this._pickId.destroy(); this._polylineCollection = undefined; diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 4b51df626946..2144331db366 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -947,8 +947,10 @@ define([ } var scratchWritePosition = new Cartesian3(); - var scratchAdjacency = new Cartesian4(); - var scratchColor = new Color(); + var scratchWriteAdjacency = new Cartesian4(); + var scratchWriteColor = new Color(); + var scratchWriteColorArray = new Array(1); + var scratchWriteOutlineColorArray = new Array(1); /** * @private @@ -960,18 +962,38 @@ define([ var polyline = polylines[i]; var width = polyline.getWidth(); var show = polyline.getShow(); - var color = polyline.getColor(); - var outlineColor = polyline.getOutlineColor(); - //var pickColor = polyline.getPickId(context).normalizedRgb; var positions = this._getPositions(polyline); var positionsLength = positions.length; + + var colors = polyline.getColors(); + var colorIncrement = 1; + if (typeof colors === 'undefined' || colors.length !== positionsLength) { + colors = scratchWriteColorArray; + colors[0] = polyline.getDefaultColor(); + colorIncrement = 0; + } + + var outlineColors = polyline.getOutlineColors(); + var outlineColorIncrement = 1; + if (typeof outlineColors === 'undefined' || outlineColors.length !== positionsLength) { + outlineColors = scratchWriteOutlineColorArray; + outlineColors[0] = polyline.getDefaultOutlineColor(); + outlineColorIncrement = 0; + } + + //var pickColor = polyline.getPickId(context).normalizedRgb; + var pickColor = Color.WHITE; + + var vertexColorIndex = 0; + var vertexOutlineColorIndex = 0; + for ( var j = 0; j < positionsLength; ++j) { var position = positions[j]; scratchWritePosition.x = position.x; scratchWritePosition.y = position.y; scratchWritePosition.z = (this.mode !== SceneMode.SCENE2D) ? position.z : 0.0; - var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchAdjacency); + var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchWriteAdjacency); for (var k = 0; k < 2; ++k) { EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); @@ -988,15 +1010,17 @@ define([ adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; } - scratchColor.red = color.alpha; - scratchColor.green = outlineColor.alpha; - //scratchColor.blue = pickColor.alpha; + var color = colors[vertexColorIndex]; + var outlineColor = outlineColors[vertexOutlineColorIndex]; + + scratchWriteColor.red = color.alpha; + scratchWriteColor.green = outlineColor.alpha; + scratchWriteColor.blue = pickColor.alpha; colorArray[colorIndex] = Color.encode(color); colorArray[colorIndex + 1] = Color.encode(outlineColor); - //colorArray[colorIndex + 2] = Color.encode(pickColor); - colorArray[colorIndex + 2] = 0.0; - colorArray[colorIndex + 3] = Color.encode(scratchColor); + colorArray[colorIndex + 2] = Color.encode(pickColor); + colorArray[colorIndex + 3] = Color.encode(scratchWriteColor); miscArray[miscIndex] = j / positionsLength; // s tex coord miscArray[miscIndex + 1] = 2 * k - 1; // expand direction @@ -1008,6 +1032,9 @@ define([ colorIndex += 4; miscIndex += 4; } + + vertexColorIndex += colorIncrement; + vertexOutlineColorIndex += outlineColorIncrement; } } }; @@ -1371,6 +1398,8 @@ define([ }; var scratchColorAlpha = new Color(); + var scratchColorArray = new Array(1); + var scratchOutlineColorArray = new Array(1); /** * @private @@ -1380,23 +1409,46 @@ define([ if (positionsLength) { positionIndex += this._getPolylineStartIndex(polyline); - var index = 0; - var color = polyline.getColor(); - var outlineColor = polyline.getOutlineColor(); + var colors = polyline.getColors(); + var colorIncrement = 1; + if (typeof colors === 'undefined' || colors.length !== positionsLength) { + colors = scratchColorArray; + colors[0] = polyline.getDefaultColor(); + colorIncrement = 0; + } + + var outlineColors = polyline.getOutlineColors(); + var outlineColorIncrement = 1; + if (typeof outlineColors === 'undefined' || outlineColors.length !== positionsLength) { + outlineColors = scratchOutlineColorArray; + outlineColors[0] = polyline.getDefaultOutlineColor(); + outlineColorIncrement = 0; + } + //var pickColor = polyline.getPickId(context).normalizedRgb; + var pickColor = Color.WHITE; + + var index = 0; + var colorIndex = 0; + var outlineColorIndex = 0; + var colorsArray = new Float32Array(4 * positionsLength * 2); for ( var j = 0; j < positionsLength * 2; ++j) { + var color = colors[colorIndex]; + var outlineColor = outlineColors[outlineColorIndex]; + scratchColorAlpha.red = color.alpha; scratchColorAlpha.green = outlineColor.alpha; - //scratchColorAlpha.blue = pickColor.alpha; + scratchColorAlpha.blue = pickColor.alpha; colorsArray[index] = Color.encode(color); colorsArray[index + 1] = Color.encode(outlineColor); - //colorsArray[index + 2] = Color.encode(pickColor); - colorsArray[index + 2] = 0.0; + colorsArray[index + 2] = Color.encode(pickColor); colorsArray[index + 3] = Color.encode(scratchColorAlpha); index += 4; + colorIndex += colorIncrement; + outlineColorIndex += outlineColorIncrement; } buffer.copyFromArrayView(colorsArray, 4 * positionIndex * 2); } From f8eee706889852474c3b46a0453009862cbda0be Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Feb 2013 16:46:44 -0500 Subject: [PATCH 017/114] Add a per-vertex color polyline example to the Sandcastle. --- Apps/Sandcastle/gallery/Polylines.html | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index fb482d6d65ff..1c341f851701 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -62,6 +62,27 @@ blue : 0.0, alpha : 0.75 }); + + // set a polyline's color per position + var perPositionColoredPolyline = polylines.add(); + Sandcastle.declare(perPositionColoredPolyline); // For highlighting on mouseover in Sandcastle. + perPositionColoredPolyline.setPositions(ellipsoid.cartographicArrayToCartesianArray([ + Cesium.Cartographic.fromDegrees(-115.0, 45.0), + Cesium.Cartographic.fromDegrees(-95.0, 45.0) + ])); + perPositionColoredPolyline.setColors([ + { + red : 0.0, + green : 1.0, + blue : 0.0, + alpha : 0.5, + }, { + red : 1.0, + green : 0.0, + blue : 0.0, + alpha : 1.0 + } + ]); // Set a polyline's width var widePolyline = polylines.add(); From 62570ef2212d6099377a91d092e47ca5632f82ab Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Feb 2013 18:05:37 -0500 Subject: [PATCH 018/114] Re-add polyline picking. --- Apps/Sandcastle/gallery/Polylines.html | 2 +- Source/Scene/PolylineCollection.js | 139 ++++++++++++++++++++----- Source/Shaders/PolylineFS.glsl | 5 +- Source/Shaders/PolylineFSPick.glsl | 6 ++ Source/Shaders/PolylineVS.glsl | 15 ++- 5 files changed, 130 insertions(+), 37 deletions(-) create mode 100644 Source/Shaders/PolylineFSPick.glsl diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index 1c341f851701..7ee293c974ba 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -75,7 +75,7 @@ red : 0.0, green : 1.0, blue : 0.0, - alpha : 0.5, + alpha : 0.5 }, { red : 1.0, green : 0.0, diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 2144331db366..c55cce6acead 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -20,7 +20,8 @@ define([ './SceneMode', './Polyline', '../Shaders/PolylineVS', - '../Shaders/PolylineFS' + '../Shaders/PolylineFS', + '../Shaders/PolylineFSPick' ], function( DeveloperError, combine, @@ -42,12 +43,11 @@ define([ SceneMode, Polyline, PolylineVS, - PolylineFS) { + PolylineFS, + PolylineFSPick) { "use strict"; // TODO: - // outline color - // picking // better name than 'misc' for tex coord, expansion direction, show and width attribute // materials // separate by materials @@ -142,6 +142,7 @@ define([ this._modelMatrix = Matrix4.IDENTITY.clone(); this._sp = undefined; this._rs = undefined; + this._spPick = undefined; this._rsPick = undefined; this._boundingVolume = undefined; @@ -174,9 +175,11 @@ define([ this._polylinesToUpdate = []; this._colorVertexArrays = []; + this._pickColorVertexArrays = []; this._positionBuffer = undefined; this._adjacencyBuffer = undefined; this._colorBuffer = undefined; + this._pickColorBuffer = undefined; this._miscBuffer = undefined; }; @@ -377,9 +380,6 @@ define([ * @memberof PolylineCollection */ PolylineCollection.prototype.update = function(context, frameState, commandList) { - if (typeof this._sp === 'undefined') { - this._sp = context.getShaderCache().getShaderProgram(PolylineVS, PolylineFS, attributeIndices); - } this._removePolylines(); this._updateMode(frameState); @@ -470,11 +470,15 @@ define([ var commands; var command; polylineBuckets = this._polylineBuckets; - var sp = this._sp; var useDepthTest = (this.morphTime !== 0.0); this._commandLists.removeAll(); if (typeof polylineBuckets !== 'undefined') { if (pass.color) { + if (typeof this._sp === 'undefined') { + this._sp = context.getShaderCache().getShaderProgram( + PolylineVS, PolylineFS, attributeIndices); + } + if (typeof this._rs === 'undefined') { this._rs = context.createRenderState({ blending : BlendingState.ALPHA_BLEND @@ -488,7 +492,7 @@ define([ commands = this._commandLists.colorList; for ( var m = 0; m < length; ++m) { var vaColor = this._colorVertexArrays[m]; - buckets = this._colorVertexArrays[m].buckets; + buckets = vaColor.buckets; bucketLength = buckets.length; var p = commands.length; commands.length += bucketLength; @@ -505,7 +509,7 @@ define([ command.primitiveType = PrimitiveType.TRIANGLES; command.count = bucketLocator.count; command.offset = bucketLocator.offset; - command.shaderProgram = sp; + command.shaderProgram = this._sp; command.uniformMap = this._uniforms; command.vertexArray = vaColor.va; command.renderState = this._rs; @@ -514,6 +518,10 @@ define([ } if (pass.pick) { + if (typeof this._spPick === 'undefined') { + this._spPick = context.getShaderCache().getShaderProgram( + '#define RENDER_FOR_PICK\n\n' + PolylineVS, PolylineFSPick, attributeIndices); + } if (typeof this._rsPick === 'undefined') { this._rsPick = context.createRenderState(); } @@ -524,8 +532,8 @@ define([ length = this._colorVertexArrays.length; commands = this._commandLists.pickList; for ( var a = 0; a < length; ++a) { - var vaColor = this._colorVertexArrays[a]; - buckets = this._colorVertexArrays[a].buckets; + var vaPickColor = this._pickColorVertexArrays[a]; + buckets = vaPickColor.buckets; bucketLength = buckets.length; commands.length += bucketLength; for ( var b = 0; b < bucketLength; ++b) { @@ -541,9 +549,9 @@ define([ command.primitiveType = PrimitiveType.TRIANGLES; command.count = bucketLocator.count; command.offset = bucketLocator.offset; - command.shaderProgram = sp; + command.shaderProgram = this._spPick; command.uniformMap = this._uniforms; - command.vertexArray = vaColor.va; + command.vertexArray = vaPickColor.va; command.renderState = this._rsPick; } } @@ -592,6 +600,7 @@ define([ */ PolylineCollection.prototype.destroy = function() { this._sp = this._sp && this._sp.release(); + this._spPick = this._spPick && this._spPick.release(); this._destroyVertexArrays(); this._destroyPolylines(); return destroyObject(this); @@ -657,6 +666,7 @@ define([ var positionArray = new Float32Array(2 * totalLength * 3 * 2); var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); var colorArray = new Float32Array(totalLength * 4 * 2); + var pickColorArray = new Uint8Array(totalLength * 4 * 2); var miscArray = new Float32Array(totalLength * 4 * 2); var position3DArray; @@ -667,7 +677,7 @@ define([ for (x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; - bucket.write(positionArray, adjacencyArray, colorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context); + bucket.write(positionArray, adjacencyArray, colorArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context); if (this._mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { position3DArray = new Float32Array(2 * totalLength * 3 * 2); @@ -689,8 +699,10 @@ define([ } this._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, this._buffersUsage[POSITION_INDEX].bufferUsage); this._colorBuffer = context.createVertexBuffer(colorArray, this._buffersUsage[COLOR_INDEX].bufferUsage); + this._pickColorBuffer = context.createVertexBuffer(pickColorArray, BufferUsage.STATIC_DRAW); this._miscBuffer = context.createVertexBuffer(miscArray, this._buffersUsage[MISC_INDEX].bufferUsage); var colorSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; + var pickColorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var miscSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; @@ -708,6 +720,7 @@ define([ var prevOffset = 2 * (k * (adjacencySizeInBytes * SIXTYFOURK) - vbo * adjacencySizeInBytes); var nextOffset = adjacencySizeInBytes + prevOffset; var vertexColorBufferOffset = k * (colorSizeInBytes * SIXTYFOURK) - vbo * colorSizeInBytes; + var vertexPickColorBufferOffset = k * (pickColorSizeInBytes * SIXTYFOURK) - vbo * pickColorSizeInBytes; var vertexMiscBufferOffset = k * (miscSizeInBytes * SIXTYFOURK) - vbo * miscSizeInBytes; var attributes = [{ index : attributeIndices.position3DHigh, @@ -761,28 +774,98 @@ define([ offsetInBytes : vertexMiscBufferOffset }]; + var attributesPickColor = [{ + index : attributeIndices.position3DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionHighOffset, + strideInBytes : 2 * positionSizeInBytes + }, { + index : attributeIndices.position3DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionLowOffset, + strideInBytes : 2 * positionSizeInBytes + }, { + index : attributeIndices.position2DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionHighOffset, + strideInBytes : 2 * positionSizeInBytes + }, { + index : attributeIndices.position2DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : positionLowOffset, + strideInBytes : 2 * positionSizeInBytes + }, { + index : attributeIndices.prev, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + vertexBuffer : this._adjacencyBuffer, + offsetInBytes : prevOffset, + strideInBytes : 2 * adjacencySizeInBytes + }, { + index : attributeIndices.next, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + vertexBuffer : this._adjacencyBuffer, + offsetInBytes : nextOffset, + strideInBytes : 2 * adjacencySizeInBytes + }, { + index : attributeIndices.color, + componentsPerAttribute : 4, + normalize : true, + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + vertexBuffer : this._pickColorBuffer, + offsetInBytes : vertexPickColorBufferOffset + }, { + index : attributeIndices.misc, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.FLOAT, + vertexBuffer : this._miscBuffer, + offsetInBytes : vertexMiscBufferOffset + }]; + if (this._mode === SceneMode.SCENE3D) { attributes[0].vertexBuffer = this._positionBuffer; attributes[1].vertexBuffer = this._positionBuffer; attributes[2].value = [0.0, 0.0, 0.0]; attributes[3].value = [0.0, 0.0, 0.0]; + attributesPickColor[0].vertexBuffer = this._positionBuffer; + attributesPickColor[1].vertexBuffer = this._positionBuffer; + attributesPickColor[2].value = [0.0, 0.0, 0.0]; + attributesPickColor[3].value = [0.0, 0.0, 0.0]; } else if (this._mode === SceneMode.SCENE2D || this._mode === SceneMode.COLUMBUS_VIEW) { attributes[0].value = [0.0, 0.0, 0.0]; attributes[1].value = [0.0, 0.0, 0.0]; attributes[2].vertexBuffer = this._positionBuffer; attributes[3].vertexBuffer = this._positionBuffer; + attributesPickColor[0].value = [0.0, 0.0, 0.0]; + attributesPickColor[1].value = [0.0, 0.0, 0.0]; + attributesPickColor[2].vertexBuffer = this._positionBuffer; + attributesPickColor[3].vertexBuffer = this._positionBuffer; } else { attributes[0].vertexBuffer = position3DBuffer; attributes[1].vertexBuffer = position3DBuffer; attributes[2].vertexBuffer = this._positionBuffer; attributes[3].vertexBuffer = this._positionBuffer; + attributesPickColor[0].vertexBuffer = position3DBuffer; + attributesPickColor[1].vertexBuffer = position3DBuffer; + attributesPickColor[2].vertexBuffer = this._positionBuffer; + attributesPickColor[3].vertexBuffer = this._positionBuffer; } var va = context.createVertexArray(attributes, indexBuffer); + var vaPickColor = context.createVertexArray(attributesPickColor, indexBuffer); this._colorVertexArrays.push({ va : va, buckets : vertexArrayBuckets[k] }); + this._pickColorVertexArrays.push({ + va : vaPickColor, + buckets : vertexArrayBuckets[k] + }); } } } @@ -842,8 +925,10 @@ define([ var length = this._colorVertexArrays.length; for ( var t = 0; t < length; ++t) { this._colorVertexArrays[t].va.destroy(); + this._pickColorVertexArrays[t].va.destroy(); } this._colorVertexArrays.length = 0; + this._pickColorVertexArrays.length = 0; }; PolylineCollection.prototype._updatePolyline = function(polyline, propertyChanged) { @@ -955,7 +1040,7 @@ define([ /** * @private */ - PolylineBucket.prototype.write = function(positionArray, adjacencyArray, colorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { + PolylineBucket.prototype.write = function(positionArray, adjacencyArray, colorArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { var polylines = this.polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { @@ -981,8 +1066,7 @@ define([ outlineColorIncrement = 0; } - //var pickColor = polyline.getPickId(context).normalizedRgb; - var pickColor = Color.WHITE; + var pickColor = polyline.getPickId(context).unnormalizedRgb; var vertexColorIndex = 0; var vertexOutlineColorIndex = 0; @@ -1015,12 +1099,15 @@ define([ scratchWriteColor.red = color.alpha; scratchWriteColor.green = outlineColor.alpha; - scratchWriteColor.blue = pickColor.alpha; colorArray[colorIndex] = Color.encode(color); colorArray[colorIndex + 1] = Color.encode(outlineColor); - colorArray[colorIndex + 2] = Color.encode(pickColor); - colorArray[colorIndex + 3] = Color.encode(scratchWriteColor); + colorArray[colorIndex + 2] = Color.encode(scratchWriteColor); + + pickColorArray[colorIndex] = pickColor.red; + pickColorArray[colorIndex + 1] = pickColor.green; + pickColorArray[colorIndex + 2] = pickColor.blue; + pickColorArray[colorIndex + 3] = 255; miscArray[miscIndex] = j / positionsLength; // s tex coord miscArray[miscIndex + 1] = 2 * k - 1; // expand direction @@ -1352,6 +1439,9 @@ define([ return newPositions; }; + + var scratchAdjacency = new Cartesian4(); + /** * @private */ @@ -1425,9 +1515,6 @@ define([ outlineColorIncrement = 0; } - //var pickColor = polyline.getPickId(context).normalizedRgb; - var pickColor = Color.WHITE; - var index = 0; var colorIndex = 0; var outlineColorIndex = 0; @@ -1439,12 +1526,10 @@ define([ scratchColorAlpha.red = color.alpha; scratchColorAlpha.green = outlineColor.alpha; - scratchColorAlpha.blue = pickColor.alpha; colorsArray[index] = Color.encode(color); colorsArray[index + 1] = Color.encode(outlineColor); - colorsArray[index + 2] = Color.encode(pickColor); - colorsArray[index + 3] = Color.encode(scratchColorAlpha); + colorsArray[index + 2] = Color.encode(scratchColorAlpha); index += 4; colorIndex += colorIncrement; diff --git a/Source/Shaders/PolylineFS.glsl b/Source/Shaders/PolylineFS.glsl index 3ac46df8174a..d69096a2a17d 100644 --- a/Source/Shaders/PolylineFS.glsl +++ b/Source/Shaders/PolylineFS.glsl @@ -2,10 +2,7 @@ varying vec4 v_color; varying vec4 v_outlineColor; varying float v_textureCoordinate; -varying vec4 v_pickColor; - void main() { - gl_FragColor = v_color; - //gl_FragColor = v_outlineColor; + gl_FragColor = v_color; } \ No newline at end of file diff --git a/Source/Shaders/PolylineFSPick.glsl b/Source/Shaders/PolylineFSPick.glsl new file mode 100644 index 000000000000..e1865b7284fd --- /dev/null +++ b/Source/Shaders/PolylineFSPick.glsl @@ -0,0 +1,6 @@ +varying vec4 v_pickColor; + +void main() +{ + gl_FragColor = v_pickColor; +} \ No newline at end of file diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index cec3a261433e..ac8f28b723e1 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -7,11 +7,14 @@ attribute vec4 next; attribute vec4 color; attribute vec4 misc; + +#ifndef RENDER_FOR_PICK varying vec4 v_color; varying vec4 v_outlineColor; varying float v_textureCoordinate; - +#else varying vec4 v_pickColor; +#endif uniform float u_morphTime; @@ -83,10 +86,12 @@ void main() gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); - v_textureCoordinate = texCoord; - - vec3 alphas = czm_decodeColor(color.a); +#ifndef RENDER_FOR_PICK + vec3 alphas = czm_decodeColor(color.b); v_color = vec4(czm_decodeColor(color.r), alphas.r); v_outlineColor = vec4(czm_decodeColor(color.g), alphas.g); - v_pickColor = vec4(czm_decodeColor(color.b), alphas.b); + v_textureCoordinate = texCoord; +#else + v_pickColor = color; +#endif } From 4497c0180b9d6c263f876404595a0f9b2bf367fb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Feb 2013 18:53:00 -0500 Subject: [PATCH 019/114] Add polyline highlighting to the Sandcastle. --- Source/Scene/Polyline.js | 14 ++------------ Source/Widgets/Dojo/CesiumViewerWidget.js | 9 ++++++++- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 001f88b4d382..b77bcbd8f4d3 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -216,7 +216,6 @@ define([ * * @param {Array} colors The colors of the polyline at each position. * - * @exception {DeveloperError} colors is required. * @exception {DeveloperError} colors must have the same number of elements as the positions. * * @see Polyline#getColors @@ -224,11 +223,7 @@ define([ * @see Polyline#SetDefaultColor */ Polyline.prototype.setColors = function(colors) { - if (typeof colors === 'undefined') { - throw new DeveloperError('colors is required.'); - } - - if (typeof colors.length === 'undefined' || colors.length !== this._positions.length) { + if (typeof colors !== 'undefined' && colors.length !== this._positions.length) { throw new DeveloperError('colors must have the same number of elements as the positions.'); } @@ -352,7 +347,6 @@ define([ * * @param {Array} colors The outline colors of the polyline at each position. * - * @exception {DeveloperError} colors is required. * @exception {DeveloperError} colors must have the same number of elements as the positions. * * @see Polyline#getOutlineColors @@ -360,11 +354,7 @@ define([ * @see Polyline#SetDefaultOutlineColor */ Polyline.prototype.setOutlineColors = function(colors) { - if (typeof colors === 'undefined') { - throw new DeveloperError('colors is required.'); - } - - if (typeof colors.length === 'undefined' || colors.length !== this._positions.length) { + if (typeof colors !== 'undefined' && colors.length !== this._positions.length) { throw new DeveloperError('colors must have the same number of elements as the positions.'); } diff --git a/Source/Widgets/Dojo/CesiumViewerWidget.js b/Source/Widgets/Dojo/CesiumViewerWidget.js index b0253cefde33..fe279a2a7c07 100644 --- a/Source/Widgets/Dojo/CesiumViewerWidget.js +++ b/Source/Widgets/Dojo/CesiumViewerWidget.js @@ -1044,6 +1044,9 @@ define([ this.highlightedObject.outerMaterial = this._originalMaterial; } else if (typeof this.highlightedObject.setColor !== 'undefined') { this.highlightedObject.setColor(this._originalColor); + } else if (typeof this.highlightedObject.setDefaultColor !== 'undefined') { + this.highlightedObject.setDefaultColor(this._originalColor); + this.highlightedObject.setColors(this._colors); } } this.highlightedObject = selectedObject; @@ -1054,9 +1057,13 @@ define([ } else if (typeof selectedObject.outerMaterial !== 'undefined') { this._originalMaterial = selectedObject.outerMaterial; selectedObject.outerMaterial = this.highlightMaterial; - } else if (typeof this.highlightedObject.setColor !== 'undefined') { + } else if (typeof selectedObject.setColor !== 'undefined') { this._originalColor = Color.clone(selectedObject.getColor(), this._originalColor); selectedObject.setColor(this.highlightColor); + } else if (typeof selectedObject.setDefaultColor !== 'undefined') { + this._originalColor = Color.clone(selectedObject.getDefaultColor(), this._originalColor); + this._colors = (typeof selectedObject.setColors !== 'undefined') ? selectedObject.getColors() : undefined; + selectedObject.setDefaultColor(this.highlightColor); } } } From 7f20f7523327c93b823c5157f33fee20f065425b Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 25 Feb 2013 15:03:03 -0500 Subject: [PATCH 020/114] Fix array indexing in color update. --- Source/Scene/Polyline.js | 2 +- Source/Scene/PolylineCollection.js | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index b77bcbd8f4d3..55b01e9a097a 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -461,7 +461,7 @@ define([ return true; } - function colorArrayEquals(a, aPositionsLength, bPositionsLength) { + function colorArrayEquals(a, aPositionsLength, b, bPositionsLength) { if (typeof a === 'undefined' && typeof b === 'undefined') { return true; } diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index c55cce6acead..1686681030f9 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1520,18 +1520,21 @@ define([ var outlineColorIndex = 0; var colorsArray = new Float32Array(4 * positionsLength * 2); - for ( var j = 0; j < positionsLength * 2; ++j) { - var color = colors[colorIndex]; - var outlineColor = outlineColors[outlineColorIndex]; + for ( var j = 0; j < positionsLength; ++j) { + var color = Color.encode(colors[colorIndex]); + var outlineColor = Color.encode(outlineColors[outlineColorIndex]); scratchColorAlpha.red = color.alpha; scratchColorAlpha.green = outlineColor.alpha; + var alpha = Color.encode(scratchColorAlpha); - colorsArray[index] = Color.encode(color); - colorsArray[index + 1] = Color.encode(outlineColor); - colorsArray[index + 2] = Color.encode(scratchColorAlpha); + for (var k = 0; k < 2; ++k) { + colorsArray[index] = color; + colorsArray[index + 1] = outlineColor; + colorsArray[index + 2] = alpha; + index += 4; + } - index += 4; colorIndex += colorIncrement; outlineColorIndex += outlineColorIncrement; } From 58d82e19e63c09036f7905d2bcc9764b7ff25bfd Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 25 Feb 2013 15:22:02 -0500 Subject: [PATCH 021/114] Change polyline color when highlighting a polyline with per-vertex color in the Sandcastle. Tweak vertex shader. --- Source/Shaders/PolylineVS.glsl | 4 +--- Source/Widgets/Dojo/CesiumViewerWidget.js | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index ac8f28b723e1..3e6bb3e98600 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -82,9 +82,7 @@ void main() float pixelSize = czm_pixelSize * abs(positionEC.z); direction = direction * expandDir * width * pixelSize; - vec4 positionWC = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + direction, 1.0)); - - gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0); + gl_Position = czm_projection * vec4(positionEC.xyz + direction, 1.0) * show; #ifndef RENDER_FOR_PICK vec3 alphas = czm_decodeColor(color.b); diff --git a/Source/Widgets/Dojo/CesiumViewerWidget.js b/Source/Widgets/Dojo/CesiumViewerWidget.js index fe279a2a7c07..eca1b656e7ec 100644 --- a/Source/Widgets/Dojo/CesiumViewerWidget.js +++ b/Source/Widgets/Dojo/CesiumViewerWidget.js @@ -1064,6 +1064,7 @@ define([ this._originalColor = Color.clone(selectedObject.getDefaultColor(), this._originalColor); this._colors = (typeof selectedObject.setColors !== 'undefined') ? selectedObject.getColors() : undefined; selectedObject.setDefaultColor(this.highlightColor); + selectedObject.setColors(undefined); } } } From d402f195b9dca581e2f5d75801fb0e581ecdb366 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 25 Feb 2013 17:45:15 -0500 Subject: [PATCH 022/114] Start adding polyline materials. --- Source/Scene/Material.js | 15 +++- Source/Scene/Polyline.js | 46 ++++++++-- Source/Scene/PolylineCollection.js | 90 +++++++++++++------ .../Shaders/Materials/PolylineMaterial.glsl | 19 ++++ Source/Shaders/PolylineFS.glsl | 20 ++++- Source/Shaders/PolylineVS.glsl | 11 ++- 6 files changed, 155 insertions(+), 46 deletions(-) create mode 100644 Source/Shaders/Materials/PolylineMaterial.glsl diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index fcd6a6e6c1c4..d271454f6db3 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -33,7 +33,8 @@ define([ '../Shaders/Materials/Water', '../Shaders/Materials/WoodMaterial', '../Shaders/Materials/RimLightingMaterial', - '../Shaders/Materials/ErosionMaterial' + '../Shaders/Materials/ErosionMaterial', + '../Shaders/Materials/PolylineMaterial' ], function( when, loadImage, @@ -68,7 +69,8 @@ define([ WaterMaterial, WoodMaterial, RimLightingMaterial, - ErosionMaterial) { + ErosionMaterial, + PolylineMaterial) { "use strict"; /** @@ -1173,5 +1175,14 @@ define([ source : ErosionMaterial }); + Material.PolylineType = 'Polyline'; + Material._materialCache.addMaterial(Material.PolylineType, { + type : Material.PolylineType, + uniforms : { + outlineWidth : 0.0 + }, + source : PolylineMaterial + }); + return Material; }); diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 55b01e9a097a..47729d47f8c7 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -6,7 +6,8 @@ define([ '../Core/BoundingSphere', '../Core/Cartesian3', '../Core/Color', - '../Core/PolylinePipeline' + '../Core/PolylinePipeline', + './Material' ], function( defaultValue, DeveloperError, @@ -14,10 +15,12 @@ define([ BoundingSphere, Cartesian3, Color, - PolylinePipeline) { + PolylinePipeline, + Material) { "use strict"; var EMPTY_OBJECT = {}; + var defaultOutlineColor = new Color(1.0, 1.0, 1.0, 0.0); /** * DOC_TBA @@ -31,10 +34,15 @@ define([ this._show = defaultValue(description.show, true); this._width = defaultValue(description.width, 1.0); this._color = Color.clone(defaultValue(description.color, Color.WHITE)); - this._outlineColor = Color.clone(defaultValue(description.outlineColor, Color.WHITE)); + this._outlineColor = Color.clone(defaultValue(description.outlineColor, defaultOutlineColor)); this._perVertexColors = undefined; this._perVertexOutlineColors = undefined; + this._material = description.material; + if (typeof this._material === 'undefined') { + this._material = Material.fromType(undefined, Material.PolylineType); + } + var positions = description.positions; if (typeof positions === 'undefined') { positions = []; @@ -54,11 +62,12 @@ define([ this._boundingVolume2D = new BoundingSphere(); // modified in PolylineCollection }; - var MISC = Polyline.MISC = 0; + var MISC_INDEX = Polyline.MISC_INDEX = 0; var POSITION_INDEX = Polyline.POSITION_INDEX = 1; var COLOR_INDEX = Polyline.COLOR_INDEX = 2; - var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 3; - var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 4; + var MATERIAL_INDEX = Polyline.MATERIAL_INDEX = 3; + var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 4; + var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 5; function makeDirty(polyline, propertyChanged) { ++polyline._propertiesChanged[propertyChanged]; @@ -102,7 +111,7 @@ define([ if (value !== this._show) { this._show = value; - makeDirty(this, MISC); + makeDirty(this, MISC_INDEX); } }; @@ -154,6 +163,27 @@ define([ makeDirty(this, POSITION_INDEX); }; + /** + * TODO + * @returns + */ + Polyline.prototype.getMaterial = function() { + return this._material; + }; + + /** + * TODO + * @param material + */ + Polyline.prototype.setMaterial = function(material) { + if (typeof material === 'undefined') { + throw new DeveloperError('material is required.'); + } + + this._material = material; + makeDirty(this, MATERIAL_INDEX); + }; + /** * Returns the default color of the polyline. This color is used if per-vertex * colors are not defined. @@ -281,7 +311,7 @@ define([ var width = this._width; if (value !== width) { this._width = value; - makeDirty(this, MISC); + makeDirty(this, MISC_INDEX); } }; diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 1686681030f9..b4245200c991 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -19,6 +19,7 @@ define([ '../Renderer/DrawCommand', './SceneMode', './Polyline', + '../Shaders/Noise', '../Shaders/PolylineVS', '../Shaders/PolylineFS', '../Shaders/PolylineFSPick' @@ -42,6 +43,7 @@ define([ DrawCommand, SceneMode, Polyline, + Noise, PolylineVS, PolylineFS, PolylineFSPick) { @@ -50,12 +52,12 @@ define([ // TODO: // better name than 'misc' for tex coord, expansion direction, show and width attribute // materials - // separate by materials // adjacency info in 2d at idl - var MISC_INDEX = Polyline.MISC; + var MISC_INDEX = Polyline.MISC_INDEX; var POSITION_INDEX = Polyline.POSITION_INDEX; var COLOR_INDEX = Polyline.COLOR_INDEX; + var MATERIAL_INDEX = Polyline.MATERIAL_INDEX; //POSITION_SIZE_INDEX is needed for when the polyline's position array changes size. //When it does, we need to recreate the indicesBuffer. var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX; @@ -140,7 +142,6 @@ define([ */ this.modelMatrix = Matrix4.IDENTITY.clone(); this._modelMatrix = Matrix4.IDENTITY.clone(); - this._sp = undefined; this._rs = undefined; this._spPick = undefined; this._rsPick = undefined; @@ -159,9 +160,10 @@ define([ // The buffer usage for each attribute is determined based on the usage of the attribute over time. this._buffersUsage = [ - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // MISC + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // MISC_INDEX {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // POSITION_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0} // COLOR_INDEX + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // COLOR_INDEX + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0} // MATERIAL_INDEX ]; this._mode = undefined; @@ -415,8 +417,9 @@ define([ } } } - //if a polyline's positions size changes, we need to recreate the vertex arrays and vertex buffers because the indices will be different. - if (properties[POSITION_SIZE_INDEX] || properties[MISC_INDEX] || createVertexArrays) { + // if a polyline's positions size changes, we need to recreate the vertex arrays and vertex buffers because the indices will be different. + // if a polyline's material changes, we need to recreate the VAOs and VBOs because they will be batched differenty. + if (properties[POSITION_SIZE_INDEX] || properties[MATERIAL_INDEX] || createVertexArrays) { this._createVertexArrays(context); } else { length = polylinesToUpdate.length; @@ -474,11 +477,6 @@ define([ this._commandLists.removeAll(); if (typeof polylineBuckets !== 'undefined') { if (pass.color) { - if (typeof this._sp === 'undefined') { - this._sp = context.getShaderCache().getShaderProgram( - PolylineVS, PolylineFS, attributeIndices); - } - if (typeof this._rs === 'undefined') { this._rs = context.createRenderState({ blending : BlendingState.ALPHA_BLEND @@ -509,8 +507,8 @@ define([ command.primitiveType = PrimitiveType.TRIANGLES; command.count = bucketLocator.count; command.offset = bucketLocator.offset; - command.shaderProgram = this._sp; - command.uniformMap = this._uniforms; + command.shaderProgram = bucketLocator.shaderProgram; + command.uniformMap = combine([this._uniforms, bucketLocator.material._uniforms], false, false); command.vertexArray = vaColor.va; command.renderState = this._rs; } @@ -659,6 +657,7 @@ define([ for (x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; + bucket.updateShader(context); totalLength += bucket.lengthOfPositions; } } @@ -871,18 +870,29 @@ define([ } }; + PolylineCollection.prototype._createMaterialHash = function(material) { + var hash = material.type; + var uniforms = material._uniforms; + for (var uniform in uniforms) { + if (uniforms.hasOwnProperty(uniform)) { + hash += '_' + uniform + '_' + uniforms[uniform](); + } + } + + return hash; + }; + PolylineCollection.prototype._sortPolylinesIntoBuckets = function() { var polylineBuckets = this._polylineBuckets = {}; var polylines = this._polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { var p = polylines[i]; - var width = p.getWidth(); - // TODO separate by material - var hash = 'W' + width; + var material = p.getMaterial(); + var hash = this._createMaterialHash(material); var value = polylineBuckets[hash]; if (typeof value === 'undefined') { - value = polylineBuckets[hash] = new PolylineBucket(width, this._mode, this._projection, this._modelMatrix); + value = polylineBuckets[hash] = new PolylineBucket(material, this._mode, this._projection, this._modelMatrix); } value.addPolyline(p); } @@ -950,18 +960,21 @@ define([ /** * @private */ - function VertexArrayBucketLocator(count, offset) { + function VertexArrayBucketLocator(count, offset, bucket) { this.count = count; this.offset = offset; + this.shaderProgram = bucket.shaderProgram; + this.material = bucket.material; } /** * @private */ - var PolylineBucket = function(width, mode, projection, modelMatrix) { - this.width = width; + var PolylineBucket = function(material, mode, projection, modelMatrix) { this.polylines = []; this.lengthOfPositions = 0; + this.material = material; + this.shaderProgram = undefined; this.mode = mode; this.projection = projection; this.ellipsoid = projection.getEllipsoid(); @@ -979,6 +992,25 @@ define([ p._bucket = this; }; + /** + * @private + */ + PolylineBucket.prototype.updateShader = function(context) { + if (typeof this.shaderProgram !== 'undefined') { + return; + } + + var fsSource = + '#line 0\n' + + Noise + + '#line 0\n' + + this.material.shaderSource + + '#line 0\n' + + PolylineFS; + + this.shaderProgram = context.getShaderCache().getShaderProgram(PolylineVS, fsSource, attributeIndices); + }; + function intersectsIDL(polyline) { return Cartesian3.dot(Cartesian3.UNIT_X, polyline._boundingVolume.center) < 0 || polyline._boundingVolume.intersect(Cartesian4.UNIT_Y) === Intersect.INTERSECTING; @@ -1196,7 +1228,7 @@ define([ */ PolylineBucket.prototype._updateIndices3D = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { var vaCount = vertexArrayBuckets.length - 1; - var bucketLocator = new VertexArrayBucketLocator(0, offset); + var bucketLocator = new VertexArrayBucketLocator(0, offset, this); vertexArrayBuckets[vaCount].push(bucketLocator); var count = 0; var indices = totalIndices[totalIndices.length - 1]; @@ -1221,7 +1253,7 @@ define([ bucketLocator.count = count; count = 0; offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0); + bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } @@ -1243,7 +1275,7 @@ define([ bucketLocator.count = count; offset = 0; count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0); + bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } } @@ -1258,7 +1290,7 @@ define([ */ PolylineBucket.prototype._updateIndices2D = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { var vaCount = vertexArrayBuckets.length - 1; - var bucketLocator = new VertexArrayBucketLocator(0, offset); + var bucketLocator = new VertexArrayBucketLocator(0, offset, this); vertexArrayBuckets[vaCount].push(bucketLocator); var count = 0; var indices = totalIndices[totalIndices.length - 1]; @@ -1287,7 +1319,7 @@ define([ bucketLocator.count = count; count = 0; offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0); + bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } @@ -1314,7 +1346,7 @@ define([ bucketLocator.count = count; offset = 0; count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0); + bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } } @@ -1331,7 +1363,7 @@ define([ bucketLocator.count = count; count = 0; offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0); + bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } @@ -1353,7 +1385,7 @@ define([ bucketLocator.count = count; offset = 0; count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0); + bucketLocator = new VertexArrayBucketLocator(0, 0, this); vertexArrayBuckets[++vaCount] = [bucketLocator]; } } diff --git a/Source/Shaders/Materials/PolylineMaterial.glsl b/Source/Shaders/Materials/PolylineMaterial.glsl new file mode 100644 index 000000000000..071c028d239a --- /dev/null +++ b/Source/Shaders/Materials/PolylineMaterial.glsl @@ -0,0 +1,19 @@ +uniform float outlineWidth; + +varying vec4 v_color; +varying vec4 v_outlineColor; +varying float v_width; + +czm_material czm_getMaterial(czm_materialInput materialInput) +{ + czm_material material = czm_getDefaultMaterial(materialInput); + + float halfInteriorWidth = (v_width - outlineWidth * 2.0) / (v_width * 2.0); + float s = step(0.5 - halfInteriorWidth, materialInput.st.t); + s *= 1.0 - step(0.5 + halfInteriorWidth, materialInput.st.t); + + material.diffuse = mix(v_outlineColor.rgb, v_color.rgb, s); + material.alpha = mix(v_outlineColor.a, v_color.a, s); + + return material; +} diff --git a/Source/Shaders/PolylineFS.glsl b/Source/Shaders/PolylineFS.glsl index d69096a2a17d..1ef60da551ce 100644 --- a/Source/Shaders/PolylineFS.glsl +++ b/Source/Shaders/PolylineFS.glsl @@ -1,8 +1,20 @@ -varying vec4 v_color; -varying vec4 v_outlineColor; -varying float v_textureCoordinate; +varying vec2 v_textureCoordinates; +varying vec3 v_positionEC; void main() { - gl_FragColor = v_color; + czm_materialInput materialInput; + + materialInput.s = v_textureCoordinates.r; + materialInput.st = v_textureCoordinates; + materialInput.str = vec3(v_textureCoordinates, 0.0); + + materialInput.normalEC = vec3(0.0, 0.0, 1.0); + + vec3 positionToEyeEC = -v_positionEC; + materialInput.positionToEyeEC = positionToEyeEC; + + czm_material material = czm_getMaterial(materialInput); + + gl_FragColor = czm_phong(normalize(positionToEyeEC), material); } \ No newline at end of file diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 3e6bb3e98600..0d4c31873621 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -11,7 +11,9 @@ attribute vec4 misc; #ifndef RENDER_FOR_PICK varying vec4 v_color; varying vec4 v_outlineColor; -varying float v_textureCoordinate; +varying vec2 v_textureCoordinates; +varying float v_width; +varying vec3 v_positionEC; #else varying vec4 v_pickColor; #endif @@ -82,13 +84,16 @@ void main() float pixelSize = czm_pixelSize * abs(positionEC.z); direction = direction * expandDir * width * pixelSize; - gl_Position = czm_projection * vec4(positionEC.xyz + direction, 1.0) * show; + positionEC = vec4(positionEC.xyz + direction, 1.0); + gl_Position = czm_projection * positionEC * show; #ifndef RENDER_FOR_PICK vec3 alphas = czm_decodeColor(color.b); v_color = vec4(czm_decodeColor(color.r), alphas.r); v_outlineColor = vec4(czm_decodeColor(color.g), alphas.g); - v_textureCoordinate = texCoord; + v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); + v_width = width * 2.0; + v_positionEC = positionEC.xyz; #else v_pickColor = color; #endif From da1fa0e78ee5e2d117738763b47b11f49a031eec Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 25 Feb 2013 19:09:01 -0500 Subject: [PATCH 023/114] Displace polyline vertices in screen space. Add outline example to the polyline Sandcastle example. --- Apps/Sandcastle/gallery/Polylines.html | 7 ++++++- Source/Shaders/PolylineVS.glsl | 26 +++++++++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index 7ee293c974ba..c9ffb6da7acf 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -93,7 +93,12 @@ Cesium.Cartographic.fromDegrees(-105.0, 35.0), Cesium.Cartographic.fromDegrees(-100.0, 32.0) ])); - widePolyline.setWidth(5); + widePolyline.setWidth(10.0); + + // Set the polyline's material to have an outline + var material = Cesium.Material.fromType(undefined, Cesium.Material.PolylineType); + material.uniforms.outlineWidth = 5.0; + widePolyline.setMaterial(material); widePolyline.setDefaultOutlineColor({ red : 1.0, green : 0.0, diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 0d4c31873621..0ed840c96c8c 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -66,26 +66,30 @@ void main() vec4 prevEC = czm_modelView * prevDir; vec4 nextEC = czm_modelView * nextDir; - vec3 direction = (prevEC.xyz + nextEC.xyz) * 0.5; - direction.z = 0.0; - direction = normalize(direction); + float pixelSize = czm_pixelSize * abs(positionEC.z); + + vec4 p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); + vec4 p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); + vec4 positionWC = czm_eyeToWindowCoordinates(positionEC); + + vec2 nextWC = normalize(p0.xy - positionWC.xy); + vec2 prevWC = normalize(p1.xy - positionWC.xy); + vec2 normal = normalize(vec2(nextWC.y, - nextWC.x)); - if (direction.x < 0.0) + vec2 direction = normalize((nextWC + prevWC) * 0.5); + if (dot(direction, normal) < 0.0) { - expandDir *= -1.0; + direction = -direction; } - float angle = acos(dot(direction, nextEC.xyz)); + float angle = acos(dot(direction, nextWC)); if (abs(angle - czm_piOverTwo) > czm_epsilon1) { width = width / sin(angle); } - float pixelSize = czm_pixelSize * abs(positionEC.z); - direction = direction * expandDir * width * pixelSize; - - positionEC = vec4(positionEC.xyz + direction, 1.0); - gl_Position = czm_projection * positionEC * show; + positionWC.xy += direction * width * expandDir; + gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0) * show; #ifndef RENDER_FOR_PICK vec3 alphas = czm_decodeColor(color.b); From bd235f3d68fc9e035a73fd6912e1b097b0e5942d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Feb 2013 10:59:53 -0500 Subject: [PATCH 024/114] Add polyline glow material. --- Apps/Sandcastle/gallery/Polylines.html | 5 +++- Source/Scene/Material.js | 20 ++++++++++----- Source/Scene/Polyline.js | 2 +- Source/Shaders/BuiltinFunctions.glsl | 13 ++++++++++ .../Materials/PolylineGlowMaterial.glsl | 25 +++++++++++++++++++ ...rial.glsl => PolylineOutlineMaterial.glsl} | 0 Source/Shaders/PolylineVS.glsl | 18 ++++++++----- 7 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 Source/Shaders/Materials/PolylineGlowMaterial.glsl rename Source/Shaders/Materials/{PolylineMaterial.glsl => PolylineOutlineMaterial.glsl} (100%) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index c9ffb6da7acf..5cce837d3817 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -62,6 +62,9 @@ blue : 0.0, alpha : 0.75 }); + coloredPolyline.setWidth(10); + coloredPolyline.setMaterial(Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType)); + // set a polyline's color per position var perPositionColoredPolyline = polylines.add(); @@ -96,7 +99,7 @@ widePolyline.setWidth(10.0); // Set the polyline's material to have an outline - var material = Cesium.Material.fromType(undefined, Cesium.Material.PolylineType); + var material = Cesium.Material.fromType(undefined, Cesium.Material.PolylineOutlineType); material.uniforms.outlineWidth = 5.0; widePolyline.setMaterial(material); widePolyline.setDefaultOutlineColor({ diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index d271454f6db3..ac66f5875306 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -34,7 +34,8 @@ define([ '../Shaders/Materials/WoodMaterial', '../Shaders/Materials/RimLightingMaterial', '../Shaders/Materials/ErosionMaterial', - '../Shaders/Materials/PolylineMaterial' + '../Shaders/Materials/PolylineOutlineMaterial', + '../Shaders/Materials/PolylineGlowMaterial' ], function( when, loadImage, @@ -70,7 +71,8 @@ define([ WoodMaterial, RimLightingMaterial, ErosionMaterial, - PolylineMaterial) { + PolylineOutlineMaterial, + PolylineGlowMaterial) { "use strict"; /** @@ -1175,13 +1177,19 @@ define([ source : ErosionMaterial }); - Material.PolylineType = 'Polyline'; - Material._materialCache.addMaterial(Material.PolylineType, { - type : Material.PolylineType, + Material.PolylineOutlineType = 'PolylineOutline'; + Material._materialCache.addMaterial(Material.PolylineOutlineType, { + type : Material.PolylineOutlineType, uniforms : { outlineWidth : 0.0 }, - source : PolylineMaterial + source : PolylineOutlineMaterial + }); + + Material.PolylineGlowType = 'PolylineGlow'; + Material._materialCache.addMaterial(Material.PolylineGlowType, { + type : Material.PolylineGlowType, + source : PolylineGlowMaterial }); return Material; diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 47729d47f8c7..ef307e5b8278 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -40,7 +40,7 @@ define([ this._material = description.material; if (typeof this._material === 'undefined') { - this._material = Material.fromType(undefined, Material.PolylineType); + this._material = Material.fromType(undefined, Material.PolylineOutlineType); } var positions = description.positions; diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index feb380d650bf..4ac4ee449f93 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -1027,3 +1027,16 @@ vec4 czm_getWaterNoise(sampler2D normalMap, vec2 uv, float time, float angleInRa // average and scale to between -1 and 1 return ((noise / 4.0) - 0.5) * 2.0; } + +/** + * TODO + */ +float czm_pointLineDistance(czm_ray ray, vec3 point) +{ + vec3 origin = ray.origin; + vec3 direction = ray.direction; + //float t = dot(direction, point - origin) / dot(direction, direction); + float t = dot(direction, point - origin); + return distance(point, czm_pointAlongRay(ray, t)); +} + diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl new file mode 100644 index 000000000000..9b15fe33faa4 --- /dev/null +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -0,0 +1,25 @@ +varying vec2 v_positionWC; +varying vec2 v_endPointWC; +varying vec2 v_nextWC; + +varying vec4 v_color; +varying float v_width; + +czm_material czm_getMaterial(czm_materialInput materialInput) +{ + czm_material material = czm_getDefaultMaterial(materialInput); + + czm_ray ray; + ray.origin = vec3(v_endPointWC, 0.0); + ray.direction = vec3(normalize(v_nextWC), 0.0); + + float d = czm_pointLineDistance(ray, vec3(v_positionWC, 0.0)); + d /= v_width * 2.0; + d = 1.0 - 6.0 * d; + + material.diffuse = v_color.rgb; + material.emission = v_color.rgb * d; + material.alpha = d; + + return material; +} diff --git a/Source/Shaders/Materials/PolylineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl similarity index 100% rename from Source/Shaders/Materials/PolylineMaterial.glsl rename to Source/Shaders/Materials/PolylineOutlineMaterial.glsl diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 0ed840c96c8c..f6d4c051a4ac 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -14,6 +14,9 @@ varying vec4 v_outlineColor; varying vec2 v_textureCoordinates; varying float v_width; varying vec3 v_positionEC; +varying vec2 v_positionWC; +varying vec2 v_endPointWC; +varying vec2 v_nextWC; #else varying vec4 v_pickColor; #endif @@ -70,10 +73,10 @@ void main() vec4 p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); vec4 p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); - vec4 positionWC = czm_eyeToWindowCoordinates(positionEC); + vec4 endPointWC = czm_eyeToWindowCoordinates(positionEC); - vec2 nextWC = normalize(p0.xy - positionWC.xy); - vec2 prevWC = normalize(p1.xy - positionWC.xy); + vec2 nextWC = normalize(p0.xy - endPointWC.xy); + vec2 prevWC = normalize(p1.xy - endPointWC.xy); vec2 normal = normalize(vec2(nextWC.y, - nextWC.x)); vec2 direction = normalize((nextWC + prevWC) * 0.5); @@ -87,9 +90,9 @@ void main() { width = width / sin(angle); } - - positionWC.xy += direction * width * expandDir; - gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0) * show; + + vec4 positionWC = vec4(endPointWC.xy + direction * width * expandDir, -endPointWC.z, 1.0); + gl_Position = czm_viewportOrthographic * positionWC * show; #ifndef RENDER_FOR_PICK vec3 alphas = czm_decodeColor(color.b); @@ -98,6 +101,9 @@ void main() v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); v_width = width * 2.0; v_positionEC = positionEC.xyz; + v_positionWC = positionWC.xy; + v_endPointWC = endPointWC.xy; + v_nextWC = nextWC; #else v_pickColor = color; #endif From f31cf55aec66956e67d61fc457ad0f479989d870 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Feb 2013 11:29:54 -0500 Subject: [PATCH 025/114] Update DynamicPathVisualizer and DynamicPolylineVisualizer. --- Source/DynamicScene/DynamicPathVisualizer.js | 8 ++++---- Source/DynamicScene/DynamicPolylineVisualizer.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index f8693db44efd..73e9963d8b28 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -135,8 +135,8 @@ define([ polyline.dynamicObject = dynamicObject; // CZML_TODO Determine official defaults - polyline.setColor(Color.WHITE); - polyline.setOutlineColor(Color.BLACK); + polyline.setDefaultColor(Color.WHITE); + polyline.setDefaultOutlineColor(Color.BLACK); polyline.setWidth(1); } else { polyline = this._polylineCollection.get(pathVisualizerIndex); @@ -147,12 +147,12 @@ define([ property = dynamicPath.color; if (typeof property !== 'undefined') { - polyline.setColor(property.getValue(time, polyline.getColor())); + polyline.setDefaultColor(property.getValue(time, polyline.getDefaultColor())); } property = dynamicPath.outlineColor; if (typeof property !== 'undefined') { - polyline.setOutlineColor(property.getValue(time, polyline.getOutlineColor())); + polyline.setDefaultOutlineColor(property.getValue(time, polyline.getDefaultOutlineColor())); } property = dynamicPath.width; diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index d7030543dfae..2d000860b207 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -206,8 +206,8 @@ define([ polyline.dynamicObject = dynamicObject; // CZML_TODO Determine official defaults - polyline.setColor(Color.WHITE); - polyline.setOutlineColor(Color.BLACK); + polyline.setDefaultColor(Color.WHITE); + polyline.setDefaultOutlineColor(Color.BLACK); polyline.setWidth(1); } else { polyline = this._polylineCollection.get(polylineVisualizerIndex); @@ -223,12 +223,12 @@ define([ var property = dynamicPolyline.color; if (typeof property !== 'undefined') { - polyline.setColor(property.getValue(time, polyline.getColor())); + polyline.setDefaultColor(property.getValue(time, polyline.getDefaultColor())); } property = dynamicPolyline.outlineColor; if (typeof property !== 'undefined') { - polyline.setOutlineColor(property.getValue(time, polyline.getOutlineColor())); + polyline.setDefaultOutlineColor(property.getValue(time, polyline.getDefaultOutlineColor())); } property = dynamicPolyline.width; From 4cd211dac247db9d4cee18047d0e2be1f094b67e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Feb 2013 15:27:04 -0500 Subject: [PATCH 026/114] Tweak glow material shader. --- Apps/Sandcastle/gallery/Polylines.html | 5 +++-- .../Shaders/Materials/PolylineGlowMaterial.glsl | 15 ++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index 5cce837d3817..f66fa39f878b 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -62,8 +62,9 @@ blue : 0.0, alpha : 0.75 }); - coloredPolyline.setWidth(10); - coloredPolyline.setMaterial(Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType)); + coloredPolyline.setWidth(10.0); + var material = Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType); + coloredPolyline.setMaterial(material); // set a polyline's color per position diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl index 9b15fe33faa4..e0f96d82d6b4 100644 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -13,13 +13,18 @@ czm_material czm_getMaterial(czm_materialInput materialInput) ray.origin = vec3(v_endPointWC, 0.0); ray.direction = vec3(normalize(v_nextWC), 0.0); + float interiorWidth = 0.5; + float d = czm_pointLineDistance(ray, vec3(v_positionWC, 0.0)); - d /= v_width * 2.0; - d = 1.0 - 6.0 * d; + float alpha = 1.0 - 12.0 * d / (v_width * 12.0); + vec4 color = vec4(v_color.rgb * alpha, alpha); + + //d = 1.0 - step(interiorWidth, d); + //vec4 currentColor = d * v_color; + //material.diffuse = currentColor.rgb; - material.diffuse = v_color.rgb; - material.emission = v_color.rgb * d; - material.alpha = d; + material.emission = color.rgb; + material.alpha = alpha; return material; } From 982e5d3641bb3cea22313b3b45f147dea121c13f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Feb 2013 17:23:53 -0500 Subject: [PATCH 027/114] Tweak polyline VS and outline material shader. Remove unused function from the built-in functions GLSL. Rewrote the polyline glow shader. --- Apps/Sandcastle/gallery/Polylines.html | 8 ++--- Source/Shaders/BuiltinFunctions.glsl | 13 --------- .../Materials/PolylineGlowMaterial.glsl | 29 +++++++------------ .../Materials/PolylineOutlineMaterial.glsl | 8 +++-- Source/Shaders/PolylineVS.glsl | 8 +---- 5 files changed, 20 insertions(+), 46 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index f66fa39f878b..f434a14e5414 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -57,12 +57,12 @@ Cesium.Cartographic.fromDegrees(-85.0, 40.0) ])); coloredPolyline.setDefaultColor({ - red : 1.0, + red : 0.0, green : 1.0, - blue : 0.0, - alpha : 0.75 + blue : 1.0, + alpha : 1.0 }); - coloredPolyline.setWidth(10.0); + coloredPolyline.setWidth(20.0); var material = Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType); coloredPolyline.setMaterial(material); diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index 4ac4ee449f93..feb380d650bf 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -1027,16 +1027,3 @@ vec4 czm_getWaterNoise(sampler2D normalMap, vec2 uv, float time, float angleInRa // average and scale to between -1 and 1 return ((noise / 4.0) - 0.5) * 2.0; } - -/** - * TODO - */ -float czm_pointLineDistance(czm_ray ray, vec3 point) -{ - vec3 origin = ray.origin; - vec3 direction = ray.direction; - //float t = dot(direction, point - origin) / dot(direction, direction); - float t = dot(direction, point - origin); - return distance(point, czm_pointAlongRay(ray, t)); -} - diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl index e0f96d82d6b4..c6c5c189f62c 100644 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -1,30 +1,21 @@ -varying vec2 v_positionWC; -varying vec2 v_endPointWC; -varying vec2 v_nextWC; - varying vec4 v_color; varying float v_width; +float dropOffFunction(float value) +{ + return value * value; +} + czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); - czm_ray ray; - ray.origin = vec3(v_endPointWC, 0.0); - ray.direction = vec3(normalize(v_nextWC), 0.0); + float halfInteriorWidth = 1.0 / v_width; + float s = (1.0 - step(0.5 - halfInteriorWidth, materialInput.st.t)) * dropOffFunction(1.0 - materialInput.st.t); + s += step(0.5 + halfInteriorWidth, materialInput.st.t) * dropOffFunction(materialInput.st.t); + float alpha = mix(0.1, 1.0, 1.0 - s); - float interiorWidth = 0.5; - - float d = czm_pointLineDistance(ray, vec3(v_positionWC, 0.0)); - float alpha = 1.0 - 12.0 * d / (v_width * 12.0); - vec4 color = vec4(v_color.rgb * alpha, alpha); - - //d = 1.0 - step(interiorWidth, d); - //vec4 currentColor = d * v_color; - //material.diffuse = currentColor.rgb; - - material.emission = color.rgb; + material.emission = v_color.rgb * alpha; material.alpha = alpha; - return material; } diff --git a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl index 071c028d239a..b44176f6dbf6 100644 --- a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl +++ b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl @@ -8,12 +8,14 @@ czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); - float halfInteriorWidth = (v_width - outlineWidth * 2.0) / (v_width * 2.0); + float halfInteriorWidth = 0.5 - outlineWidth / v_width; float s = step(0.5 - halfInteriorWidth, materialInput.st.t); s *= 1.0 - step(0.5 + halfInteriorWidth, materialInput.st.t); - material.diffuse = mix(v_outlineColor.rgb, v_color.rgb, s); - material.alpha = mix(v_outlineColor.a, v_color.a, s); + vec4 color = mix(v_outlineColor, v_color, s); + + material.diffuse = color.rgb; + material.alpha = color.a; return material; } diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index f6d4c051a4ac..d5ac5349b7e1 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -14,9 +14,6 @@ varying vec4 v_outlineColor; varying vec2 v_textureCoordinates; varying float v_width; varying vec3 v_positionEC; -varying vec2 v_positionWC; -varying vec2 v_endPointWC; -varying vec2 v_nextWC; #else varying vec4 v_pickColor; #endif @@ -77,7 +74,7 @@ void main() vec2 nextWC = normalize(p0.xy - endPointWC.xy); vec2 prevWC = normalize(p1.xy - endPointWC.xy); - vec2 normal = normalize(vec2(nextWC.y, - nextWC.x)); + vec2 normal = normalize(vec2(nextWC.y, -nextWC.x)); vec2 direction = normalize((nextWC + prevWC) * 0.5); if (dot(direction, normal) < 0.0) @@ -101,9 +98,6 @@ void main() v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); v_width = width * 2.0; v_positionEC = positionEC.xyz; - v_positionWC = positionWC.xy; - v_endPointWC = endPointWC.xy; - v_nextWC = nextWC; #else v_pickColor = color; #endif From f6a18841f6c654b51a6f000ec29c2d998c40bf46 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Feb 2013 18:03:50 -0500 Subject: [PATCH 028/114] Fix polyline flicker caused by dividing by a number close to zero. --- Source/Shaders/PolylineVS.glsl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index d5ac5349b7e1..e4ba35297957 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -83,9 +83,10 @@ void main() } float angle = acos(dot(direction, nextWC)); - if (abs(angle - czm_piOverTwo) > czm_epsilon1) + float sinAngle = sin(angle); + if (abs(sinAngle) > czm_epsilon1 * 2.5) { - width = width / sin(angle); + width = width / sinAngle; } vec4 positionWC = vec4(endPointWC.xy + direction * width * expandDir, -endPointWC.z, 1.0); From e21021da3a01bba772db4cf35f85219f6089e072 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Feb 2013 19:29:09 -0500 Subject: [PATCH 029/114] Fix polyline outline material at the end points. --- Source/Shaders/Materials/PolylineOutlineMaterial.glsl | 2 +- Source/Shaders/PolylineVS.glsl | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl index b44176f6dbf6..84568c6ce3b6 100644 --- a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl +++ b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl @@ -8,7 +8,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); - float halfInteriorWidth = 0.5 - outlineWidth / v_width; + float halfInteriorWidth = 0.5 * (v_width - outlineWidth) / v_width; float s = step(0.5 - halfInteriorWidth, materialInput.st.t); s *= 1.0 - step(0.5 + halfInteriorWidth, materialInput.st.t); diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index e4ba35297957..31747c7436ca 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -24,7 +24,7 @@ void main() { float texCoord = misc.x; float expandDir = misc.y; - float width = misc.z * 0.5; + float width = misc.z; float show = misc.w; vec4 p; @@ -84,12 +84,13 @@ void main() float angle = acos(dot(direction, nextWC)); float sinAngle = sin(angle); + float expandWidth = width * 0.5; if (abs(sinAngle) > czm_epsilon1 * 2.5) { - width = width / sinAngle; + expandWidth = expandWidth / sinAngle; } - vec4 positionWC = vec4(endPointWC.xy + direction * width * expandDir, -endPointWC.z, 1.0); + vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, -endPointWC.z, 1.0); gl_Position = czm_viewportOrthographic * positionWC * show; #ifndef RENDER_FOR_PICK @@ -97,7 +98,7 @@ void main() v_color = vec4(czm_decodeColor(color.r), alphas.r); v_outlineColor = vec4(czm_decodeColor(color.g), alphas.g); v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); - v_width = width * 2.0; + v_width = width; v_positionEC = positionEC.xyz; #else v_pickColor = color; From 7c12b59a9b9b2830cbbb678ebd3728d6876cf0ad Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Feb 2013 20:11:42 -0500 Subject: [PATCH 030/114] Fix polyline color update. --- Source/Scene/PolylineCollection.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index b4245200c991..b39c44883e57 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -51,7 +51,6 @@ define([ // TODO: // better name than 'misc' for tex coord, expansion direction, show and width attribute - // materials // adjacency info in 2d at idl var MISC_INDEX = Polyline.MISC_INDEX; @@ -1553,24 +1552,26 @@ define([ var colorsArray = new Float32Array(4 * positionsLength * 2); for ( var j = 0; j < positionsLength; ++j) { - var color = Color.encode(colors[colorIndex]); - var outlineColor = Color.encode(outlineColors[outlineColorIndex]); - + var color = colors[colorIndex]; + var outlineColor = outlineColors[outlineColorIndex]; scratchColorAlpha.red = color.alpha; scratchColorAlpha.green = outlineColor.alpha; - var alpha = Color.encode(scratchColorAlpha); + + var encodedColor = Color.encode(color); + var encodedOutlineColor = Color.encode(outlineColor); + var encodedAlpha = Color.encode(scratchColorAlpha); for (var k = 0; k < 2; ++k) { - colorsArray[index] = color; - colorsArray[index + 1] = outlineColor; - colorsArray[index + 2] = alpha; + colorsArray[index] = encodedColor; + colorsArray[index + 1] = encodedOutlineColor; + colorsArray[index + 2] = encodedAlpha; index += 4; } colorIndex += colorIncrement; outlineColorIndex += outlineColorIncrement; } - buffer.copyFromArrayView(colorsArray, 4 * positionIndex * 2); + buffer.copyFromArrayView(colorsArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); } }; From a705d271f89baf9e77684cf5676a2ed09c699858 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Feb 2013 14:59:13 -0500 Subject: [PATCH 031/114] Add anti-aliasing to polyline outline material. --- .../Materials/PolylineOutlineMaterial.glsl | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl index 84568c6ce3b6..405ab602f862 100644 --- a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl +++ b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl @@ -8,11 +8,27 @@ czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); + vec2 st = materialInput.st; float halfInteriorWidth = 0.5 * (v_width - outlineWidth) / v_width; - float s = step(0.5 - halfInteriorWidth, materialInput.st.t); - s *= 1.0 - step(0.5 + halfInteriorWidth, materialInput.st.t); + float b = step(0.5 - halfInteriorWidth, st.t); + b *= 1.0 - step(0.5 + halfInteriorWidth, st.t); - vec4 color = mix(v_outlineColor, v_color, s); + // Find the distance from the closest separator (region between two colors) + float d1 = abs(st.t - (0.5 - halfInteriorWidth)); + float d2 = abs(st.t - (0.5 + halfInteriorWidth)); + float value = min(d1, d2); + + //anti-aliasing + const float fuzz = 0.1; + float val1 = clamp(value / fuzz, 0.0, 1.0); + float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); + val1 = val1 * (1.0 - val2); + val1 = val1 * val1 * (3.0 - (2.0 * val1)); + val1 = pow(val1, 0.5); //makes the transition nicer + + vec4 midColor = (v_outlineColor + v_color) * 0.5; + vec4 currentColor = mix(v_outlineColor, v_color, b); + vec4 color = mix(midColor, currentColor, val1); material.diffuse = color.rgb; material.alpha = color.a; From 7c9e2d18441ac02a8284ddbe05683080774a69d8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Feb 2013 15:12:01 -0500 Subject: [PATCH 032/114] Add anti-aliasing to the polyline glow material. --- .../Materials/PolylineGlowMaterial.glsl | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl index c6c5c189f62c..c183f8536ba1 100644 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -10,12 +10,30 @@ czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); + vec2 st = materialInput.st; float halfInteriorWidth = 1.0 / v_width; - float s = (1.0 - step(0.5 - halfInteriorWidth, materialInput.st.t)) * dropOffFunction(1.0 - materialInput.st.t); - s += step(0.5 + halfInteriorWidth, materialInput.st.t) * dropOffFunction(materialInput.st.t); + float s = (1.0 - step(0.5 - halfInteriorWidth, st.t)) * dropOffFunction(1.0 - st.t); + s += step(0.5 + halfInteriorWidth, st.t) * dropOffFunction(st.t); float alpha = mix(0.1, 1.0, 1.0 - s); - material.emission = v_color.rgb * alpha; - material.alpha = alpha; + // Find the distance from the closest separator (region between two colors) + float d1 = abs(st.t - (0.5 - halfInteriorWidth)); + float d2 = abs(st.t - (0.5 + halfInteriorWidth)); + float value = min(d1, d2); + + //anti-aliasing + const float fuzz = 0.1; + float val1 = clamp(value / fuzz, 0.0, 1.0); + float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); + val1 = val1 * (1.0 - val2); + val1 = val1 * val1 * (3.0 - (2.0 * val1)); + val1 = pow(val1, 0.5); //makes the transition nicer + + vec4 currentColor = vec4(v_color.rgb * alpha, alpha); + vec4 midColor = (currentColor + v_color) * 0.5; + vec4 color = mix(midColor, currentColor, val1); + + material.emission = color.rgb; + material.alpha = color.a; return material; } From b6e2fd02584cccff5cf508a23bfe633edb963410 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Feb 2013 16:03:24 -0500 Subject: [PATCH 033/114] Make polyline glow brighter. --- Source/Shaders/Materials/PolylineGlowMaterial.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl index c183f8536ba1..f1b0b2ee51a2 100644 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineGlowMaterial.glsl @@ -29,7 +29,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) val1 = val1 * val1 * (3.0 - (2.0 * val1)); val1 = pow(val1, 0.5); //makes the transition nicer - vec4 currentColor = vec4(v_color.rgb * alpha, alpha); + vec4 currentColor = vec4(mix(vec3(0.0), v_color.rgb, 2.0), alpha); vec4 midColor = (currentColor + v_color) * 0.5; vec4 color = mix(midColor, currentColor, val1); From 22e96ac1a03472dcb19882fe9dde633efbe882d3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Feb 2013 16:41:57 -0500 Subject: [PATCH 034/114] Start adding polyline arrow material. --- Apps/Sandcastle/gallery/Polylines.html | 20 ++++++------- Source/Scene/Material.js | 28 ++++++++++++------- Source/Scene/PolylineCollection.js | 2 +- .../Materials/PolylineArrowMaterial.glsl | 28 +++++++++++++++++++ 4 files changed, 57 insertions(+), 21 deletions(-) create mode 100644 Source/Shaders/Materials/PolylineArrowMaterial.glsl diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index f434a14e5414..b4ec563f6745 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -57,14 +57,14 @@ Cesium.Cartographic.fromDegrees(-85.0, 40.0) ])); coloredPolyline.setDefaultColor({ - red : 0.0, + red : 1.0, green : 1.0, - blue : 1.0, + blue : 0.0, alpha : 1.0 }); coloredPolyline.setWidth(20.0); - var material = Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType); - coloredPolyline.setMaterial(material); + var glowMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType); + coloredPolyline.setMaterial(glowMaterial); // set a polyline's color per position @@ -100,9 +100,9 @@ widePolyline.setWidth(10.0); // Set the polyline's material to have an outline - var material = Cesium.Material.fromType(undefined, Cesium.Material.PolylineOutlineType); - material.uniforms.outlineWidth = 5.0; - widePolyline.setMaterial(material); + var outlineMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineOutlineType); + outlineMaterial.uniforms.outlineWidth = 5.0; + widePolyline.setMaterial(outlineMaterial); widePolyline.setDefaultOutlineColor({ red : 1.0, green : 0.0, @@ -121,11 +121,11 @@ Sandcastle.declare(localPolyline); // For highlighting on mouseover in Sandcastle. localPolyline.setPositions([ new Cesium.Cartesian3(0.0, 0.0, 0.0), - new Cesium.Cartesian3(1000000.0, 0.0, 0.0), - new Cesium.Cartesian3(900000.0, -100000.0, 0.0), - new Cesium.Cartesian3(900000.0, 100000.0, 0.0), new Cesium.Cartesian3(1000000.0, 0.0, 0.0) ]); + localPolyline.setWidth(10.0); + var arrowMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineArrowType); + localPolyline.setMaterial(arrowMaterial); primitives.add(localPolylines); } diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index ac66f5875306..2fc38459fe84 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -34,8 +34,9 @@ define([ '../Shaders/Materials/WoodMaterial', '../Shaders/Materials/RimLightingMaterial', '../Shaders/Materials/ErosionMaterial', - '../Shaders/Materials/PolylineOutlineMaterial', - '../Shaders/Materials/PolylineGlowMaterial' + '../Shaders/Materials/PolylineArrowMaterial', + '../Shaders/Materials/PolylineGlowMaterial', + '../Shaders/Materials/PolylineOutlineMaterial' ], function( when, loadImage, @@ -71,8 +72,9 @@ define([ WoodMaterial, RimLightingMaterial, ErosionMaterial, - PolylineOutlineMaterial, - PolylineGlowMaterial) { + PolylineArrowMaterial, + PolylineGlowMaterial, + PolylineOutlineMaterial) { "use strict"; /** @@ -1177,6 +1179,18 @@ define([ source : ErosionMaterial }); + Material.PolylineArrowType = 'PolylineArrow'; + Material._materialCache.addMaterial(Material.PolylineArrowType, { + type : Material.PolylineArrowType, + source : PolylineArrowMaterial + }); + + Material.PolylineGlowType = 'PolylineGlow'; + Material._materialCache.addMaterial(Material.PolylineGlowType, { + type : Material.PolylineGlowType, + source : PolylineGlowMaterial + }); + Material.PolylineOutlineType = 'PolylineOutline'; Material._materialCache.addMaterial(Material.PolylineOutlineType, { type : Material.PolylineOutlineType, @@ -1186,11 +1200,5 @@ define([ source : PolylineOutlineMaterial }); - Material.PolylineGlowType = 'PolylineGlow'; - Material._materialCache.addMaterial(Material.PolylineGlowType, { - type : Material.PolylineGlowType, - source : PolylineGlowMaterial - }); - return Material; }); diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index b39c44883e57..0c79156cb1c2 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1140,7 +1140,7 @@ define([ pickColorArray[colorIndex + 2] = pickColor.blue; pickColorArray[colorIndex + 3] = 255; - miscArray[miscIndex] = j / positionsLength; // s tex coord + miscArray[miscIndex] = j / (positionsLength - 1); // s tex coord miscArray[miscIndex + 1] = 2 * k - 1; // expand direction miscArray[miscIndex + 2] = width; miscArray[miscIndex + 3] = show; diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl new file mode 100644 index 000000000000..43c7d063411e --- /dev/null +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -0,0 +1,28 @@ +varying vec4 v_color; +varying float v_width; + +czm_material czm_getMaterial(czm_materialInput materialInput) +{ + czm_material material = czm_getDefaultMaterial(materialInput); + + vec2 st = materialInput.st; + + float base = 0.75; + vec2 upperBase = vec2(base, 1.0); + vec2 lowerBase = vec2(base, 0.0); + vec2 tip = vec2(1.0, 0.5); + float upperSlope = (upperBase.y - tip.y) / (upperBase.x - tip.x); + float lowerSlope = (lowerBase.y - tip.y) / (lowerBase.x - tip.x); + + float s = step(0.25, st.t); + s *= 1.0 - step(0.75, st.t); + s *= 1.0 - step(base, st.s); + + float t = step(base, materialInput.st.s); + t *= 1.0 - step(upperSlope * (st.s - upperBase.x) + upperBase.y, st.t); + t *= step(lowerSlope * (st.s - lowerBase.x) + lowerBase.y, st.t); + + material.diffuse = v_color.rgb; + material.alpha = clamp(s + t, 0.0, 1.0); + return material; +} From 1dd02c6f1561a5fcc5649eaa769ed56ed433f4fa Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Feb 2013 17:08:44 -0500 Subject: [PATCH 035/114] Tweak polyline arrow material. --- Apps/Sandcastle/gallery/Polylines.html | 2 +- Source/Shaders/Materials/PolylineArrowMaterial.glsl | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index b4ec563f6745..c0edcc7ce567 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -62,7 +62,7 @@ blue : 0.0, alpha : 1.0 }); - coloredPolyline.setWidth(20.0); + coloredPolyline.setWidth(10.0); var glowMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType); coloredPolyline.setMaterial(glowMaterial); diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index 43c7d063411e..cca86f82d5ee 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -14,8 +14,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float upperSlope = (upperBase.y - tip.y) / (upperBase.x - tip.x); float lowerSlope = (lowerBase.y - tip.y) / (lowerBase.x - tip.x); - float s = step(0.25, st.t); - s *= 1.0 - step(0.75, st.t); + float halfWidth = 0.15; + float s = step(0.5 - halfWidth, st.t); + s *= 1.0 - step(0.5 + halfWidth, st.t); s *= 1.0 - step(base, st.s); float t = step(base, materialInput.st.s); From c2842e8fc3d7ace12c289ae06a1a0e04b95a521d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Feb 2013 19:49:20 -0500 Subject: [PATCH 036/114] Tweak polyline arrow shader. --- Source/Shaders/Materials/PolylineArrowMaterial.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index cca86f82d5ee..1557746fcce4 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -7,7 +7,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec2 st = materialInput.st; - float base = 0.75; + float base = 1.0 - dFdx(st.s) * 10.0; vec2 upperBase = vec2(base, 1.0); vec2 lowerBase = vec2(base, 0.0); vec2 tip = vec2(1.0, 0.5); From efd3c5152cf77d468d91763d9140263d46e04bc3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Feb 2013 20:16:26 -0500 Subject: [PATCH 037/114] Add anti-aliasing to polyline arrow material. --- .../Materials/PolylineArrowMaterial.glsl | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index 1557746fcce4..7bbe9a4a5556 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -1,6 +1,12 @@ varying vec4 v_color; varying float v_width; +float getPointOnLine(vec2 p0, vec2 p1, float x) +{ + float slope = (p0.y - p1.y) / (p0.x - p1.x); + return slope * (x - p0.x) + p0.y; +} + czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); @@ -8,11 +14,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec2 st = materialInput.st; float base = 1.0 - dFdx(st.s) * 10.0; - vec2 upperBase = vec2(base, 1.0); - vec2 lowerBase = vec2(base, 0.0); - vec2 tip = vec2(1.0, 0.5); - float upperSlope = (upperBase.y - tip.y) / (upperBase.x - tip.x); - float lowerSlope = (lowerBase.y - tip.y) / (lowerBase.x - tip.x); + vec2 center = vec2(1.0, 0.5); + float ptOnUpperLine = getPointOnLine(vec2(base, 1.0), center, st.s); + float ptOnLowerLine = getPointOnLine(vec2(base, 0.0), center, st.s); float halfWidth = 0.15; float s = step(0.5 - halfWidth, st.t); @@ -20,10 +24,43 @@ czm_material czm_getMaterial(czm_materialInput materialInput) s *= 1.0 - step(base, st.s); float t = step(base, materialInput.st.s); - t *= 1.0 - step(upperSlope * (st.s - upperBase.x) + upperBase.y, st.t); - t *= step(lowerSlope * (st.s - lowerBase.x) + lowerBase.y, st.t); + t *= 1.0 - step(ptOnUpperLine, st.t); + t *= step(ptOnLowerLine, st.t); + + // Find the distance from the closest separator (region between two colors) + float value; + if (st.s < base) + { + float d1 = abs(st.t - (0.5 - halfWidth)); + float d2 = abs(st.t - (0.5 + halfWidth)); + value = min(d1, d2); + } + else + { + float d1 = czm_infinity; + if (st.t < 0.5 - halfWidth && st.t > 0.5 + halfWidth) + { + d1 = abs(st.s - base); + } + float d2 = abs(st.t - ptOnUpperLine); + float d3 = abs(st.t - ptOnLowerLine); + value = min(min(d1, d2), d3); + } + + //anti-aliasing + const float fuzz = 0.1; + float val1 = clamp(value / fuzz, 0.0, 1.0); + float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); + val1 = val1 * (1.0 - val2); + val1 = val1 * val1 * (3.0 - (2.0 * val1)); + val1 = pow(val1, 0.5); //makes the transition nicer + + vec4 outsideColor = vec4(0.0); + vec4 midColor = (outsideColor + v_color) * 0.5; + vec4 currentColor = mix(outsideColor, v_color, clamp(s + t, 0.0, 1.0)); + vec4 color = mix(midColor, currentColor, val1); - material.diffuse = v_color.rgb; - material.alpha = clamp(s + t, 0.0, 1.0); + material.diffuse = color.rgb; + material.alpha = color.a; return material; } From 974873a295316d095884ae8ad9167295864a8372 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 1 Mar 2013 17:37:54 -0500 Subject: [PATCH 038/114] Start adding fade material. --- Source/Scene/Material.js | 18 +++++++++++ Source/Shaders/Materials/FadeMaterial.glsl | 36 ++++++++++++++++++++++ Source/Shaders/PolylineFS.glsl | 2 +- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 Source/Shaders/Materials/FadeMaterial.glsl diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 2fc38459fe84..d02c77aff40b 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -10,6 +10,7 @@ define([ '../Core/defaultValue', '../Core/destroyObject', '../Core/Cartesian2', + '../Core/Cartesian3', '../Core/Matrix2', '../Core/Matrix3', '../Core/Matrix4', @@ -34,6 +35,7 @@ define([ '../Shaders/Materials/WoodMaterial', '../Shaders/Materials/RimLightingMaterial', '../Shaders/Materials/ErosionMaterial', + '../Shaders/Materials/FadeMaterial', '../Shaders/Materials/PolylineArrowMaterial', '../Shaders/Materials/PolylineGlowMaterial', '../Shaders/Materials/PolylineOutlineMaterial' @@ -48,6 +50,7 @@ define([ defaultValue, destroyObject, Cartesian2, + Cartesian3, Matrix2, Matrix3, Matrix4, @@ -72,6 +75,7 @@ define([ WoodMaterial, RimLightingMaterial, ErosionMaterial, + FadeMaterial, PolylineArrowMaterial, PolylineGlowMaterial, PolylineOutlineMaterial) { @@ -1179,6 +1183,20 @@ define([ source : ErosionMaterial }); + Material.FadeType = 'Fade'; + Material._materialCache.addMaterial(Material.FadeType, { + type : Material.FadeType, + uniforms : { + fadeInAlpha : 1.0, + fadeOutAlpha : 0.0, + maxDistance : 0.5, + repeat : true, + time : Cartesian3.ZERO.clone(), + color : new Color(1.0, 0.0, 0.0, 1.0) + }, + source : FadeMaterial + }); + Material.PolylineArrowType = 'PolylineArrow'; Material._materialCache.addMaterial(Material.PolylineArrowType, { type : Material.PolylineArrowType, diff --git a/Source/Shaders/Materials/FadeMaterial.glsl b/Source/Shaders/Materials/FadeMaterial.glsl new file mode 100644 index 000000000000..3ff7079acee8 --- /dev/null +++ b/Source/Shaders/Materials/FadeMaterial.glsl @@ -0,0 +1,36 @@ +uniform float fadeInAlpha; +uniform float fadeOutAlpha; +uniform float maxDistance; +uniform bool repeat; +uniform vec3 time; + +uniform vec4 color; + +float getTime(float t, float coord) +{ + float scalar = 1.0 / maxDistance; + float q = distance(t, coord) * scalar; + if (repeat) + { + float r = distance(t, coord + 1.0) * scalar; + float s = distance(t, coord - 1.0) * scalar; + q = min(min(r, s), q); + } + return clamp(q, 0.0, 1.0); +} + +czm_material czm_getMaterial(czm_materialInput materialInput) +{ + czm_material material = czm_getDefaultMaterial(materialInput); + + vec2 st = materialInput.st; + float t = getTime(time.x, st.s); + float u = getTime(time.y, st.t); + float v = clamp(t * u, 0.0, 1.0); + float alpha = mix(fadeInAlpha * color.a, fadeOutAlpha * color.a, v); + + material.diffuse = color.rgb; + material.alpha = alpha; + + return material; +} diff --git a/Source/Shaders/PolylineFS.glsl b/Source/Shaders/PolylineFS.glsl index 1ef60da551ce..9b9a75a3cdf7 100644 --- a/Source/Shaders/PolylineFS.glsl +++ b/Source/Shaders/PolylineFS.glsl @@ -5,7 +5,7 @@ void main() { czm_materialInput materialInput; - materialInput.s = v_textureCoordinates.r; + materialInput.s = v_textureCoordinates.s; materialInput.st = v_textureCoordinates; materialInput.str = vec3(v_textureCoordinates, 0.0); From 9afd1f9aea1ec4a4573dbb4a2843716384a10148 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 1 Mar 2013 19:27:55 -0500 Subject: [PATCH 039/114] Do not request stencil buffer by default when creating a context or pick framebuffer. --- Source/Renderer/Context.js | 2 +- Source/Renderer/PickFramebuffer.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Renderer/Context.js b/Source/Renderer/Context.js index 51b434bfe797..3a23b3ba668d 100644 --- a/Source/Renderer/Context.js +++ b/Source/Renderer/Context.js @@ -183,7 +183,7 @@ define([ options = {}; } if (typeof options.stencil === 'undefined') { - options.stencil = true; + options.stencil = false; } if (typeof options.alpha === 'undefined') { options.alpha = false; diff --git a/Source/Renderer/PickFramebuffer.js b/Source/Renderer/PickFramebuffer.js index ac55412e5f15..0e645394c32a 100644 --- a/Source/Renderer/PickFramebuffer.js +++ b/Source/Renderer/PickFramebuffer.js @@ -56,8 +56,8 @@ define([ this._fb = this._fb && this._fb.destroy(); this._fb = context.createFramebuffer({ colorRenderbuffer : context.createRenderbuffer(), - depthStencilRenderbuffer : context.createRenderbuffer({ - format : RenderbufferFormat.DEPTH_STENCIL + depthRenderbuffer : context.createRenderbuffer({ + format : RenderbufferFormat.DEPTH_COMPONENT16 }) }); } From dd1b6cc74b994eead87d427b549c88628f193278 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 4 Mar 2013 14:21:04 -0500 Subject: [PATCH 040/114] Fix polyline flickering and vertex expansion at end points. --- Source/Scene/PolylineCollection.js | 7 +--- Source/Shaders/BuiltinFunctions.glsl | 29 +++++++++++++- Source/Shaders/PolylineVS.glsl | 58 +++++++++++++++++++--------- 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 0c79156cb1c2..61c7533aa77e 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1030,16 +1030,13 @@ define([ function computeAdjacencyAngles(position, index, positions, result, modelMatrix) { // TODO handle cross idl - var currentPosition = position; if (typeof result === 'undefined') { result = new Cartesian4(); } var prev = computeAdjacencyAnglesPosition; if (index === 0) { - prev = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[1], prev) : Matrix4.multiplyByPoint(modelMatrix, positions[1], prev); - Cartesian3.subtract(prev, currentPosition, prev); - Cartesian3.negate(prev, prev); + Cartesian3.ZERO.clone(prev); } else { prev = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[index - 1], prev) : Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); Cartesian3.subtract(prev, position, prev); @@ -1050,7 +1047,7 @@ define([ var next = computeAdjacencyAnglesPosition; if (index === positions.length - 1) { - Cartesian3.negate(prev, next); + Cartesian3.ZERO.clone(next); } else { next = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[index + 1], next) : Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); Cartesian3.subtract(next, position, next); diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index feb380d650bf..373ad2b1f48b 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -63,11 +63,38 @@ const float czm_epsilon6 = 0.000001; const float czm_epsilon7 = 0.0000001; /** - * DOC_TBA + * Compares left and right componentwise. Returns true + * if they are within epsilon and false otherwise. The inputs + * left and right can be floats, vec2s, + * vec3s, or vec4s. * * @name czm_equalsEpsilon * @glslFunction + * + * @param {} left The first vector. + * @param {} right The second vector. + * @param {float} epsilon The epsilon to use for equality testing. + * @returns {bool} true if the components are within epsilon and false otherwise. + * + * @example + * // GLSL declarations + * bool czm_equalsEpsilon(float left, float right, float epsilon); + * bool czm_equalsEpsilon(vec2 left, vec2 right, float epsilon); + * bool czm_equalsEpsilon(vec3 left, vec3 right, float epsilon); + * bool czm_equalsEpsilon(vec4 left, vec4 right, float epsilon); */ +bool czm_equalsEpsilon(vec4 left, vec4 right, float epsilon) { + return all(lessThanEqual(abs(left - right), vec4(epsilon))); +} + +bool czm_equalsEpsilon(vec3 left, vec3 right, float epsilon) { + return all(lessThanEqual(abs(left - right), vec3(epsilon))); +} + +bool czm_equalsEpsilon(vec2 left, vec2 right, float epsilon) { + return all(lessThanEqual(abs(left - right), vec2(epsilon))); +} + bool czm_equalsEpsilon(float left, float right, float epsilon) { return (abs(left - right) <= epsilon); } diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 31747c7436ca..088b0d43922d 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -63,31 +63,51 @@ void main() } vec4 positionEC = czm_modelViewRelativeToEye * p; - vec4 prevEC = czm_modelView * prevDir; - vec4 nextEC = czm_modelView * nextDir; - - float pixelSize = czm_pixelSize * abs(positionEC.z); - - vec4 p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); - vec4 p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); vec4 endPointWC = czm_eyeToWindowCoordinates(positionEC); - vec2 nextWC = normalize(p0.xy - endPointWC.xy); - vec2 prevWC = normalize(p1.xy - endPointWC.xy); - vec2 normal = normalize(vec2(nextWC.y, -nextWC.x)); + float pixelSize = czm_pixelSize * abs(positionEC.z); + float expandWidth = width * 0.5; + vec4 prevEC, nextEC, p0, p1; + vec2 direction, nextWC, prevWC; - vec2 direction = normalize((nextWC + prevWC) * 0.5); - if (dot(direction, normal) < 0.0) + if (czm_equalsEpsilon(prevDir, vec4(0.0), czm_epsilon7)) { - direction = -direction; + nextEC = czm_modelView * nextDir; + p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); + nextWC = normalize(p1.xy - endPointWC.xy); + direction = normalize(vec2(nextWC.y, -nextWC.x)); } - - float angle = acos(dot(direction, nextWC)); - float sinAngle = sin(angle); - float expandWidth = width * 0.5; - if (abs(sinAngle) > czm_epsilon1 * 2.5) + else if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7)) + { + prevEC = czm_modelView * prevDir; + p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); + prevWC = normalize(p0.xy - endPointWC.xy); + direction = -normalize(vec2(prevWC.y, -prevWC.x)); + } + else { - expandWidth = expandWidth / sinAngle; + prevEC = czm_modelView * prevDir; + nextEC = czm_modelView * nextDir; + + p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); + p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); + + prevWC = normalize(p0.xy - endPointWC.xy); + nextWC = normalize(p1.xy - endPointWC.xy); + vec2 normal = normalize(vec2(nextWC.y, -nextWC.x)); + + direction = normalize((nextWC + prevWC) * 0.5); + if (dot(direction, normal) < 0.0) + { + direction = -direction; + } + + float angle = acos(dot(direction, nextWC)); + float sinAngle = sin(angle); + if (abs(sinAngle) > czm_epsilon1 * 2.5) + { + expandWidth = expandWidth / sinAngle; + } } vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, -endPointWC.z, 1.0); From 79d05d42a59f8b3a1fea18e33b8441f7e46c70d7 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 4 Mar 2013 15:03:27 -0500 Subject: [PATCH 041/114] Tweak fade material. --- Source/Shaders/Materials/FadeMaterial.glsl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/Materials/FadeMaterial.glsl b/Source/Shaders/Materials/FadeMaterial.glsl index 3ff7079acee8..8db6cf6f5031 100644 --- a/Source/Shaders/Materials/FadeMaterial.glsl +++ b/Source/Shaders/Materials/FadeMaterial.glsl @@ -26,8 +26,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec2 st = materialInput.st; float t = getTime(time.x, st.s); float u = getTime(time.y, st.t); - float v = clamp(t * u, 0.0, 1.0); - float alpha = mix(fadeInAlpha * color.a, fadeOutAlpha * color.a, v); + + float v = (1.0 - t) * (1.0 - u); + float alpha = mix(fadeOutAlpha * color.a, fadeInAlpha * color.a, v); material.diffuse = color.rgb; material.alpha = alpha; From 6ea64b96d07ea7f0028b9f8abd46c5c7d2ef6190 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 4 Mar 2013 15:44:04 -0500 Subject: [PATCH 042/114] Change fade material to use fade in and out colors instead of alpha values. Add uniforms to disable fade directions. --- Source/Scene/Material.js | 13 +++++++------ Source/Shaders/Materials/FadeMaterial.glsl | 19 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index d02c77aff40b..55e43f9fb47a 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -10,7 +10,6 @@ define([ '../Core/defaultValue', '../Core/destroyObject', '../Core/Cartesian2', - '../Core/Cartesian3', '../Core/Matrix2', '../Core/Matrix3', '../Core/Matrix4', @@ -50,7 +49,6 @@ define([ defaultValue, destroyObject, Cartesian2, - Cartesian3, Matrix2, Matrix3, Matrix4, @@ -1187,12 +1185,15 @@ define([ Material._materialCache.addMaterial(Material.FadeType, { type : Material.FadeType, uniforms : { - fadeInAlpha : 1.0, - fadeOutAlpha : 0.0, + fadeInColor : new Color(1.0, 0.0, 0.0, 1.0), + fadeOutColor : new Color(0.0, 0.0, 0.0, 0.0), maxDistance : 0.5, repeat : true, - time : Cartesian3.ZERO.clone(), - color : new Color(1.0, 0.0, 0.0, 1.0) + fadeDirection : { + x : true, + y : true + }, + time : Cartesian2.ZERO.clone() }, source : FadeMaterial }); diff --git a/Source/Shaders/Materials/FadeMaterial.glsl b/Source/Shaders/Materials/FadeMaterial.glsl index 8db6cf6f5031..eda5d7e1b20f 100644 --- a/Source/Shaders/Materials/FadeMaterial.glsl +++ b/Source/Shaders/Materials/FadeMaterial.glsl @@ -1,10 +1,9 @@ -uniform float fadeInAlpha; -uniform float fadeOutAlpha; +uniform vec4 fadeInColor; +uniform vec4 fadeOutColor; uniform float maxDistance; uniform bool repeat; -uniform vec3 time; - -uniform vec4 color; +uniform vec2 fadeDirection; +uniform vec2 time; float getTime(float t, float coord) { @@ -24,14 +23,14 @@ czm_material czm_getMaterial(czm_materialInput materialInput) czm_material material = czm_getDefaultMaterial(materialInput); vec2 st = materialInput.st; - float t = getTime(time.x, st.s); - float u = getTime(time.y, st.t); + float s = getTime(time.x, st.s) * fadeDirection.s; + float t = getTime(time.y, st.t) * fadeDirection.t; - float v = (1.0 - t) * (1.0 - u); - float alpha = mix(fadeOutAlpha * color.a, fadeInAlpha * color.a, v); + float u = length(vec2(s, t)); + vec4 color = mix(fadeInColor, fadeOutColor, u); material.diffuse = color.rgb; - material.alpha = alpha; + material.alpha = color.a; return material; } From c571aad9010933ff7fc363411d2e655e2b60e8a6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 4 Mar 2013 16:33:23 -0500 Subject: [PATCH 043/114] Tweak fade material lighting. --- Source/Shaders/Materials/FadeMaterial.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/Materials/FadeMaterial.glsl b/Source/Shaders/Materials/FadeMaterial.glsl index eda5d7e1b20f..711cda805304 100644 --- a/Source/Shaders/Materials/FadeMaterial.glsl +++ b/Source/Shaders/Materials/FadeMaterial.glsl @@ -29,7 +29,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) float u = length(vec2(s, t)); vec4 color = mix(fadeInColor, fadeOutColor, u); - material.diffuse = color.rgb; + material.emission = color.rgb; material.alpha = color.a; return material; From 78f10ec1c46874bbd5154a69f35c13c390c7eee9 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 6 Mar 2013 16:52:53 -0500 Subject: [PATCH 044/114] Enable standard derivatives extension in polyline arrow shader. --- Source/Shaders/Materials/PolylineArrowMaterial.glsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index 7bbe9a4a5556..a67f3b30888f 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -1,3 +1,5 @@ +#extension GL_OES_standard_derivatives : enable // TODO check for support + varying vec4 v_color; varying float v_width; From 517e15252b76089e664518e10f31d0f1426b88b1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 6 Mar 2013 16:55:04 -0500 Subject: [PATCH 045/114] Modify polyline vertex shader to make triangles front facing. --- Source/Shaders/PolylineVS.glsl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 088b0d43922d..bb4e428b3d0b 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -75,14 +75,14 @@ void main() nextEC = czm_modelView * nextDir; p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); nextWC = normalize(p1.xy - endPointWC.xy); - direction = normalize(vec2(nextWC.y, -nextWC.x)); + direction = -normalize(vec2(nextWC.y, -nextWC.x)); } else if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7)) { prevEC = czm_modelView * prevDir; p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); prevWC = normalize(p0.xy - endPointWC.xy); - direction = -normalize(vec2(prevWC.y, -prevWC.x)); + direction = normalize(vec2(prevWC.y, -prevWC.x)); } else { @@ -94,7 +94,7 @@ void main() prevWC = normalize(p0.xy - endPointWC.xy); nextWC = normalize(p1.xy - endPointWC.xy); - vec2 normal = normalize(vec2(nextWC.y, -nextWC.x)); + vec2 normal = -normalize(vec2(nextWC.y, -nextWC.x)); direction = normalize((nextWC + prevWC) * 0.5); if (dot(direction, normal) < 0.0) From c092829eae0a52a8a6fd7fdf8490ccbff811a02e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 6 Mar 2013 17:25:35 -0500 Subject: [PATCH 046/114] Fix line expansion in 2D and Columbus view. --- Source/Shaders/PolylineVS.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index bb4e428b3d0b..c29c6dddc379 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -40,8 +40,8 @@ void main() else if (u_morphTime == 0.0) { p = vec4(czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), 1.0); - prevDir = vec4(czm_sphericalToCartesianCoordinates(prev.zw), 0.0); - nextDir = vec4(czm_sphericalToCartesianCoordinates(next.zw), 0.0); + prevDir = vec4(czm_sphericalToCartesianCoordinates(prev.zw).zxy, 0.0); + nextDir = vec4(czm_sphericalToCartesianCoordinates(next.zw).zxy, 0.0); } else { From 7f8e6db51ce973efa7f32f7e6224e50c5c3788eb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 12 Mar 2013 20:04:06 -0400 Subject: [PATCH 047/114] Fix offscreen rendering artifact. --- Source/Shaders/PolylineVS.glsl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index c29c6dddc379..cd5007a8a82c 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -7,7 +7,6 @@ attribute vec4 next; attribute vec4 color; attribute vec4 misc; - #ifndef RENDER_FOR_PICK varying vec4 v_color; varying vec4 v_outlineColor; @@ -75,7 +74,7 @@ void main() nextEC = czm_modelView * nextDir; p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); nextWC = normalize(p1.xy - endPointWC.xy); - direction = -normalize(vec2(nextWC.y, -nextWC.x)); + direction = normalize(vec2(-nextWC.y, nextWC.x)); } else if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7)) { @@ -94,7 +93,7 @@ void main() prevWC = normalize(p0.xy - endPointWC.xy); nextWC = normalize(p1.xy - endPointWC.xy); - vec2 normal = -normalize(vec2(nextWC.y, -nextWC.x)); + vec2 normal = normalize(vec2(-nextWC.y, nextWC.x)); direction = normalize((nextWC + prevWC) * 0.5); if (dot(direction, normal) < 0.0) @@ -110,8 +109,8 @@ void main() } } - vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, -endPointWC.z, 1.0); - gl_Position = czm_viewportOrthographic * positionWC * show; + vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, endPointWC.zw); + gl_Position = czm_projection * czm_windowToEyeCoordinates(positionWC) * show; #ifndef RENDER_FOR_PICK vec3 alphas = czm_decodeColor(color.b); From 9490a2598735d9bc4d146a94d0129398f8d042c2 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 14 Mar 2013 12:37:58 -0400 Subject: [PATCH 048/114] Remove glow material. --- Apps/Sandcastle/gallery/Polylines.html | 3 -- Source/Scene/Material.js | 8 ---- .../Materials/PolylineGlowMaterial.glsl | 39 ------------------- 3 files changed, 50 deletions(-) delete mode 100644 Source/Shaders/Materials/PolylineGlowMaterial.glsl diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index c0edcc7ce567..f80d2e61f768 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -62,9 +62,6 @@ blue : 0.0, alpha : 1.0 }); - coloredPolyline.setWidth(10.0); - var glowMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineGlowType); - coloredPolyline.setMaterial(glowMaterial); // set a polyline's color per position diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 55e43f9fb47a..489b4e7bc604 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -36,7 +36,6 @@ define([ '../Shaders/Materials/ErosionMaterial', '../Shaders/Materials/FadeMaterial', '../Shaders/Materials/PolylineArrowMaterial', - '../Shaders/Materials/PolylineGlowMaterial', '../Shaders/Materials/PolylineOutlineMaterial' ], function( when, @@ -75,7 +74,6 @@ define([ ErosionMaterial, FadeMaterial, PolylineArrowMaterial, - PolylineGlowMaterial, PolylineOutlineMaterial) { "use strict"; @@ -1204,12 +1202,6 @@ define([ source : PolylineArrowMaterial }); - Material.PolylineGlowType = 'PolylineGlow'; - Material._materialCache.addMaterial(Material.PolylineGlowType, { - type : Material.PolylineGlowType, - source : PolylineGlowMaterial - }); - Material.PolylineOutlineType = 'PolylineOutline'; Material._materialCache.addMaterial(Material.PolylineOutlineType, { type : Material.PolylineOutlineType, diff --git a/Source/Shaders/Materials/PolylineGlowMaterial.glsl b/Source/Shaders/Materials/PolylineGlowMaterial.glsl deleted file mode 100644 index f1b0b2ee51a2..000000000000 --- a/Source/Shaders/Materials/PolylineGlowMaterial.glsl +++ /dev/null @@ -1,39 +0,0 @@ -varying vec4 v_color; -varying float v_width; - -float dropOffFunction(float value) -{ - return value * value; -} - -czm_material czm_getMaterial(czm_materialInput materialInput) -{ - czm_material material = czm_getDefaultMaterial(materialInput); - - vec2 st = materialInput.st; - float halfInteriorWidth = 1.0 / v_width; - float s = (1.0 - step(0.5 - halfInteriorWidth, st.t)) * dropOffFunction(1.0 - st.t); - s += step(0.5 + halfInteriorWidth, st.t) * dropOffFunction(st.t); - float alpha = mix(0.1, 1.0, 1.0 - s); - - // Find the distance from the closest separator (region between two colors) - float d1 = abs(st.t - (0.5 - halfInteriorWidth)); - float d2 = abs(st.t - (0.5 + halfInteriorWidth)); - float value = min(d1, d2); - - //anti-aliasing - const float fuzz = 0.1; - float val1 = clamp(value / fuzz, 0.0, 1.0); - float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); - val1 = val1 * (1.0 - val2); - val1 = val1 * val1 * (3.0 - (2.0 * val1)); - val1 = pow(val1, 0.5); //makes the transition nicer - - vec4 currentColor = vec4(mix(vec3(0.0), v_color.rgb, 2.0), alpha); - vec4 midColor = (currentColor + v_color) * 0.5; - vec4 color = mix(midColor, currentColor, val1); - - material.emission = color.rgb; - material.alpha = color.a; - return material; -} From bab3c9b78a3cfe8de8b4dd0a4291293e00426fd1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 14 Mar 2013 17:05:09 -0400 Subject: [PATCH 049/114] Clean up polyline. --- Source/Core/PolylinePipeline.js | 42 +++---- Source/Scene/Polyline.js | 111 ++++++----------- Source/Scene/PolylineCollection.js | 183 ++++++++--------------------- Specs/Core/PolylinePipelineSpec.js | 16 +-- 4 files changed, 113 insertions(+), 239 deletions(-) diff --git a/Source/Core/PolylinePipeline.js b/Source/Core/PolylinePipeline.js index b3ac4c7736db..5643bb6a99e9 100644 --- a/Source/Core/PolylinePipeline.js +++ b/Source/Core/PolylinePipeline.js @@ -41,7 +41,8 @@ define([ * the upper three elements in the fourth column are the translation. The bottom row is assumed to be [0, 0, 0, 1]. * The matrix is not verified to be in the proper form. * - * @returns An array of polyline segment objects containing the Cartesian position and indices. + * @returns {Object} An object with a positions property that is an array of positions and a + * segments property. * * @see Polyline * @see PolylineCollection @@ -54,6 +55,7 @@ define([ * var segments = PolylinePipeline.wrapLongitude(positions, modelMatrix); */ PolylinePipeline.wrapLongitude = function(positions, modelMatrix) { + var cartesians = []; var segments = []; if (typeof positions !== 'undefined' && positions.length > 0) { @@ -66,11 +68,9 @@ define([ var yzNormal = Matrix4.multiplyByVector(inverseModelMatrix, Cartesian4.UNIT_X, wrapLongitudeYZNormal); var yzPlane = Plane.fromPointNormal(origin, yzNormal, wrapLongitudeYZPlane); - var currentSegment = [{ - cartesian : Cartesian3.clone(positions[0]), - index : 0 - }]; - var prev = currentSegment[0].cartesian; + var count = 1; + cartesians.push(Cartesian3.clone(positions[0])); + var prev = cartesians[0]; var length = positions.length; for ( var i = 1; i < length; ++i) { @@ -87,36 +87,28 @@ define([ Cartesian3.negate(offset, offset); } - currentSegment.push({ - cartesian : Cartesian3.add(intersection, offset), - index : i - }); - segments.push(currentSegment); + cartesians.push(Cartesian3.add(intersection, offset)); + segments.push(count + 1); Cartesian3.negate(offset, offset); - - currentSegment = []; - currentSegment.push({ - cartesian : Cartesian3.add(intersection, offset), - index : i - }); + cartesians.push(Cartesian3.add(intersection, offset)); + count = 1; } } - currentSegment.push({ - cartesian : Cartesian3.clone(positions[i]), - index : i - }); + cartesians.push(Cartesian3.clone(positions[i])); + count++; prev = cur; } - if (currentSegment.length > 1) { - segments.push(currentSegment); - } + segments.push(count); } - return segments; + return { + positions : cartesians, + lengths : segments + }; }; return PolylinePipeline; diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index ef307e5b8278..d7ba64f87d07 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -7,6 +7,7 @@ define([ '../Core/Cartesian3', '../Core/Color', '../Core/PolylinePipeline', + '../Core/Matrix4', './Material' ], function( defaultValue, @@ -16,6 +17,7 @@ define([ Cartesian3, Color, PolylinePipeline, + Matrix4, Material) { "use strict"; @@ -49,15 +51,22 @@ define([ } this._positions = positions; - this._positionsLength = positions.length; - this._actualLength = positions.length; + + var modelMatrix; + if (typeof this._polylineCollection !== 'undefined') { + modelMatrix = Matrix4.clone(this._polylineCollection.modelMatrix); + } + + this._modelMatrix = modelMatrix; + this._segments = PolylinePipeline.wrapLongitude(positions, modelMatrix); + + this._actualLength = undefined; this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES); this._polylineCollection = polylineCollection; this._dirty = false; this._pickId = undefined; this._pickIdThis = description._pickIdThis; - this._segments = undefined; this._boundingVolume = BoundingSphere.fromPoints(this._positions); this._boundingVolume2D = new BoundingSphere(); // modified in PolylineCollection }; @@ -153,8 +162,7 @@ define([ throw new DeveloperError('value is required.'); } - if (this._positionsLength !== value.length) { - this._positionsLength = value.length; + if (this._positions.length !== value.length) { makeDirty(this, POSITION_SIZE_INDEX); } @@ -163,6 +171,28 @@ define([ makeDirty(this, POSITION_INDEX); }; + /** + * @private + */ + Polyline.prototype.update = function() { + var modelMatrix = Matrix4.IDENTITY; + if (typeof this._polylineCollection !== 'undefined') { + modelMatrix = this._polylineCollection.modelMatrix; + } + + var length = this._segments.lengths.length; + this._modelMatrix = modelMatrix; + + var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; + if (!modelMatrix.equals(this._modelMatrix) || positionsChanged) { + this._segments = PolylinePipeline.wrapLongitude(this._positions, modelMatrix); + } + + if (this._segments.lengths.length !== length) { + makeDirty(this, POSITION_SIZE_INDEX); + } + }; + /** * TODO * @returns @@ -263,22 +293,16 @@ define([ /** * Gets the width of the polyline. - * The actual width used is clamped to the minimum and maximum width supported by - * the WebGL implementation. These can be queried with - * {@link Context#getMinimumAliasedLineWidth} and {@link Context#getMaximumAliasedLineWidth}. * * @memberof Polyline * * @return {Number} The width of the polyline. * * @see Polyline#setWidth - * @see Context#getMinimumAliasedLineWidth - * @see Context#getMaximumAliasedLineWidth * * @example - * // 3 pixel total width, 1 pixel interior width - * polyline.width = 1.0; - * polyline.outlineWidth = 3.0; + * polyline.setWidth(5.0); + * var width = polyline.getWidth(); // 5.0 */ Polyline.prototype.getWidth = function() { return this._width; @@ -286,22 +310,16 @@ define([ /** * Sets the width of the polyline. - * The actual width used is clamped to the minimum and maximum width supported by - * the WebGL implementation. These can be queried with - * {@link Context#getMinimumAliasedLineWidth} and {@link Context#getMaximumAliasedLineWidth}. * * @param {Number} value The width of the polyline. * * @exception {DeveloperError} value is required. * * @see Polyline#getWidth - * @see Context#getMinimumAliasedLineWidth - * @see Context#getMaximumAliasedLineWidth * * @example - * // 3 pixel total width, 1 pixel interior width - * polyline.width = 1.0; - * polyline.outlineWidth = 3.0; + * polyline.setWidth(5.0); + * var width = polyline.getWidth(); // 5.0 */ Polyline.prototype.setWidth = function(value) { if (typeof value === 'undefined') { @@ -405,57 +423,6 @@ define([ } }; - Polyline.prototype._getPositions2D = function() { - var segments = this._segments; - var positions = []; - var numberOfSegments = segments.length; - - for ( var i = 0; i < numberOfSegments; ++i) { - var segment = segments[i]; - var segmentLength = segment.length; - for ( var n = 0; n < segmentLength; ++n) { - positions.push(segment[n].cartesian); - } - } - return positions; - }; - - Polyline.prototype._createSegments = function(modelMatrix) { - return PolylinePipeline.wrapLongitude(this.getPositions(), modelMatrix); - }; - - Polyline.prototype._setSegments = function(segments) { - this._segments = segments; - var numberOfSegments = segments.length; - var length = 0; - for ( var i = 0; i < numberOfSegments; ++i) { - var segment = segments[i]; - var segmentLength = segment.length; - length += segmentLength; - } - return length; - }; - - Polyline.prototype._getSegments = function() { - return this._segments; - }; - - Polyline.prototype._segmentsLengthChanged = function(newSegments) { - var origSegments = this._segments; - if (typeof origSegments !== 'undefined') { - var numberOfSegments = newSegments.length; - if (numberOfSegments !== origSegments.length) { - return true; - } - for ( var i = 0; i < numberOfSegments; ++i) { - if (newSegments[i].length !== origSegments[i].length) { - return true; - } - } - return false; - } - return true; - }; /** * Determines if this polyline equals another polyline. Polylines are equal if all their properties diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 61c7533aa77e..97ecfb9d8ea1 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -49,10 +49,6 @@ define([ PolylineFSPick) { "use strict"; - // TODO: - // better name than 'misc' for tex coord, expansion direction, show and width attribute - // adjacency info in 2d at idl - var MISC_INDEX = Polyline.MISC_INDEX; var POSITION_INDEX = Polyline.POSITION_INDEX; var COLOR_INDEX = Polyline.COLOR_INDEX; @@ -107,9 +103,9 @@ define([ * new Cartographic2(-77.02, 38.53), * new Cartographic2(-80.50, 35.14), * new Cartographic2(-80.12, 25.46)]), - width:2 - }); - + * width:2 + * }); + * * polylines.add({positions:ellipsoid.cartographicDegreesToCartesians([ * new Cartographic2(-73.10, 37.57), * new Cartographic2(-75.02, 36.53), @@ -398,27 +394,17 @@ define([ } else if (this._polylinesUpdated) { // Polylines were modified, but no polylines were added or removed. var polylinesToUpdate = this._polylinesToUpdate; - var createVertexArrays = false; if (this._mode !== SceneMode.SCENE3D) { var updateLength = polylinesToUpdate.length; for ( var i = 0; i < updateLength; ++i) { polyline = polylinesToUpdate[i]; - var changedProperties = polyline._propertiesChanged; - if (changedProperties[POSITION_INDEX]) { - if (intersectsIDL(polyline)) { - var newSegments = polyline._createSegments(this.modelMatrix); - if (polyline._segmentsLengthChanged(newSegments)) { - createVertexArrays = true; - break; - } - polyline._setSegments(newSegments); - } - } + polyline.update(); } } + // if a polyline's positions size changes, we need to recreate the vertex arrays and vertex buffers because the indices will be different. // if a polyline's material changes, we need to recreate the VAOs and VBOs because they will be batched differenty. - if (properties[POSITION_SIZE_INDEX] || properties[MATERIAL_INDEX] || createVertexArrays) { + if (properties[POSITION_SIZE_INDEX] || properties[MATERIAL_INDEX]) { this._createVertexArrays(context); } else { length = polylinesToUpdate.length; @@ -887,6 +873,7 @@ define([ var length = polylines.length; for ( var i = 0; i < length; ++i) { var p = polylines[i]; + p.update(); var material = p.getMaterial(); var hash = this._createMaterialHash(material); var value = polylineBuckets[hash]; @@ -1022,8 +1009,9 @@ define([ if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { return polyline.getPositions().length; } - var segments = polyline._createSegments(this.modelMatrix); - return polyline._setSegments(segments); + + polyline.update(); + return polyline._segments.positions.length; }; var computeAdjacencyAnglesPosition = new Cartesian3(); @@ -1154,66 +1142,34 @@ define([ } }; + var morphPositionScratch = new Cartesian3(); + /** * @private */ PolylineBucket.prototype.writeForMorph = function(positionArray, adjacencyArray, positionIndex, adjacencyIndex) { var modelMatrix = this.modelMatrix; - var position; var polylines = this.polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { var polyline = polylines[i]; - var positions = polyline.getPositions(); - - var numberOfSegments; - var j; - var k; - if (intersectsIDL(polyline)) { - var segments = polyline._getSegments(); - numberOfSegments = segments.length; - for ( j = 0; j < numberOfSegments; ++j) { - var segment = segments[j]; - var segmentLength = segment.length; - for ( var n = 0; n < segmentLength; ++n) { - var index = segment[n].index; - position = positions[index]; - position = modelMatrix.multiplyByPoint(position); - - var adjacencyAngles = computeAdjacencyAngles(position, index, positions, scratchAdjacency, modelMatrix); - - for (k = 0; k < 2; ++k) { - EncodedCartesian3.writeElements(position, positionArray, positionIndex); - - adjacencyArray[adjacencyIndex] = adjacencyAngles.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; - - positionIndex += 6; - adjacencyIndex += 8; - } - } - } - } else { - numberOfSegments = positions.length; - for ( j = 0; j < numberOfSegments; ++j) { - position = positions[j]; - position = modelMatrix.multiplyByPoint(position); + var positions = polyline._segments.positions; + var positionsLength = positions.length; - var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchAdjacency, modelMatrix); + for ( var j = 0; j < positionsLength; ++j) { + var position = Matrix4.multiplyByPoint(modelMatrix, positions[j], morphPositionScratch); + var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchAdjacency, modelMatrix); - for (k = 0; k < 2; ++k) { - EncodedCartesian3.writeElements(position, positionArray, positionIndex); + for (var k = 0; k < 2; ++k) { + EncodedCartesian3.writeElements(position, positionArray, positionIndex); - adjacencyArray[adjacencyIndex] = adjacencyAngles.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + adjacencyArray[adjacencyIndex] = adjacencyAngles.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; - positionIndex += 6; - adjacencyIndex += 8; - } + positionIndex += 6; + adjacencyIndex += 8; } } } @@ -1298,79 +1254,38 @@ define([ var length = polylines.length; for ( var i = 0; i < length; ++i) { var polyline = polylines[i]; - if (intersectsIDL(polyline)) { - var segments = polyline._segments; - var numberOfSegments = segments.length; - if (numberOfSegments > 0) { - for ( var k = 0; k < numberOfSegments; ++k) { - var segment = segments[k]; - var segmentLength = segment.length; - for ( var n = 0; n < segmentLength; ++n) { - if (n !== segmentLength - 1) { - if (indicesCount + 3 >= SIXTYFOURK - 1) { - vertexBufferOffset.push(2); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - count = 0; - offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; - } + var segments = polyline._segments.lengths; + var numberOfSegments = segments.length; + if (numberOfSegments > 0) { + for ( var j = 0; j < numberOfSegments; ++j) { + var segmentLength = segments[j]; + for ( var k = 0; k < segmentLength; ++k) { + if (k !== segmentLength - 1) { + if (indicesCount + 3 >= SIXTYFOURK - 1) { + vertexBufferOffset.push(2); + indices = []; + totalIndices.push(indices); + indicesCount = 0; + bucketLocator.count = count; + count = 0; + offset = 0; + bucketLocator = new VertexArrayBucketLocator(0, 0, this); + vertexArrayBuckets[++vaCount] = [bucketLocator]; + } - indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount, indicesCount + 2, indicesCount + 1); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); - count += 6; - offset += 6; - indicesCount += 2; - } - } - if (k !== numberOfSegments - 1) { + count += 6; + offset += 6; indicesCount += 2; } } - - if (indicesCount + 3 < SIXTYFOURK - 1) { + if (j !== numberOfSegments - 1) { indicesCount += 2; - } else { - vertexBufferOffset.push(0); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - offset = 0; - count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; } } - } else { - var positions = polyline.getPositions(); - var positionsLength = positions.length; - for ( var j = 0; j < positionsLength; ++j) { - if (j !== positionsLength - 1) { - if (indicesCount + 3 >= SIXTYFOURK - 1) { - vertexBufferOffset.push(2); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - count = 0; - offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; - } - indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); - - count += 6; - offset += 6; - indicesCount += 2; - } - } if (indicesCount + 3 < SIXTYFOURK - 1) { indicesCount += 2; } else { @@ -1436,7 +1351,7 @@ define([ return positions; } if (intersectsIDL(polyline)) { - positions = polyline._getPositions2D(); + positions = polyline._segments.positions; } var ellipsoid = this.ellipsoid; diff --git a/Specs/Core/PolylinePipelineSpec.js b/Specs/Core/PolylinePipelineSpec.js index afd9b90f6dae..7e45362b702b 100644 --- a/Specs/Core/PolylinePipelineSpec.js +++ b/Specs/Core/PolylinePipelineSpec.js @@ -21,8 +21,8 @@ defineSuite([ var positions = [ellipsoid.cartographicToCartesian(p1), ellipsoid.cartographicToCartesian(p2)]; var segments = PolylinePipeline.wrapLongitude(positions); - expect(segments.length).toEqual(1); - expect(segments[0].length).toEqual(2); + expect(segments.lengths.length).toEqual(1); + expect(segments.lengths[0]).toEqual(2); }); it('wrapLongitude breaks polyline into segments', function() { @@ -32,9 +32,9 @@ defineSuite([ var positions = [ellipsoid.cartographicToCartesian(p1), ellipsoid.cartographicToCartesian(p2)]; var segments = PolylinePipeline.wrapLongitude(positions); - expect(segments.length).toEqual(2); - expect(segments[0].length).toEqual(2); - expect(segments[1].length).toEqual(2); + expect(segments.lengths.length).toEqual(2); + expect(segments.lengths[0]).toEqual(2); + expect(segments.lengths[1]).toEqual(2); }); it('wrapLongitude breaks polyline into segments with model matrix', function() { @@ -45,8 +45,8 @@ defineSuite([ var positions = [ new Cartesian3(0.0, 0.0, 0.0), new Cartesian3(0.0, 100000000.0, 0.0)]; var segments = PolylinePipeline.wrapLongitude(positions, matrix); - expect(segments.length).toEqual(2); - expect(segments[0].length).toEqual(2); - expect(segments[1].length).toEqual(2); + expect(segments.lengths.length).toEqual(2); + expect(segments.lengths[0]).toEqual(2); + expect(segments.lengths[1]).toEqual(2); }); }); \ No newline at end of file From 5cf7d3b4fe1de25d9a01da745e50622c48b3280a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 14 Mar 2013 17:21:02 -0400 Subject: [PATCH 050/114] Minor polyline collection clean up. --- Source/Scene/PolylineCollection.js | 73 +++--------------------------- 1 file changed, 7 insertions(+), 66 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 97ecfb9d8ea1..ef3b194be107 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -758,94 +758,35 @@ define([ offsetInBytes : vertexMiscBufferOffset }]; - var attributesPickColor = [{ - index : attributeIndices.position3DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position3DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position2DHigh, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.position2DLow, - componentsPerAttribute : 3, - componentDatatype : ComponentDatatype.FLOAT, - offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes - }, { - index : attributeIndices.prev, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : this._adjacencyBuffer, - offsetInBytes : prevOffset, - strideInBytes : 2 * adjacencySizeInBytes - }, { - index : attributeIndices.next, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : this._adjacencyBuffer, - offsetInBytes : nextOffset, - strideInBytes : 2 * adjacencySizeInBytes - }, { - index : attributeIndices.color, - componentsPerAttribute : 4, - normalize : true, - componentDatatype : ComponentDatatype.UNSIGNED_BYTE, - vertexBuffer : this._pickColorBuffer, - offsetInBytes : vertexPickColorBufferOffset - }, { - index : attributeIndices.misc, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : this._miscBuffer, - offsetInBytes : vertexMiscBufferOffset - }]; - if (this._mode === SceneMode.SCENE3D) { attributes[0].vertexBuffer = this._positionBuffer; attributes[1].vertexBuffer = this._positionBuffer; attributes[2].value = [0.0, 0.0, 0.0]; attributes[3].value = [0.0, 0.0, 0.0]; - attributesPickColor[0].vertexBuffer = this._positionBuffer; - attributesPickColor[1].vertexBuffer = this._positionBuffer; - attributesPickColor[2].value = [0.0, 0.0, 0.0]; - attributesPickColor[3].value = [0.0, 0.0, 0.0]; } else if (this._mode === SceneMode.SCENE2D || this._mode === SceneMode.COLUMBUS_VIEW) { attributes[0].value = [0.0, 0.0, 0.0]; attributes[1].value = [0.0, 0.0, 0.0]; attributes[2].vertexBuffer = this._positionBuffer; attributes[3].vertexBuffer = this._positionBuffer; - attributesPickColor[0].value = [0.0, 0.0, 0.0]; - attributesPickColor[1].value = [0.0, 0.0, 0.0]; - attributesPickColor[2].vertexBuffer = this._positionBuffer; - attributesPickColor[3].vertexBuffer = this._positionBuffer; } else { attributes[0].vertexBuffer = position3DBuffer; attributes[1].vertexBuffer = position3DBuffer; attributes[2].vertexBuffer = this._positionBuffer; attributes[3].vertexBuffer = this._positionBuffer; - attributesPickColor[0].vertexBuffer = position3DBuffer; - attributesPickColor[1].vertexBuffer = position3DBuffer; - attributesPickColor[2].vertexBuffer = this._positionBuffer; - attributesPickColor[3].vertexBuffer = this._positionBuffer; } var va = context.createVertexArray(attributes, indexBuffer); - var vaPickColor = context.createVertexArray(attributesPickColor, indexBuffer); this._colorVertexArrays.push({ va : va, buckets : vertexArrayBuckets[k] }); + + attributes[6].componentDatatype = ComponentDatatype.UNSIGNED_BYTE; + attributes[6].vertexBuffer = this._pickColorBuffer; + attributes[6].offsetInBytes = vertexPickColorBufferOffset; + attributes[6].normalize = true; + + var vaPickColor = context.createVertexArray(attributes, indexBuffer); this._pickColorVertexArrays.push({ va : vaPickColor, buckets : vertexArrayBuckets[k] From b39c8f71bde496b847faba0bc2e890404b4a7043 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 18 Mar 2013 14:39:00 -0400 Subject: [PATCH 051/114] Adjust polyline width in VS. --- Source/Shaders/PolylineVS.glsl | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index cd5007a8a82c..5546d562079b 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -103,10 +103,7 @@ void main() float angle = acos(dot(direction, nextWC)); float sinAngle = sin(angle); - if (abs(sinAngle) > czm_epsilon1 * 2.5) - { - expandWidth = expandWidth / sinAngle; - } + expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0); } vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, endPointWC.zw); From 1998e9addf86980ac034dcbfb5a2931ddd9df2be Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 18 Mar 2013 15:00:44 -0400 Subject: [PATCH 052/114] Sort polylines by material. --- Source/Scene/Material.js | 8 ++++++++ Source/Scene/PolylineCollection.js | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 11214f96c76e..30af92919a97 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -357,8 +357,16 @@ define([ value : this.type, writable : false }); + + if (typeof Material._uniformList[this.type] === 'undefined') { + Material._uniformList[this.type] = Object.keys(this._uniforms); + } }; + // Cached list of combined uniform names indexed by type. + // Used to get the list of uniforms in the same order. + Material._uniformList = {}; + /** * Creates a new material using an existing material type. *

diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index ef3b194be107..e9fa47517698 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -17,6 +17,7 @@ define([ '../Renderer/BufferUsage', '../Renderer/CommandLists', '../Renderer/DrawCommand', + './Material', './SceneMode', './Polyline', '../Shaders/Noise', @@ -41,6 +42,7 @@ define([ BufferUsage, CommandLists, DrawCommand, + Material, SceneMode, Polyline, Noise, @@ -796,16 +798,21 @@ define([ } }; + var scratchUniformArray = []; PolylineCollection.prototype._createMaterialHash = function(material) { - var hash = material.type; - var uniforms = material._uniforms; - for (var uniform in uniforms) { - if (uniforms.hasOwnProperty(uniform)) { - hash += '_' + uniform + '_' + uniforms[uniform](); - } + var uniforms = Material._uniformList[material.type]; + var length = uniforms.length; + scratchUniformArray.length = 2.0 * length; + + var index = 0; + for (var i = 0; i < length; ++i) { + var uniform = uniforms[i]; + scratchUniformArray[index] = uniform; + scratchUniformArray[index + 1] = material._uniforms[uniform](); + index += 2; } - return hash; + return JSON.stringify(scratchUniformArray); }; PolylineCollection.prototype._sortPolylinesIntoBuckets = function() { From a538e343a453a8e8c78f9ff882ee70485b0c40fa Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 18 Mar 2013 15:30:10 -0400 Subject: [PATCH 053/114] Fix tests. --- .../DynamicScene/DynamicPathVisualizerSpec.js | 8 +- .../DynamicPolylineVisualizerSpec.js | 8 +- Specs/Renderer/DrawSpec.js | 4 +- Specs/Scene/PolylineCollectionSpec.js | 258 +++++++----------- Specs/createContext.js | 9 +- 5 files changed, 116 insertions(+), 171 deletions(-) diff --git a/Specs/DynamicScene/DynamicPathVisualizerSpec.js b/Specs/DynamicScene/DynamicPathVisualizerSpec.js index 200641c4ef96..de37a0c4b872 100644 --- a/Specs/DynamicScene/DynamicPathVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPathVisualizerSpec.js @@ -130,8 +130,8 @@ defineSuite([ expect(testObject.position.lastStop).toEqual(time.addSeconds(path.leadTime.getValue())); expect(primitive.getShow()).toEqual(testObject.path.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); - expect(primitive.getColor()).toEqual(testObject.path.color.getValue(time)); - expect(primitive.getOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); + expect(primitive.getDefaultColor()).toEqual(testObject.path.color.getValue(time)); + expect(primitive.getDefaultOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); testObject.position = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); @@ -143,8 +143,8 @@ defineSuite([ visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.path.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); - expect(primitive.getColor()).toEqual(testObject.path.color.getValue(time)); - expect(primitive.getOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); + expect(primitive.getDefaultColor()).toEqual(testObject.path.color.getValue(time)); + expect(primitive.getDefaultOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); path.show = new MockProperty(false); diff --git a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js index 85550fd0b074..59ede3e064a7 100644 --- a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js @@ -131,8 +131,8 @@ defineSuite([ visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); - expect(primitive.getColor()).toEqual(testObject.polyline.color.getValue(time)); - expect(primitive.getOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); + expect(primitive.getDefaultColor()).toEqual(testObject.polyline.color.getValue(time)); + expect(primitive.getDefaultOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); testObject.vertexPositions = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); @@ -144,8 +144,8 @@ defineSuite([ visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); - expect(primitive.getColor()).toEqual(testObject.polyline.color.getValue(time)); - expect(primitive.getOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); + expect(primitive.getDefaultColor()).toEqual(testObject.polyline.color.getValue(time)); + expect(primitive.getDefaultOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); polyline.show = new MockProperty(false); diff --git a/Specs/Renderer/DrawSpec.js b/Specs/Renderer/DrawSpec.js index e09f674e0efd..36e2c13bf144 100644 --- a/Specs/Renderer/DrawSpec.js +++ b/Specs/Renderer/DrawSpec.js @@ -35,7 +35,9 @@ defineSuite([ var va; beforeAll(function() { - context = createContext(); + context = createContext({ + stencil : true + }); }); afterAll(function() { diff --git a/Specs/Scene/PolylineCollectionSpec.js b/Specs/Scene/PolylineCollectionSpec.js index afe128e02bce..8a54d703e3e4 100644 --- a/Specs/Scene/PolylineCollectionSpec.js +++ b/Specs/Scene/PolylineCollectionSpec.js @@ -67,16 +67,15 @@ defineSuite([ var p = polylines.add(); expect(p.getShow()).toEqual(true); expect(p.getPositions().length).toEqual(0); - expect(p.getColor().red).toEqual(1.0); - expect(p.getColor().green).toEqual(1.0); - expect(p.getColor().blue).toEqual(1.0); - expect(p.getColor().alpha).toEqual(1.0); - expect(p.getOutlineColor().red).toEqual(1.0); - expect(p.getOutlineColor().green).toEqual(1.0); - expect(p.getOutlineColor().blue).toEqual(1.0); - expect(p.getOutlineColor().alpha).toEqual(1.0); + expect(p.getDefaultColor().red).toEqual(1.0); + expect(p.getDefaultColor().green).toEqual(1.0); + expect(p.getDefaultColor().blue).toEqual(1.0); + expect(p.getDefaultColor().alpha).toEqual(1.0); + expect(p.getDefaultOutlineColor().red).toEqual(1.0); + expect(p.getDefaultOutlineColor().green).toEqual(1.0); + expect(p.getDefaultOutlineColor().blue).toEqual(1.0); + expect(p.getDefaultOutlineColor().alpha).toEqual(0.0); expect(p.getWidth()).toEqual(1.0); - expect(p.getOutlineWidth()).toEqual(1.0); }); it('explicitly constructs a polyline', function() { @@ -84,7 +83,6 @@ defineSuite([ show : false, positions : [new Cartesian3(1.0, 2.0, 3.0), new Cartesian3(4.0, 5.0, 6.0)], width : 2, - outlineWidth : 5, color : { red : 1.0, green : 2.0, @@ -102,50 +100,47 @@ defineSuite([ expect(p.getShow()).toEqual(false); expect(p.getPositions()[0]).toEqual(new Cartesian3(1.0, 2.0, 3.0)); expect(p.getPositions()[1]).toEqual(new Cartesian3(4.0, 5.0, 6.0)); - expect(p.getColor().red).toEqual(1.0); - expect(p.getColor().green).toEqual(2.0); - expect(p.getColor().blue).toEqual(3.0); - expect(p.getColor().alpha).toEqual(4.0); + expect(p.getDefaultColor().red).toEqual(1.0); + expect(p.getDefaultColor().green).toEqual(2.0); + expect(p.getDefaultColor().blue).toEqual(3.0); + expect(p.getDefaultColor().alpha).toEqual(4.0); expect(p.getWidth()).toEqual(2); - expect(p.getOutlineWidth()).toEqual(5); - expect(p.getOutlineColor().red).toEqual(6.0); - expect(p.getOutlineColor().green).toEqual(7.0); - expect(p.getOutlineColor().blue).toEqual(8.0); - expect(p.getOutlineColor().alpha).toEqual(9.0); + expect(p.getDefaultOutlineColor().red).toEqual(6.0); + expect(p.getDefaultOutlineColor().green).toEqual(7.0); + expect(p.getDefaultOutlineColor().blue).toEqual(8.0); + expect(p.getDefaultOutlineColor().alpha).toEqual(9.0); }); it('sets polyline properties', function() { var p = polylines.add(); p.setShow(false); p.setPositions([new Cartesian3(1.0, 2.0, 3.0), new Cartesian3(4.0, 5.0, 6.0)]); - p.setColor({ + p.setDefaultColor({ red : 1.0, green : 2.0, blue : 3.0, alpha : 4.0 }); - p.setOutlineColor({ + p.setDefaultOutlineColor({ red : 5.0, green : 6.0, blue : 7.0, alpha : 8.0 }); p.setWidth(2); - p.setOutlineWidth(7); expect(p.getShow()).toEqual(false); expect(p.getPositions()[0]).toEqual(new Cartesian3(1.0, 2.0, 3.0)); expect(p.getPositions()[1]).toEqual(new Cartesian3(4.0, 5.0, 6.0)); - expect(p.getColor().red).toEqual(1.0); - expect(p.getColor().green).toEqual(2.0); - expect(p.getColor().blue).toEqual(3.0); - expect(p.getColor().alpha).toEqual(4.0); + expect(p.getDefaultColor().red).toEqual(1.0); + expect(p.getDefaultColor().green).toEqual(2.0); + expect(p.getDefaultColor().blue).toEqual(3.0); + expect(p.getDefaultColor().alpha).toEqual(4.0); expect(p.getWidth()).toEqual(2); - expect(p.getOutlineWidth()).toEqual(7); - expect(p.getOutlineColor().red).toEqual(5.0); - expect(p.getOutlineColor().green).toEqual(6.0); - expect(p.getOutlineColor().blue).toEqual(7.0); - expect(p.getOutlineColor().alpha).toEqual(8.0); + expect(p.getDefaultOutlineColor().red).toEqual(5.0); + expect(p.getDefaultOutlineColor().green).toEqual(6.0); + expect(p.getDefaultOutlineColor().blue).toEqual(7.0); + expect(p.getDefaultOutlineColor().alpha).toEqual(8.0); }); it('sets removed polyline properties', function() { @@ -421,10 +416,10 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); - it('renders 64K vertexes of same polyline', function() { + it('renders 64K vertices of same polyline', function() { var positions = []; for ( var i = 0; i < (64 * 1024) / 2; ++i) { positions.push({ @@ -510,7 +505,7 @@ defineSuite([ }); - it('renders more than 64K vertexes of same polyline', function() { + it('renders more than 64K vertices of same polyline', function() { var positions = []; for ( var i = 0; i < 64 * 1024; ++i) { positions.push({ @@ -579,7 +574,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); polylines.add({ positions : [], @@ -595,8 +590,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); - + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders an updated polyline with no positions using setPositions', function() { @@ -627,7 +621,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); var p2 = polylines.add({ positions : [], @@ -643,7 +637,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //recreates vertex array because buffer usage changed p2.setPositions([]); @@ -652,7 +646,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //should call PolylineCollection.writePositionsUpdate p2.setPositions([]); @@ -661,8 +655,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); - + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders an updated polyline with no positions using setShow', function() { @@ -693,7 +686,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); var p2 = polylines.add({ positions : [], @@ -709,7 +702,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //recreates vertex array because buffer usage changed p2.setShow(false); @@ -718,7 +711,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //should call PolylineCollection.writeShowUpdate p2.setShow(true); @@ -727,11 +720,11 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); - it('renders an updated polyline with no positions using setColor', function() { + it('renders an updated polyline with no positions using setDefaultColor', function() { var positions = []; for ( var i = 0; i < 100; ++i) { positions.push({ @@ -759,7 +752,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); var p2 = polylines.add({ positions : [], @@ -775,10 +768,10 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //recreates vertex array because buffer usage changed - p2.setColor({ + p2.setDefaultColor({ red : 1.0, blue : 1.0, green : 0.1, @@ -789,10 +782,10 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //should call PolylineCollection.writeColorUpdate - p2.setColor({ + p2.setDefaultColor({ red : 1.0, blue : 0.5, green : 0.1, @@ -803,7 +796,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('changes buffer usage after 100 iterations of not changing', function() { @@ -833,11 +826,8 @@ defineSuite([ context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); // changes buffer usage, recreates vertex arrays p.setPositions(positions); @@ -849,11 +839,11 @@ defineSuite([ for(var j = 0; j < 101; ++j){ render(context, frameState, polylines); } - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); - it('renders an updated polyline with no positions using setOutlineColor', function() { + it('renders an updated polyline with no positions using setDefaultOutlineColor', function() { var positions = []; for ( var i = 0; i < 100; ++i) { positions.push({ @@ -881,7 +871,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); var p2 = polylines.add({ positions : [], @@ -897,10 +887,10 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //recreates vertex array because buffer usage changed - p2.setOutlineColor({ + p2.setDefaultOutlineColor({ red : 1.0, blue : 1.0, green : 0.1, @@ -911,10 +901,10 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //should call PolylineCollection.writeColorUpdate - p2.setOutlineColor({ + p2.setDefaultOutlineColor({ red : 1.0, blue : 0.5, green : 0.1, @@ -925,10 +915,10 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); - it('renders more than 64K vertexes of different polylines', function() { + it('renders more than 64K vertices of different polylines', function() { var positions = []; for ( var i = 0; i < 64 * 1024; ++i) { positions.push({ @@ -980,7 +970,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 255, 0, 255]); }); - it('renders more than 64K vertexes of different polylines of different widths', function() { + it('renders more than 64K vertices of different polylines of different widths', function() { var positions = []; for ( var i = 0; i < 64 * 1024 - 2; ++i) { positions.push({ @@ -1144,7 +1134,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('adds and renders a polyline', function() { @@ -1170,7 +1160,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); polylines.add({ positions : [{ @@ -1191,7 +1181,7 @@ defineSuite([ }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 0, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('removes and renders a polyline', function() { @@ -1234,14 +1224,14 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 0, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); polylines.remove(bluePolyline); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('removes all polylines and renders', function() { @@ -1267,7 +1257,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -1300,7 +1290,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -1325,7 +1315,7 @@ defineSuite([ }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 0, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders using polyline positions property', function() { @@ -1345,7 +1335,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -1372,7 +1362,7 @@ defineSuite([ z : 0.0 }]); // Back in front of viewer render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders using polyline color property', function() { @@ -1392,32 +1382,32 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); - p.setColor({ + p.setDefaultColor({ red : 1.0, green : 0.0, blue : 1.0, alpha : 1.0 }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); // Update a second time since it goes through a different vertex array update path context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); - p.setColor({ + p.setDefaultColor({ red : 0.0, green : 1.0, blue : 0.0, alpha : 1.0 }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders using polyline outlineColor property', function() { @@ -1430,40 +1420,39 @@ defineSuite([ x : 0.0, y : 1.0, z : 0.0 - }], - outlineWidth:2 + }] }); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); - p.setOutlineColor({ + p.setDefaultOutlineColor({ red : 1.0, green : 0.0, blue : 1.0, alpha : 1.0 }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); // Update a second time since it goes through a different vertex array update path context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); - p.setOutlineColor({ + p.setDefaultOutlineColor({ red : 0.0, green : 1.0, blue : 0.0, alpha : 1.0 }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders and updates one polyline from many polylines using show property', function() { @@ -1517,7 +1506,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -1531,7 +1520,7 @@ defineSuite([ p.setShow(true); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); @@ -1553,7 +1542,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -1568,10 +1557,10 @@ defineSuite([ p.setShow(true); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); - it('renders four polylines with different widths and outline widths', function() { + it('renders four polylines with different widths', function() { var positions = []; for(var i = 0; i < 200; ++i){ positions.push({ @@ -1592,8 +1581,7 @@ defineSuite([ blue : 0.0, alpha : 1.0 }, - width : 3, - outlineWidth:8 + width : 3 }); polylines.add({ positions : positions, @@ -1613,8 +1601,7 @@ defineSuite([ blue : 0.0, alpha : 1.0 }, - width : 2, - outlineWidth:4 + width : 2 }); polylines.add({ positions : [{ @@ -1632,14 +1619,13 @@ defineSuite([ blue : 1.0, alpha : 1.0 }, - width : 7, - outlineWidth:2 + width : 7 }); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 0, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders three polylines with different widths and updates one', function() { @@ -1697,25 +1683,25 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 0, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - p2.setColor({ + p2.setDefaultColor({ red : 1.0, green : 1.0, blue : 0.0, alpha : 1.0 }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - p2.setColor({ + p2.setDefaultColor({ red : 1.0, green : 0.0, blue : 0.0, alpha : 1.0 }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('changes polyline position size recreates vertex arrays', function() { @@ -1732,20 +1718,19 @@ defineSuite([ }); } var p = polylines.add({ - positions : positions, - outlineWidth:2 + positions : positions }); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); p.setPositions(positions); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); positions.push({ x : 0.0, @@ -1755,7 +1740,7 @@ defineSuite([ p.setPositions(positions); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('changes polyline width property', function() { @@ -1785,62 +1770,19 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); p1.setWidth(2); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); p2.setWidth(2); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); p1.setWidth(1); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); - - }); - - it('changes polyline outlinewidth property', function() { - var p1 = polylines.add({ - positions : [{ - x : 0.0, - y : -1.0, - z : 0.0 - }, { - x : 0.0, - y : 1.0, - z : 0.0 - }] - }); - var p2 = polylines.add({ - positions : [{ - x : 0.0, - y : -1.0, - z : 0.0 - }, { - x : 0.0, - y : 1.0, - z : 0.0 - }] - }); - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); - - p1.setOutlineWidth(2); - render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); - - p2.setOutlineWidth(2); - render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); - - p1.setOutlineWidth(1); - render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 255, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); diff --git a/Specs/createContext.js b/Specs/createContext.js index b563d935e313..c7ed957bb516 100644 --- a/Specs/createContext.js +++ b/Specs/createContext.js @@ -7,11 +7,12 @@ define([ createCanvas) { "use strict"; - function createContext() { + function createContext(options) { + options = (typeof options !== 'undefined') ? options : {}; + options.alpha = (typeof options.alpha !== 'undefined') ? options.alpha : true; + var canvas = createCanvas(); - var context = new Context(canvas, { - alpha : true - }); + var context = new Context(canvas, options); context.setValidateShaderProgram(true); context.setValidateFramebuffer(true); context.setLogShaderCompilation(true); From 322bd2c300dac20d361f8da78e6b342fdbcea56d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 18 Mar 2013 17:32:49 -0400 Subject: [PATCH 054/114] Fix more tests. --- Source/Scene/PolylineCollection.js | 4 ++-- Specs/Scene/PolylineCollectionSpec.js | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index e9fa47517698..157c545a344d 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1146,7 +1146,7 @@ define([ for ( var j = 0; j < positionsLength; ++j) { if (j !== positionsLength - 1) { if (indicesCount + 3 >= SIXTYFOURK - 1) { - vertexBufferOffset.push(2); + vertexBufferOffset.push(4); indices = []; totalIndices.push(indices); indicesCount = 0; @@ -1210,7 +1210,7 @@ define([ for ( var k = 0; k < segmentLength; ++k) { if (k !== segmentLength - 1) { if (indicesCount + 3 >= SIXTYFOURK - 1) { - vertexBufferOffset.push(2); + vertexBufferOffset.push(4); indices = []; totalIndices.push(indices); indicesCount = 0; diff --git a/Specs/Scene/PolylineCollectionSpec.js b/Specs/Scene/PolylineCollectionSpec.js index 8a54d703e3e4..f725793d9c36 100644 --- a/Specs/Scene/PolylineCollectionSpec.js +++ b/Specs/Scene/PolylineCollectionSpec.js @@ -447,7 +447,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('creates two vertex arrays and renders', function() { @@ -478,7 +478,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -501,7 +501,7 @@ defineSuite([ }); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); @@ -543,7 +543,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([255, 0, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders a polyline with no positions', function() { @@ -967,7 +967,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('renders more than 64K vertices of different polylines of different widths', function() { @@ -1041,7 +1041,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).toEqual([0, 255, 0, 255]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); it('does not render', function() { From 79f8db2954c484ebdfd9633752014221eace09b5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 18 Mar 2013 17:42:34 -0400 Subject: [PATCH 055/114] Some polyline collection clean up. --- Source/Scene/PolylineCollection.js | 81 ++++-------------------------- 1 file changed, 9 insertions(+), 72 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 157c545a344d..b8673e869a75 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1123,10 +1123,11 @@ define([ } }; + var scratchSegmentLengths = new Array(1); /** * @private */ - PolylineBucket.prototype._updateIndices3D = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { + PolylineBucket.prototype.updateIndices = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { var vaCount = vertexArrayBuckets.length - 1; var bucketLocator = new VertexArrayBucketLocator(0, offset, this); vertexArrayBuckets[vaCount].push(bucketLocator); @@ -1139,70 +1140,16 @@ define([ var polylines = this.polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { - var polyline = polylines[i]; - var positions = polyline.getPositions(); - var positionsLength = positions.length; - if (positions.length > 0) { - for ( var j = 0; j < positionsLength; ++j) { - if (j !== positionsLength - 1) { - if (indicesCount + 3 >= SIXTYFOURK - 1) { - vertexBufferOffset.push(4); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - count = 0; - offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; - } - indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); - - count += 6; - offset += 6; - indicesCount += 2; - } - } - if (indicesCount + 3 < SIXTYFOURK - 1) { - indicesCount += 2; - } else { - vertexBufferOffset.push(0); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - offset = 0; - count = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; - } + var polyline = polylines[i]; + var segments; + if (this.mode === SceneMode.SCENE3D) { + segments = scratchSegmentLengths; + segments[0] = polyline.getPositions().length; + } else { + segments = polyline._segments.lengths; } - polyline._clean(); - } - bucketLocator.count = count; - return offset; - }; - /** - * @private - */ - PolylineBucket.prototype._updateIndices2D = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { - var vaCount = vertexArrayBuckets.length - 1; - var bucketLocator = new VertexArrayBucketLocator(0, offset, this); - vertexArrayBuckets[vaCount].push(bucketLocator); - var count = 0; - var indices = totalIndices[totalIndices.length - 1]; - var indicesCount = 0; - if (indices.length > 0) { - indicesCount = indices[indices.length - 1] + 1; - } - var polylines = this.polylines; - var length = polylines.length; - for ( var i = 0; i < length; ++i) { - var polyline = polylines[i]; - var segments = polyline._segments.lengths; var numberOfSegments = segments.length; if (numberOfSegments > 0) { for ( var j = 0; j < numberOfSegments; ++j) { @@ -1254,16 +1201,6 @@ define([ return offset; }; - /** - * @private - */ - PolylineBucket.prototype.updateIndices = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { - if (this.mode === SceneMode.SCENE3D) { - return this._updateIndices3D(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); - } - return this._updateIndices2D(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); - }; - /** * @private */ From 0a6b67fd17bafdd4cb219289b07341d73ce5e005 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 18 Mar 2013 20:00:23 -0400 Subject: [PATCH 056/114] Some minor clean up to the polyline collection. --- Source/Renderer/VertexArray.js | 4 +- Source/Scene/PolylineCollection.js | 138 ++++++++++++++--------------- 2 files changed, 70 insertions(+), 72 deletions(-) diff --git a/Source/Renderer/VertexArray.js b/Source/Renderer/VertexArray.js index e73da860c8bf..486cbb1abb1b 100644 --- a/Source/Renderer/VertexArray.js +++ b/Source/Renderer/VertexArray.js @@ -354,8 +354,8 @@ define([ } var indexBuffer = this._indexBuffer; - if (indexBuffer && indexBuffer.getVertexArrayDestroyable()) { - this._indexBuffer = indexBuffer.destroy(); + if (indexBuffer && !indexBuffer.isDestroyed() && indexBuffer.getVertexArrayDestroyable()) { + indexBuffer.destroy(); } return destroyObject(this); diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index b8673e869a75..94f533feaeef 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -462,83 +462,83 @@ define([ polylineBuckets = this._polylineBuckets; var useDepthTest = (this.morphTime !== 0.0); this._commandLists.removeAll(); - if (typeof polylineBuckets !== 'undefined') { - if (pass.color) { - if (typeof this._rs === 'undefined') { - this._rs = context.createRenderState({ - blending : BlendingState.ALPHA_BLEND - }); - } - this._rs.depthMask = !useDepthTest; - this._rs.depthTest.enabled = useDepthTest; - - length = this._colorVertexArrays.length; - commands = this._commandLists.colorList; - for ( var m = 0; m < length; ++m) { - var vaColor = this._colorVertexArrays[m]; - buckets = vaColor.buckets; - bucketLength = buckets.length; - var p = commands.length; - commands.length += bucketLength; - for ( var n = 0; n < bucketLength; ++n, ++p) { - bucketLocator = buckets[n]; - - command = commands[p]; - if (typeof command === 'undefined') { - command = commands[p] = new DrawCommand(); - } + if (pass.color) { + if (typeof this._rs === 'undefined') { + this._rs = context.createRenderState({ + blending : BlendingState.ALPHA_BLEND + }); + } - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.TRIANGLES; - command.count = bucketLocator.count; - command.offset = bucketLocator.offset; - command.shaderProgram = bucketLocator.shaderProgram; - command.uniformMap = combine([this._uniforms, bucketLocator.material._uniforms], false, false); - command.vertexArray = vaColor.va; - command.renderState = this._rs; + this._rs.depthMask = !useDepthTest; + this._rs.depthTest.enabled = useDepthTest; + + length = this._colorVertexArrays.length; + commands = this._commandLists.colorList; + for ( var m = 0; m < length; ++m) { + var vaColor = this._colorVertexArrays[m]; + buckets = vaColor.buckets; + bucketLength = buckets.length; + var p = commands.length; + commands.length += bucketLength; + for ( var n = 0; n < bucketLength; ++n, ++p) { + bucketLocator = buckets[n]; + + command = commands[p]; + if (typeof command === 'undefined') { + command = commands[p] = new DrawCommand(); } + + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.primitiveType = PrimitiveType.TRIANGLES; + command.count = bucketLocator.count; + command.offset = bucketLocator.offset; + command.shaderProgram = bucketLocator.shaderProgram; + command.uniformMap = combine([this._uniforms, bucketLocator.material._uniforms], false, false); + command.vertexArray = vaColor.va; + command.renderState = this._rs; } } + } - if (pass.pick) { - if (typeof this._spPick === 'undefined') { - this._spPick = context.getShaderCache().getShaderProgram( - '#define RENDER_FOR_PICK\n\n' + PolylineVS, PolylineFSPick, attributeIndices); - } - if (typeof this._rsPick === 'undefined') { - this._rsPick = context.createRenderState(); - } + if (pass.pick) { + if (typeof this._spPick === 'undefined') { + this._spPick = context.getShaderCache().getShaderProgram( + '#define RENDER_FOR_PICK\n\n' + PolylineVS, PolylineFSPick, attributeIndices); + } - this._rsPick.depthMask = !useDepthTest; - this._rsPick.depthTest.enabled = useDepthTest; - - length = this._colorVertexArrays.length; - commands = this._commandLists.pickList; - for ( var a = 0; a < length; ++a) { - var vaPickColor = this._pickColorVertexArrays[a]; - buckets = vaPickColor.buckets; - bucketLength = buckets.length; - commands.length += bucketLength; - for ( var b = 0; b < bucketLength; ++b) { - bucketLocator = buckets[b]; - - command = commands[b]; - if (typeof command === 'undefined') { - command = commands[b] = new DrawCommand(); - } + if (typeof this._rsPick === 'undefined') { + this._rsPick = context.createRenderState(); + } - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.TRIANGLES; - command.count = bucketLocator.count; - command.offset = bucketLocator.offset; - command.shaderProgram = this._spPick; - command.uniformMap = this._uniforms; - command.vertexArray = vaPickColor.va; - command.renderState = this._rsPick; + this._rsPick.depthMask = !useDepthTest; + this._rsPick.depthTest.enabled = useDepthTest; + + length = this._colorVertexArrays.length; + commands = this._commandLists.pickList; + for ( var a = 0; a < length; ++a) { + var vaPickColor = this._pickColorVertexArrays[a]; + buckets = vaPickColor.buckets; + bucketLength = buckets.length; + commands.length += bucketLength; + for ( var b = 0; b < bucketLength; ++b) { + bucketLocator = buckets[b]; + + command = commands[b]; + if (typeof command === 'undefined') { + command = commands[b] = new DrawCommand(); } + + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.primitiveType = PrimitiveType.TRIANGLES; + command.count = bucketLocator.count; + command.offset = bucketLocator.offset; + command.shaderProgram = this._spPick; + command.uniformMap = this._uniforms; + command.vertexArray = vaPickColor.va; + command.renderState = this._rsPick; } } } @@ -584,7 +584,6 @@ define([ * polylines = polylines && polylines.destroy(); */ PolylineCollection.prototype.destroy = function() { - this._sp = this._sp && this._sp.release(); this._spPick = this._spPick && this._spPick.release(); this._destroyVertexArrays(); this._destroyPolylines(); @@ -699,7 +698,6 @@ define([ if (indices.length > 0) { var indicesArray = new Uint16Array(indices); var indexBuffer = context.createIndexBuffer(indicesArray, BufferUsage.STATIC_DRAW, IndexDatatype.UNSIGNED_SHORT); - indexBuffer.setVertexArrayDestroyable(false); vbo += vertexBufferOffset[k]; var positionHighOffset = 2 * (k * (positionSizeInBytes * SIXTYFOURK) - vbo * positionSizeInBytes);//componentsPerAttribute(3) * componentDatatype(4) var positionLowOffset = positionSizeInBytes + positionHighOffset; From fbbd638bf55e5effc93426a6db4e573995a6a141 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Mar 2013 13:44:49 -0400 Subject: [PATCH 057/114] Release polyline shaders when removed, vertex arrays are (re)created, or collection is destroyed. --- Source/Scene/Polyline.js | 1 + Source/Scene/PolylineCollection.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index d7ba64f87d07..4ce027071b67 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -478,6 +478,7 @@ define([ Polyline.prototype._destroy = function() { this._pickId = this._pickId && this._pickId.destroy(); + this._material = this._material && this._material.destroy(); this._polylineCollection = undefined; }; diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 94f533feaeef..7d1fc2579646 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -254,6 +254,10 @@ define([ this._polylines[polyline._index] = null; // Removed later this._polylinesRemoved = true; this._createVertexArray = true; + if (typeof polyline._bucket !== 'undefined') { + var bucket = polyline._bucket; + bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.release(); + } polyline._destroy(); return true; } @@ -281,6 +285,7 @@ define([ * polylines.removeAll(); */ PolylineCollection.prototype.removeAll = function() { + this._releaseShaders(); this._destroyPolylines(); this._polylineBuckets = {}; this._polylinesRemoved = false; @@ -586,6 +591,7 @@ define([ PolylineCollection.prototype.destroy = function() { this._spPick = this._spPick && this._spPick.release(); this._destroyVertexArrays(); + this._releaseShaders(); this._destroyPolylines(); return destroyObject(this); }; @@ -622,6 +628,7 @@ define([ PolylineCollection.prototype._createVertexArrays = function(context) { this._createVertexArray = false; + this._releaseShaders(); this._destroyVertexArrays(); this._sortPolylinesIntoBuckets(); //stores all of the individual indices arrays. @@ -863,6 +870,17 @@ define([ } }; + PolylineCollection.prototype._releaseShaders = function() { + var polylines = this._polylines; + var length = polylines.length; + for (var i = 0; i < length; ++i) { + var bucket = polylines[i]._bucket; + if (typeof bucket !== 'undefined') { + bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.release(); + } + } + }; + PolylineCollection.prototype._destroyVertexArrays = function() { var length = this._colorVertexArrays.length; for ( var t = 0; t < length; ++t) { From 0f78d24ed6fd205474a7cf5dd724c74ce21f25f1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Mar 2013 14:03:10 -0400 Subject: [PATCH 058/114] Update doc. --- Source/Scene/Polyline.js | 26 ++++++++++++++--- Source/Scene/PolylineCollection.js | 47 ++---------------------------- 2 files changed, 25 insertions(+), 48 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 4ce027071b67..6cdea9a2aa89 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -194,16 +194,28 @@ define([ }; /** - * TODO - * @returns + * Gets the surface appearance of the polyline. This can be one of several built-in {@link Material} objects or a custom material, scripted with + * Fabric. + * + * @memberof Polyline + * + * @returns {Material} The material. */ Polyline.prototype.getMaterial = function() { return this._material; }; /** - * TODO - * @param material + * Sets the surface appearance of the polyline. This can be one of several built-in {@link Material} objects or a custom material, scripted with + * Fabric. + * + * @memberof Polyline + * + * @param {Material} material The material + * + * @exception {DeveloperError} material is required. + * + * @see Polyline#getMaterial */ Polyline.prototype.setMaterial = function(material) { if (typeof material === 'undefined') { @@ -259,6 +271,8 @@ define([ /** * Returns the polyline's color at each position. * + * @memberof Polyline + * * @return {Array} The polyline's color at each position. * * @see Polyline#setColors @@ -311,6 +325,8 @@ define([ /** * Sets the width of the polyline. * + * @memberof Polyline + * * @param {Number} value The width of the polyline. * * @exception {DeveloperError} value is required. @@ -378,6 +394,8 @@ define([ /** * Returns the polyline's outline color at each position. * + * @memberof Polyline + * * @return {Array} The polyline's outline color at each position. * * @see Polyline#setOutlineColors diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 7d1fc2579646..00ccbf4cb981 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -210,8 +210,7 @@ define([ * new Cartographic2(-75.10, 39.57), * new Cartographic2(-77.02, 38.53)]), * color : { red : 1.0, green : 1.0, blue : 1.0, alpha : 1.0 }, - * width : 1, - * outlineWidth : 2 + * width : 1 * }); * */ @@ -379,9 +378,7 @@ define([ }; /** - * Commits changes to properties before rendering by updating the object's WebGL resources. - * - * @memberof PolylineCollection + * @private */ PolylineCollection.prototype.update = function(context, frameState, commandList) { this._removePolylines(); @@ -907,9 +904,6 @@ define([ } }; - /** - * @private - */ function VertexArrayBucketLocator(count, offset, bucket) { this.count = count; this.offset = offset; @@ -917,9 +911,6 @@ define([ this.material = bucket.material; } - /** - * @private - */ var PolylineBucket = function(material, mode, projection, modelMatrix) { this.polylines = []; this.lengthOfPositions = 0; @@ -931,9 +922,6 @@ define([ this.modelMatrix = modelMatrix; }; - /** - * @private - */ PolylineBucket.prototype.addPolyline = function(p) { var polylines = this.polylines; polylines.push(p); @@ -942,9 +930,6 @@ define([ p._bucket = this; }; - /** - * @private - */ PolylineBucket.prototype.updateShader = function(context) { if (typeof this.shaderProgram !== 'undefined') { return; @@ -966,9 +951,6 @@ define([ polyline._boundingVolume.intersect(Cartesian4.UNIT_Y) === Intersect.INTERSECTING; } - /** - * @private - */ PolylineBucket.prototype.getPolylinePositionsLength = function(polyline) { if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { return polyline.getPositions().length; @@ -1017,9 +999,6 @@ define([ var scratchWriteColorArray = new Array(1); var scratchWriteOutlineColorArray = new Array(1); - /** - * @private - */ PolylineBucket.prototype.write = function(positionArray, adjacencyArray, colorArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { var polylines = this.polylines; var length = polylines.length; @@ -1108,9 +1087,6 @@ define([ var morphPositionScratch = new Cartesian3(); - /** - * @private - */ PolylineBucket.prototype.writeForMorph = function(positionArray, adjacencyArray, positionIndex, adjacencyIndex) { var modelMatrix = this.modelMatrix; var polylines = this.polylines; @@ -1140,9 +1116,7 @@ define([ }; var scratchSegmentLengths = new Array(1); - /** - * @private - */ + PolylineBucket.prototype.updateIndices = function(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset) { var vaCount = vertexArrayBuckets.length - 1; var bucketLocator = new VertexArrayBucketLocator(0, offset, this); @@ -1217,9 +1191,6 @@ define([ return offset; }; - /** - * @private - */ PolylineBucket.prototype._getPolylineStartIndex = function(polyline) { var polylines = this.polylines; var positionIndex = 0; @@ -1234,9 +1205,6 @@ define([ return positionIndex; }; - /** - * @private - */ PolylineBucket.prototype._getPositions = function(polyline) { var positions = polyline.getPositions(); @@ -1286,9 +1254,6 @@ define([ var scratchAdjacency = new Cartesian4(); - /** - * @private - */ PolylineBucket.prototype.writePositionsUpdate = function(positionIndex, polyline, positionBuffer, adjacencyBuffer) { var positionsLength = polyline._actualLength; if (positionsLength) { @@ -1335,9 +1300,6 @@ define([ var scratchColorArray = new Array(1); var scratchOutlineColorArray = new Array(1); - /** - * @private - */ PolylineBucket.prototype.writeColorUpdate = function(positionIndex, polyline, buffer) { var positionsLength = polyline._actualLength; if (positionsLength) { @@ -1388,9 +1350,6 @@ define([ } }; - /** - * @private - */ PolylineBucket.prototype.writeMiscUpdate = function(positionIndex, polyline, buffer) { var positionsLength = polyline._actualLength; if (positionsLength) { From 861191ef2037f3d0aab3b777951a87a7530b6350 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Mar 2013 14:38:22 -0400 Subject: [PATCH 059/114] Some more polyline collection clean up. --- Source/Scene/PolylineCollection.js | 203 ++++++++++++++++------------- 1 file changed, 109 insertions(+), 94 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 00ccbf4cb981..f4e83641bf78 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -284,8 +284,8 @@ define([ * polylines.removeAll(); */ PolylineCollection.prototype.removeAll = function() { - this._releaseShaders(); - this._destroyPolylines(); + releaseShaders(this); + destroyPolylines(this); this._polylineBuckets = {}; this._polylinesRemoved = false; this._polylines.length = 0; @@ -343,7 +343,7 @@ define([ throw new DeveloperError('index is required.'); } - this._removePolylines(); + removePolylines(this); return this._polylines[index]; }; @@ -373,7 +373,7 @@ define([ * } */ PolylineCollection.prototype.getLength = function() { - this._removePolylines(); + removePolylines(this); return this._polylines.length; }; @@ -381,10 +381,9 @@ define([ * @private */ PolylineCollection.prototype.update = function(context, frameState, commandList) { - this._removePolylines(); - this._updateMode(frameState); + removePolylines(this); + updateMode(this, frameState); - var bucket; var polyline; var length; var buckets; @@ -393,8 +392,8 @@ define([ var bucketLocator; var properties = this._propertiesChanged; - if (this._createVertexArray || this._computeNewBuffersUsage()) { - this._createVertexArrays(context); + if (this._createVertexArray || computeNewBuffersUsage(this)) { + createVertexArrays(this, context); } else if (this._polylinesUpdated) { // Polylines were modified, but no polylines were added or removed. var polylinesToUpdate = this._polylinesToUpdate; @@ -409,14 +408,14 @@ define([ // if a polyline's positions size changes, we need to recreate the vertex arrays and vertex buffers because the indices will be different. // if a polyline's material changes, we need to recreate the VAOs and VBOs because they will be batched differenty. if (properties[POSITION_SIZE_INDEX] || properties[MATERIAL_INDEX]) { - this._createVertexArrays(context); + createVertexArrays(this, context); } else { length = polylinesToUpdate.length; polylineBuckets = this._polylineBuckets; for ( var ii = 0; ii < length; ++ii) { polyline = polylinesToUpdate[ii]; properties = polyline._propertiesChanged; - bucket = polyline._bucket; + var bucket = polyline._bucket; var index = 0; for ( var x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { @@ -587,17 +586,17 @@ define([ */ PolylineCollection.prototype.destroy = function() { this._spPick = this._spPick && this._spPick.release(); - this._destroyVertexArrays(); - this._releaseShaders(); - this._destroyPolylines(); + destroyVertexArrays(this); + releaseShaders(this); + destroyPolylines(this); return destroyObject(this); }; - PolylineCollection.prototype._computeNewBuffersUsage = function() { - var buffersUsage = this._buffersUsage; + function computeNewBuffersUsage(collection) { + var buffersUsage = collection._buffersUsage; var usageChanged = false; - var properties = this._propertiesChanged; + var properties = collection._propertiesChanged; //subtract 1 from NUMBER_OF_PROPERTIES because we don't care about POSITION_SIZE_INDEX property change. for ( var k = 0; k < NUMBER_OF_PROPERTIES - 1; ++k) { var bufferUsage = buffersUsage[k]; @@ -621,27 +620,27 @@ define([ } } return usageChanged; - }; + } + + function createVertexArrays(collection, context) { + collection._createVertexArray = false; + releaseShaders(collection); + destroyVertexArrays(collection); + sortPolylinesIntoBuckets(collection); - PolylineCollection.prototype._createVertexArrays = function(context) { - this._createVertexArray = false; - this._releaseShaders(); - this._destroyVertexArrays(); - this._sortPolylinesIntoBuckets(); //stores all of the individual indices arrays. - var totalIndices = []; - var indices = []; + var totalIndices = [[]]; + var indices = totalIndices[0]; //used to determine the vertexBuffer offset if the indicesArray goes over 64k. //if it's the same polyline while it goes over 64k, the offset needs to backtrack componentsPerAttribute * componentDatatype bytes //so that the polyline looks contiguous. //if the polyline ends at the 64k mark, then the offset is just 64k * componentsPerAttribute * componentDatatype var vertexBufferOffset = [0]; - totalIndices.push(indices); var offset = 0; var vertexArrayBuckets = [[]]; var totalLength = 0; - var polylineBuckets = this._polylineBuckets; + var polylineBuckets = collection._polylineBuckets; var x; var bucket; for (x in polylineBuckets) { @@ -651,7 +650,10 @@ define([ totalLength += bucket.lengthOfPositions; } } + if (totalLength > 0) { + var mode = collection._mode; + var positionArray = new Float32Array(2 * totalLength * 3 * 2); var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); var colorArray = new Float32Array(totalLength * 4 * 2); @@ -667,12 +669,14 @@ define([ if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; bucket.write(positionArray, adjacencyArray, colorArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context); - if (this._mode === SceneMode.MORPHING) { + + if (mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { position3DArray = new Float32Array(2 * totalLength * 3 * 2); } bucket.writeForMorph(position3DArray, adjacencyArray, positionIndex, adjacencyIndex); } + var bucketLength = bucket.lengthOfPositions; positionIndex += 2 * bucketLength * 3 * 2; adjacencyIndex += 2 * bucketLength * 4 * 2; @@ -681,28 +685,34 @@ define([ offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); } } - this._positionBuffer = context.createVertexBuffer(positionArray, this._buffersUsage[POSITION_INDEX].bufferUsage); + + collection._positionBuffer = context.createVertexBuffer(positionArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); var position3DBuffer; if (typeof position3DArray !== 'undefined') { - position3DBuffer = context.createVertexBuffer(position3DArray, this._buffersUsage[POSITION_INDEX].bufferUsage); + position3DBuffer = context.createVertexBuffer(position3DArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); } - this._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, this._buffersUsage[POSITION_INDEX].bufferUsage); - this._colorBuffer = context.createVertexBuffer(colorArray, this._buffersUsage[COLOR_INDEX].bufferUsage); - this._pickColorBuffer = context.createVertexBuffer(pickColorArray, BufferUsage.STATIC_DRAW); - this._miscBuffer = context.createVertexBuffer(miscArray, this._buffersUsage[MISC_INDEX].bufferUsage); + collection._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); + collection._colorBuffer = context.createVertexBuffer(colorArray, collection._buffersUsage[COLOR_INDEX].bufferUsage); + collection._pickColorBuffer = context.createVertexBuffer(pickColorArray, BufferUsage.STATIC_DRAW); + collection._miscBuffer = context.createVertexBuffer(miscArray, collection._buffersUsage[MISC_INDEX].bufferUsage); + var colorSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var pickColorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var miscSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; + var vbo = 0; var numberOfIndicesArrays = totalIndices.length; for ( var k = 0; k < numberOfIndicesArrays; ++k) { indices = totalIndices[k]; + if (indices.length > 0) { var indicesArray = new Uint16Array(indices); var indexBuffer = context.createIndexBuffer(indicesArray, BufferUsage.STATIC_DRAW, IndexDatatype.UNSIGNED_SHORT); + vbo += vertexBufferOffset[k]; + var positionHighOffset = 2 * (k * (positionSizeInBytes * SIXTYFOURK) - vbo * positionSizeInBytes);//componentsPerAttribute(3) * componentDatatype(4) var positionLowOffset = positionSizeInBytes + positionHighOffset; var prevOffset = 2 * (k * (adjacencySizeInBytes * SIXTYFOURK) - vbo * adjacencySizeInBytes); @@ -710,6 +720,7 @@ define([ var vertexColorBufferOffset = k * (colorSizeInBytes * SIXTYFOURK) - vbo * colorSizeInBytes; var vertexPickColorBufferOffset = k * (pickColorSizeInBytes * SIXTYFOURK) - vbo * pickColorSizeInBytes; var vertexMiscBufferOffset = k * (miscSizeInBytes * SIXTYFOURK) - vbo * miscSizeInBytes; + var attributes = [{ index : attributeIndices.position3DHigh, componentsPerAttribute : 3, @@ -738,70 +749,70 @@ define([ index : attributeIndices.prev, componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : this._adjacencyBuffer, + vertexBuffer : collection._adjacencyBuffer, offsetInBytes : prevOffset, strideInBytes : 2 * adjacencySizeInBytes }, { index : attributeIndices.next, componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : this._adjacencyBuffer, + vertexBuffer : collection._adjacencyBuffer, offsetInBytes : nextOffset, strideInBytes : 2 * adjacencySizeInBytes }, { index : attributeIndices.color, componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : this._colorBuffer, + vertexBuffer : collection._colorBuffer, offsetInBytes : vertexColorBufferOffset }, { index : attributeIndices.misc, componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : this._miscBuffer, + vertexBuffer : collection._miscBuffer, offsetInBytes : vertexMiscBufferOffset }]; - if (this._mode === SceneMode.SCENE3D) { - attributes[0].vertexBuffer = this._positionBuffer; - attributes[1].vertexBuffer = this._positionBuffer; + if (mode === SceneMode.SCENE3D) { + attributes[0].vertexBuffer = collection._positionBuffer; + attributes[1].vertexBuffer = collection._positionBuffer; attributes[2].value = [0.0, 0.0, 0.0]; attributes[3].value = [0.0, 0.0, 0.0]; - } else if (this._mode === SceneMode.SCENE2D || this._mode === SceneMode.COLUMBUS_VIEW) { + } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { attributes[0].value = [0.0, 0.0, 0.0]; attributes[1].value = [0.0, 0.0, 0.0]; - attributes[2].vertexBuffer = this._positionBuffer; - attributes[3].vertexBuffer = this._positionBuffer; + attributes[2].vertexBuffer = collection._positionBuffer; + attributes[3].vertexBuffer = collection._positionBuffer; } else { attributes[0].vertexBuffer = position3DBuffer; attributes[1].vertexBuffer = position3DBuffer; - attributes[2].vertexBuffer = this._positionBuffer; - attributes[3].vertexBuffer = this._positionBuffer; + attributes[2].vertexBuffer = collection._positionBuffer; + attributes[3].vertexBuffer = collection._positionBuffer; } var va = context.createVertexArray(attributes, indexBuffer); - this._colorVertexArrays.push({ + collection._colorVertexArrays.push({ va : va, buckets : vertexArrayBuckets[k] }); attributes[6].componentDatatype = ComponentDatatype.UNSIGNED_BYTE; - attributes[6].vertexBuffer = this._pickColorBuffer; + attributes[6].vertexBuffer = collection._pickColorBuffer; attributes[6].offsetInBytes = vertexPickColorBufferOffset; attributes[6].normalize = true; var vaPickColor = context.createVertexArray(attributes, indexBuffer); - this._pickColorVertexArrays.push({ + collection._pickColorVertexArrays.push({ va : vaPickColor, buckets : vertexArrayBuckets[k] }); } } } - }; + } var scratchUniformArray = []; - PolylineCollection.prototype._createMaterialHash = function(material) { + function createMaterialHash(material) { var uniforms = Material._uniformList[material.type]; var length = uniforms.length; scratchUniformArray.length = 2.0 * length; @@ -815,60 +826,64 @@ define([ } return JSON.stringify(scratchUniformArray); - }; + } - PolylineCollection.prototype._sortPolylinesIntoBuckets = function() { - var polylineBuckets = this._polylineBuckets = {}; - var polylines = this._polylines; + function sortPolylinesIntoBuckets(collection) { + var mode = collection._mode; + var projection = collection._projection; + var modelMatrix = collection._modelMatrix; + + var polylineBuckets = collection._polylineBuckets = {}; + var polylines = collection._polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { var p = polylines[i]; p.update(); var material = p.getMaterial(); - var hash = this._createMaterialHash(material); + var hash = createMaterialHash(material); var value = polylineBuckets[hash]; if (typeof value === 'undefined') { - value = polylineBuckets[hash] = new PolylineBucket(material, this._mode, this._projection, this._modelMatrix); + value = polylineBuckets[hash] = new PolylineBucket(material, mode, projection, modelMatrix); } value.addPolyline(p); } - }; + } - PolylineCollection.prototype._updateMode = function(frameState) { + function updateMode(collection, frameState) { var mode = frameState.mode; var projection = frameState.scene2D.projection; - if (this._mode !== mode && typeof mode.morphTime !== 'undefined') { - this.morphTime = mode.morphTime; + if (collection._mode !== mode && typeof mode.morphTime !== 'undefined') { + collection.morphTime = mode.morphTime; } - if (this._mode !== mode || (this._projection !== projection) || (!this._modelMatrix.equals(this.modelMatrix))) { - this._mode = mode; - this._projection = projection; - this._modelMatrix = this.modelMatrix.clone(); - this._createVertexArray = true; + if (collection._mode !== mode || (collection._projection !== projection) || (!collection._modelMatrix.equals(collection.modelMatrix))) { + collection._mode = mode; + collection._projection = projection; + collection._modelMatrix = collection.modelMatrix.clone(); + collection._createVertexArray = true; } - }; + } - PolylineCollection.prototype._removePolylines = function() { - if (this._polylinesRemoved) { - this._polylinesRemoved = false; + function removePolylines(collection) { + if (collection._polylinesRemoved) { + collection._polylinesRemoved = false; var polylines = []; - var length = this._polylines.length; + var length = collection._polylines.length; for ( var i = 0, j = 0; i < length; ++i) { - var polyline = this._polylines[i]; + var polyline = collection._polylines[i]; if (polyline) { polyline._index = j++; polylines.push(polyline); } } - this._polylines = polylines; + collection._polylines = polylines; } - }; + } - PolylineCollection.prototype._releaseShaders = function() { - var polylines = this._polylines; + function releaseShaders(collection) { + var polylines = collection._polylines; var length = polylines.length; for (var i = 0; i < length; ++i) { var bucket = polylines[i]._bucket; @@ -876,17 +891,17 @@ define([ bucket.shaderProgram = bucket.shaderProgram && bucket.shaderProgram.release(); } } - }; + } - PolylineCollection.prototype._destroyVertexArrays = function() { - var length = this._colorVertexArrays.length; + function destroyVertexArrays(collection) { + var length = collection._colorVertexArrays.length; for ( var t = 0; t < length; ++t) { - this._colorVertexArrays[t].va.destroy(); - this._pickColorVertexArrays[t].va.destroy(); + collection._colorVertexArrays[t].va.destroy(); + collection._pickColorVertexArrays[t].va.destroy(); } - this._colorVertexArrays.length = 0; - this._pickColorVertexArrays.length = 0; - }; + collection._colorVertexArrays.length = 0; + collection._pickColorVertexArrays.length = 0; + } PolylineCollection.prototype._updatePolyline = function(polyline, propertyChanged) { this._polylinesUpdated = true; @@ -894,15 +909,15 @@ define([ ++this._propertiesChanged[propertyChanged]; }; - PolylineCollection.prototype._destroyPolylines = function() { - var polylines = this._polylines; + function destroyPolylines(collection) { + var polylines = collection._polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { if (polylines[i]) { polylines[i]._destroy(); } } - }; + } function VertexArrayBucketLocator(count, offset, bucket) { this.count = count; @@ -1006,7 +1021,7 @@ define([ var polyline = polylines[i]; var width = polyline.getWidth(); var show = polyline.getShow(); - var positions = this._getPositions(polyline); + var positions = this.getPositions(polyline); var positionsLength = positions.length; var colors = polyline.getColors(); @@ -1191,7 +1206,7 @@ define([ return offset; }; - PolylineBucket.prototype._getPolylineStartIndex = function(polyline) { + PolylineBucket.prototype.getPolylineStartIndex = function(polyline) { var polylines = this.polylines; var positionIndex = 0; var length = polylines.length; @@ -1205,7 +1220,7 @@ define([ return positionIndex; }; - PolylineBucket.prototype._getPositions = function(polyline) { + PolylineBucket.prototype.getPositions = function(polyline) { var positions = polyline.getPositions(); if (positions.length > 0) { @@ -1257,12 +1272,12 @@ define([ PolylineBucket.prototype.writePositionsUpdate = function(positionIndex, polyline, positionBuffer, adjacencyBuffer) { var positionsLength = polyline._actualLength; if (positionsLength) { - positionIndex += this._getPolylineStartIndex(polyline); + positionIndex += this.getPolylineStartIndex(polyline); var positionArray = new Float32Array(2 * positionsLength * 3 * 2); var adjacencyArray = new Float32Array(2 * positionsLength * 4 * 2); var index = 0; var adjacencyIndex = 0; - var positions = this._getPositions(polyline); + var positions = this.getPositions(polyline); for ( var i = 0; i < positionsLength; ++i) { var position = positions[i]; scratchWritePosition.x = position.x; @@ -1303,7 +1318,7 @@ define([ PolylineBucket.prototype.writeColorUpdate = function(positionIndex, polyline, buffer) { var positionsLength = polyline._actualLength; if (positionsLength) { - positionIndex += this._getPolylineStartIndex(polyline); + positionIndex += this.getPolylineStartIndex(polyline); var colors = polyline.getColors(); var colorIncrement = 1; @@ -1353,7 +1368,7 @@ define([ PolylineBucket.prototype.writeMiscUpdate = function(positionIndex, polyline, buffer) { var positionsLength = polyline._actualLength; if (positionsLength) { - positionIndex += this._getPolylineStartIndex(polyline); + positionIndex += this.getPolylineStartIndex(polyline); var show = polyline.getShow(); var width = polyline.getWidth(); var miscArray = new Float32Array(4 * positionsLength * 2); From 7ba8eba7648a6fe4b8124c5a7e4107a3c672d96c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Mar 2013 15:00:32 -0400 Subject: [PATCH 060/114] Fix broken test. --- Source/Scene/PolylineCollection.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index f4e83641bf78..052f173751ff 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -983,11 +983,15 @@ define([ result = new Cartesian4(); } + if (typeof modelMatrix === 'undefined') { + modelMatrix = Matrix4.IDENTITY; + } + var prev = computeAdjacencyAnglesPosition; if (index === 0) { Cartesian3.ZERO.clone(prev); } else { - prev = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[index - 1], prev) : Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); + prev = Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); Cartesian3.subtract(prev, position, prev); } Cartesian3.normalize(prev, prev); @@ -998,7 +1002,7 @@ define([ if (index === positions.length - 1) { Cartesian3.ZERO.clone(next); } else { - next = (typeof modelMatrix === 'undefined') ? Cartesian3.clone(positions[index + 1], next) : Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); + next = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); Cartesian3.subtract(next, position, next); } Cartesian3.normalize(next, next); @@ -1150,7 +1154,12 @@ define([ var segments; if (this.mode === SceneMode.SCENE3D) { segments = scratchSegmentLengths; - segments[0] = polyline.getPositions().length; + var positionsLength = polyline.getPositions().length; + if (positionsLength > 0) { + segments[0] = positionsLength; + } else { + continue; + } } else { segments = polyline._segments.lengths; } From ea4bddc6e9f73d0a0ea7ad3f30ee794c6d25767f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Mar 2013 16:07:38 -0400 Subject: [PATCH 061/114] Fix endpoints at IDL. --- Source/Scene/PolylineCollection.js | 83 +++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 052f173751ff..e3d01aac8b10 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -977,8 +977,7 @@ define([ var computeAdjacencyAnglesPosition = new Cartesian3(); - function computeAdjacencyAngles(position, index, positions, result, modelMatrix) { - // TODO handle cross idl + function computeAdjacencyAngles(position, index, positions, startSegment, endSegment, result, modelMatrix) { if (typeof result === 'undefined') { result = new Cartesian4(); } @@ -988,7 +987,7 @@ define([ } var prev = computeAdjacencyAnglesPosition; - if (index === 0) { + if (startSegment) { Cartesian3.ZERO.clone(prev); } else { prev = Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); @@ -999,7 +998,7 @@ define([ result.y = Math.atan2(prev.y, prev.x); var next = computeAdjacencyAnglesPosition; - if (index === positions.length - 1) { + if (endSegment) { Cartesian3.ZERO.clone(next); } else { next = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); @@ -1019,13 +1018,16 @@ define([ var scratchWriteOutlineColorArray = new Array(1); PolylineBucket.prototype.write = function(positionArray, adjacencyArray, colorArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { + var mode = this.mode; var polylines = this.polylines; var length = polylines.length; for ( var i = 0; i < length; ++i) { var polyline = polylines[i]; var width = polyline.getWidth(); var show = polyline.getShow(); - var positions = this.getPositions(polyline); + var segments = this.getSegments(polyline); + var positions = segments.positions; + var lengths = segments.lengths; var positionsLength = positions.length; var colors = polyline.getColors(); @@ -1049,18 +1051,29 @@ define([ var vertexColorIndex = 0; var vertexOutlineColorIndex = 0; + var segmentIndex = 0; + var count = 0; + for ( var j = 0; j < positionsLength; ++j) { var position = positions[j]; scratchWritePosition.x = position.x; scratchWritePosition.y = position.y; scratchWritePosition.z = (this.mode !== SceneMode.SCENE2D) ? position.z : 0.0; - var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchWriteAdjacency); + var segmentLength = lengths[segmentIndex]; + if (j === count + segmentLength) { + count += segmentLength; + ++segmentIndex; + } + + var segmentStart = j - count === 0; + var segmentEnd = j === count + lengths[segmentIndex] - 1; + var adjacencyAngles = computeAdjacencyAngles(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacency); for (var k = 0; k < 2; ++k) { EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); - if (this.mode === SceneMode.SCENE3D) { + if (mode === SceneMode.SCENE3D) { adjacencyArray[adjacencyIndex] = adjacencyAngles.x; adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; @@ -1113,11 +1126,24 @@ define([ for ( var i = 0; i < length; ++i) { var polyline = polylines[i]; var positions = polyline._segments.positions; + var lengths = polyline._segments.lengths; var positionsLength = positions.length; + var segmentIndex = 0; + var count = 0; + for ( var j = 0; j < positionsLength; ++j) { var position = Matrix4.multiplyByPoint(modelMatrix, positions[j], morphPositionScratch); - var adjacencyAngles = computeAdjacencyAngles(position, j, positions, scratchAdjacency, modelMatrix); + + var segmentLength = lengths[segmentIndex]; + if (j === count + segmentLength) { + count += segmentLength; + ++segmentIndex; + } + + var segmentStart = j - count === 0; + var segmentEnd = j === count + lengths[segmentIndex] - 1; + var adjacencyAngles = computeAdjacencyAngles(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacency); for (var k = 0; k < 2; ++k) { EncodedCartesian3.writeElements(position, positionArray, positionIndex); @@ -1229,7 +1255,13 @@ define([ return positionIndex; }; - PolylineBucket.prototype.getPositions = function(polyline) { + var scratchSegments = { + positions : undefined, + lengths : undefined + }; + var scratchLengths = new Array(1); + + PolylineBucket.prototype.getSegments = function(polyline) { var positions = polyline.getPositions(); if (positions.length > 0) { @@ -1241,8 +1273,12 @@ define([ } if (this.mode === SceneMode.SCENE3D) { - return positions; + scratchLengths[0] = positions.length; + scratchSegments.positions = positions; + scratchSegments.lengths = scratchLengths; + return scratchSegments; } + if (intersectsIDL(polyline)) { positions = polyline._segments.positions; } @@ -1272,33 +1308,52 @@ define([ } } - return newPositions; + scratchSegments.positions = newPositions; + scratchSegments.lengths = polyline._segments.lengths; + return scratchSegments; }; var scratchAdjacency = new Cartesian4(); PolylineBucket.prototype.writePositionsUpdate = function(positionIndex, polyline, positionBuffer, adjacencyBuffer) { + var mode = this.mode; var positionsLength = polyline._actualLength; if (positionsLength) { positionIndex += this.getPolylineStartIndex(polyline); var positionArray = new Float32Array(2 * positionsLength * 3 * 2); var adjacencyArray = new Float32Array(2 * positionsLength * 4 * 2); + var index = 0; var adjacencyIndex = 0; - var positions = this.getPositions(polyline); + + var segments = this.getSegments(polyline); + var positions = segments.positions; + var lengths = segments.lengths; + + var segmentIndex = 0; + var count = 0; + for ( var i = 0; i < positionsLength; ++i) { var position = positions[i]; scratchWritePosition.x = position.x; scratchWritePosition.y = position.y; scratchWritePosition.z = (this.mode !== SceneMode.SCENE2D) ? position.z : 0.0; - var adjacencyAngles = computeAdjacencyAngles(position, i, positions, scratchAdjacency); + var segmentLength = lengths[segmentIndex]; + if (i === count + segmentLength) { + count += segmentLength; + ++segmentIndex; + } + + var segmentStart = i - count === 0; + var segmentEnd = i === count + lengths[segmentIndex] - 1; + var adjacencyAngles = computeAdjacencyAngles(position, i, positions, segmentStart, segmentEnd, scratchAdjacency); for (var j = 0; j < 2; ++j) { EncodedCartesian3.writeElements(scratchWritePosition, positionArray, index); - if (this.mode === SceneMode.SCENE3D) { + if (mode === SceneMode.SCENE3D) { adjacencyArray[adjacencyIndex] = adjacencyAngles.x; adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; From 3d4c8a6dad7f4f96110729d568eb08e08d795410 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 19 Mar 2013 19:29:43 -0400 Subject: [PATCH 062/114] Create polyline draw commands grouped by material. --- Source/Scene/PolylineCollection.js | 92 +++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 22 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index e3d01aac8b10..47ecb9f1a9e3 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -476,29 +476,79 @@ define([ length = this._colorVertexArrays.length; commands = this._commandLists.colorList; + for ( var m = 0; m < length; ++m) { var vaColor = this._colorVertexArrays[m]; buckets = vaColor.buckets; bucketLength = buckets.length; - var p = commands.length; - commands.length += bucketLength; - for ( var n = 0; n < bucketLength; ++n, ++p) { + + for ( var n = 0; n < bucketLength; ++n) { bucketLocator = buckets[n]; - command = commands[p]; - if (typeof command === 'undefined') { - command = commands[p] = new DrawCommand(); + var offset = bucketLocator.offset; + var sp = bucketLocator.bucket.shaderProgram; + + var polylines = bucketLocator.bucket.polylines; + var polylineLength = polylines.length; + var currentId; + var currentMaterial; + var count = 0; + + for (var s = 0; s < polylineLength; ++s) { + polyline = polylines[s]; + var mId = createMaterialId(polyline._material); + if (mId !== currentId) { + if (typeof currentId !== 'undefined') { + command = new DrawCommand(); + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.primitiveType = PrimitiveType.TRIANGLES; + command.shaderProgram = sp; + command.vertexArray = vaColor.va; + command.renderState = this._rs; + + command.uniformMap = combine([this._uniforms, currentMaterial._uniforms], false, false); + command.count = count; + command.offset = offset; + + commands.push(command); + + offset += count; + count = 0; + } + + currentMaterial = polyline._material; + currentId = mId; + } + + var lengths; + if (this._mode === SceneMode.SCENE3D) { + lengths = [polyline.getPositions().length]; + } else { + lengths = polyline._segments.lengths; + } + + var segmentsLength = lengths.length; + for (var t = 0; t < segmentsLength; ++t) { + count += (lengths[t] - 1) * 6; + } } - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.TRIANGLES; - command.count = bucketLocator.count; - command.offset = bucketLocator.offset; - command.shaderProgram = bucketLocator.shaderProgram; - command.uniformMap = combine([this._uniforms, bucketLocator.material._uniforms], false, false); - command.vertexArray = vaColor.va; - command.renderState = this._rs; + if (typeof currentId !== 'undefined' && count > 0) { + command = new DrawCommand(); + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.primitiveType = PrimitiveType.TRIANGLES; + command.shaderProgram = sp; + command.vertexArray = vaColor.va; + command.renderState = this._rs; + + command.uniformMap = combine([this._uniforms, currentMaterial._uniforms], false, false); + command.count = count; + command.offset = offset; + + commands.push(command); + } } } } @@ -812,7 +862,7 @@ define([ } var scratchUniformArray = []; - function createMaterialHash(material) { + function createMaterialId(material) { var uniforms = Material._uniformList[material.type]; var length = uniforms.length; scratchUniformArray.length = 2.0 * length; @@ -825,7 +875,7 @@ define([ index += 2; } - return JSON.stringify(scratchUniformArray); + return material.type + ':' + JSON.stringify(scratchUniformArray); } function sortPolylinesIntoBuckets(collection) { @@ -840,10 +890,9 @@ define([ var p = polylines[i]; p.update(); var material = p.getMaterial(); - var hash = createMaterialHash(material); - var value = polylineBuckets[hash]; + var value = polylineBuckets[material.type]; if (typeof value === 'undefined') { - value = polylineBuckets[hash] = new PolylineBucket(material, mode, projection, modelMatrix); + value = polylineBuckets[material.type] = new PolylineBucket(material, mode, projection, modelMatrix); } value.addPolyline(p); } @@ -922,8 +971,7 @@ define([ function VertexArrayBucketLocator(count, offset, bucket) { this.count = count; this.offset = offset; - this.shaderProgram = bucket.shaderProgram; - this.material = bucket.material; + this.bucket = bucket; } var PolylineBucket = function(material, mode, projection, modelMatrix) { From 0de7f8129879854480e75a246d7a5a32e440053d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 14:31:36 -0400 Subject: [PATCH 063/114] Finish sorting polyline commands by material. --- Source/Scene/PolylineCollection.js | 206 +++++++++++++---------------- 1 file changed, 94 insertions(+), 112 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 47ecb9f1a9e3..11b8ec382636 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -385,13 +385,8 @@ define([ updateMode(this, frameState); var polyline; - var length; - var buckets; - var polylineBuckets; - var bucketLength; - var bucketLocator; - var properties = this._propertiesChanged; + if (this._createVertexArray || computeNewBuffersUsage(this)) { createVertexArrays(this, context); } else if (this._polylinesUpdated) { @@ -410,8 +405,8 @@ define([ if (properties[POSITION_SIZE_INDEX] || properties[MATERIAL_INDEX]) { createVertexArrays(this, context); } else { - length = polylinesToUpdate.length; - polylineBuckets = this._polylineBuckets; + var length = polylinesToUpdate.length; + var polylineBuckets = this._polylineBuckets; for ( var ii = 0; ii < length; ++ii) { polyline = polylinesToUpdate[ii]; properties = polyline._propertiesChanged; @@ -458,9 +453,6 @@ define([ } var pass = frameState.passes; - var commands; - var command; - polylineBuckets = this._polylineBuckets; var useDepthTest = (this.morphTime !== 0.0); this._commandLists.removeAll(); @@ -474,83 +466,7 @@ define([ this._rs.depthMask = !useDepthTest; this._rs.depthTest.enabled = useDepthTest; - length = this._colorVertexArrays.length; - commands = this._commandLists.colorList; - - for ( var m = 0; m < length; ++m) { - var vaColor = this._colorVertexArrays[m]; - buckets = vaColor.buckets; - bucketLength = buckets.length; - - for ( var n = 0; n < bucketLength; ++n) { - bucketLocator = buckets[n]; - - var offset = bucketLocator.offset; - var sp = bucketLocator.bucket.shaderProgram; - - var polylines = bucketLocator.bucket.polylines; - var polylineLength = polylines.length; - var currentId; - var currentMaterial; - var count = 0; - - for (var s = 0; s < polylineLength; ++s) { - polyline = polylines[s]; - var mId = createMaterialId(polyline._material); - if (mId !== currentId) { - if (typeof currentId !== 'undefined') { - command = new DrawCommand(); - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.TRIANGLES; - command.shaderProgram = sp; - command.vertexArray = vaColor.va; - command.renderState = this._rs; - - command.uniformMap = combine([this._uniforms, currentMaterial._uniforms], false, false); - command.count = count; - command.offset = offset; - - commands.push(command); - - offset += count; - count = 0; - } - - currentMaterial = polyline._material; - currentId = mId; - } - - var lengths; - if (this._mode === SceneMode.SCENE3D) { - lengths = [polyline.getPositions().length]; - } else { - lengths = polyline._segments.lengths; - } - - var segmentsLength = lengths.length; - for (var t = 0; t < segmentsLength; ++t) { - count += (lengths[t] - 1) * 6; - } - } - - if (typeof currentId !== 'undefined' && count > 0) { - command = new DrawCommand(); - command.boundingVolume = boundingVolume; - command.modelMatrix = modelMatrix; - command.primitiveType = PrimitiveType.TRIANGLES; - command.shaderProgram = sp; - command.vertexArray = vaColor.va; - command.renderState = this._rs; - - command.uniformMap = combine([this._uniforms, currentMaterial._uniforms], false, false); - command.count = count; - command.offset = offset; - - commands.push(command); - } - } - } + createCommandLists(boundingVolume, modelMatrix, this._colorVertexArrays, this._commandLists.colorList, this._rs, this._uniforms, true); } if (pass.pick) { @@ -566,38 +482,90 @@ define([ this._rsPick.depthMask = !useDepthTest; this._rsPick.depthTest.enabled = useDepthTest; - length = this._colorVertexArrays.length; - commands = this._commandLists.pickList; - for ( var a = 0; a < length; ++a) { - var vaPickColor = this._pickColorVertexArrays[a]; - buckets = vaPickColor.buckets; - bucketLength = buckets.length; - commands.length += bucketLength; - for ( var b = 0; b < bucketLength; ++b) { - bucketLocator = buckets[b]; - - command = commands[b]; - if (typeof command === 'undefined') { - command = commands[b] = new DrawCommand(); + createCommandLists(boundingVolume, modelMatrix, this._pickColorVertexArrays, this._commandLists.pickList, this._rsPick, this._uniforms, false, this._spPick); + } + + if (!this._commandLists.empty()) { + commandList.push(this._commandLists); + } + }; + + function createCommandLists(boundingVolume, modelMatrix, vertexArrays, commands, renderState, uniforms, combineUniforms, shaderProgram) { + var length = vertexArrays.length; + + for ( var m = 0; m < length; ++m) { + var va = vertexArrays[m]; + var buckets = va.buckets; + var bucketLength = buckets.length; + + for ( var n = 0; n < bucketLength; ++n) { + var bucketLocator = buckets[n]; + + var offset = bucketLocator.offset; + var sp = (typeof shaderProgram !== 'undefined') ? shaderProgram : bucketLocator.bucket.shaderProgram; + + var polylines = bucketLocator.bucket.polylines; + var polylineLength = polylines.length; + var currentId; + var currentMaterial; + var count = 0; + var command; + + for (var s = 0; s < polylineLength; ++s) { + var polyline = polylines[s]; + var mId = createMaterialId(polyline._material); + if (mId !== currentId) { + if (typeof currentId !== 'undefined') { + command = new DrawCommand(); + command.boundingVolume = boundingVolume; + command.modelMatrix = modelMatrix; + command.primitiveType = PrimitiveType.TRIANGLES; + command.shaderProgram = sp; + command.vertexArray = va.va; + command.renderState = renderState; + + command.uniformMap = combineUniforms ? combine([uniforms, currentMaterial._uniforms], false, false) : uniforms; + command.count = count; + command.offset = offset; + + commands.push(command); + + offset += count; + count = 0; + } + + currentMaterial = polyline._material; + currentId = mId; } + var locators = polyline._locatorBuckets; + var locatorLength = locators.length; + for (var t = 0; t < locatorLength; ++t) { + var locator = locators[t]; + if (locator.locator === bucketLocator) { + count += locator.count; + } + } + } + + if (typeof currentId !== 'undefined' && count > 0) { + command = new DrawCommand(); command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; command.primitiveType = PrimitiveType.TRIANGLES; - command.count = bucketLocator.count; - command.offset = bucketLocator.offset; - command.shaderProgram = this._spPick; - command.uniformMap = this._uniforms; - command.vertexArray = vaPickColor.va; - command.renderState = this._rsPick; + command.shaderProgram = sp; + command.vertexArray = va.va; + command.renderState = renderState; + + command.uniformMap = combineUniforms ? combine([uniforms, currentMaterial._uniforms], false, false) : uniforms; + command.count = count; + command.offset = offset; + + commands.push(command); } } } - - if (!this._commandLists.empty()) { - commandList.push(this._commandLists); - } - }; + } /** * Returns true if this object was destroyed; otherwise, false. @@ -1225,6 +1193,8 @@ define([ for ( var i = 0; i < length; ++i) { var polyline = polylines[i]; + polyline._locatorBuckets = []; + var segments; if (this.mode === SceneMode.SCENE3D) { segments = scratchSegmentLengths; @@ -1240,11 +1210,17 @@ define([ var numberOfSegments = segments.length; if (numberOfSegments > 0) { + var segmentIndexCount = 0; for ( var j = 0; j < numberOfSegments; ++j) { var segmentLength = segments[j]; for ( var k = 0; k < segmentLength; ++k) { if (k !== segmentLength - 1) { if (indicesCount + 3 >= SIXTYFOURK - 1) { + polyline._locatorBuckets.push({ + locator : bucketLocator, + count : segmentIndexCount + }); + segmentIndexCount = 0; vertexBufferOffset.push(4); indices = []; totalIndices.push(indices); @@ -1259,6 +1235,7 @@ define([ indices.push(indicesCount, indicesCount + 2, indicesCount + 1); indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + segmentIndexCount += 6; count += 6; offset += 6; indicesCount += 2; @@ -1269,6 +1246,11 @@ define([ } } + polyline._locatorBuckets.push({ + locator : bucketLocator, + count : segmentIndexCount + }); + if (indicesCount + 3 < SIXTYFOURK - 1) { indicesCount += 2; } else { From 8501915915fa8230904593877753f3a24859f804 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 15:42:43 -0400 Subject: [PATCH 064/114] Fix error when creating commands. --- Source/Scene/PolylineCollection.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 11b8ec382636..81c4227fff2f 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -563,6 +563,8 @@ define([ commands.push(command); } + + currentId = undefined; } } } From f4a014031d0c50d3a3a1c317800db3e72f99d9f7 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 15:45:10 -0400 Subject: [PATCH 065/114] Remove per-vertex color and outline color. --- Apps/Sandcastle/gallery/Polylines.html | 38 +--- Source/Scene/Material.js | 5 + Source/Scene/Polyline.js | 198 +----------------- Source/Scene/PolylineCollection.js | 148 ++----------- .../Materials/PolylineArrowMaterial.glsl | 13 +- .../Materials/PolylineOutlineMaterial.glsl | 14 +- Source/Shaders/PolylineVS.glsl | 15 +- 7 files changed, 51 insertions(+), 380 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index f80d2e61f768..5a98c075429e 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -56,34 +56,7 @@ Cesium.Cartographic.fromDegrees(-95.0, 30.0), Cesium.Cartographic.fromDegrees(-85.0, 40.0) ])); - coloredPolyline.setDefaultColor({ - red : 1.0, - green : 1.0, - blue : 0.0, - alpha : 1.0 - }); - - - // set a polyline's color per position - var perPositionColoredPolyline = polylines.add(); - Sandcastle.declare(perPositionColoredPolyline); // For highlighting on mouseover in Sandcastle. - perPositionColoredPolyline.setPositions(ellipsoid.cartographicArrayToCartesianArray([ - Cesium.Cartographic.fromDegrees(-115.0, 45.0), - Cesium.Cartographic.fromDegrees(-95.0, 45.0) - ])); - perPositionColoredPolyline.setColors([ - { - red : 0.0, - green : 1.0, - blue : 0.0, - alpha : 0.5 - }, { - red : 1.0, - green : 0.0, - blue : 0.0, - alpha : 1.0 - } - ]); + coloredPolyline.getMaterial().uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); // Set a polyline's width var widePolyline = polylines.add(); @@ -98,14 +71,10 @@ // Set the polyline's material to have an outline var outlineMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineOutlineType); + outlineMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 1.0, 1.0); + outlineMaterial.uniforms.outlineColor = new Cesium.Color(1.0, 0.0, 0.0, 1.0); outlineMaterial.uniforms.outlineWidth = 5.0; widePolyline.setMaterial(outlineMaterial); - widePolyline.setDefaultOutlineColor({ - red : 1.0, - green : 0.0, - blue : 0.0, - alpha : 1.0 - }); primitives.add(polylines); @@ -122,6 +91,7 @@ ]); localPolyline.setWidth(10.0); var arrowMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineArrowType); + arrowMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 1.0, 1.0); localPolyline.setMaterial(arrowMaterial); primitives.add(localPolylines); } diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 30af92919a97..18cc8047c258 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -1205,6 +1205,9 @@ define([ Material.PolylineArrowType = 'PolylineArrow'; Material._materialCache.addMaterial(Material.PolylineArrowType, { type : Material.PolylineArrowType, + uniforms : { + color : new Color(1.0, 0.0, 0.0, 1.0) + }, source : PolylineArrowMaterial }); @@ -1212,6 +1215,8 @@ define([ Material._materialCache.addMaterial(Material.PolylineOutlineType, { type : Material.PolylineOutlineType, uniforms : { + color : new Color(1.0, 0.0, 0.0, 1.0), + outlineColor : new Color(1.0, 1.0, 1.0, 1.0), outlineWidth : 0.0 }, source : PolylineOutlineMaterial diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 6cdea9a2aa89..e59198a76c72 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -5,7 +5,6 @@ define([ '../Core/destroyObject', '../Core/BoundingSphere', '../Core/Cartesian3', - '../Core/Color', '../Core/PolylinePipeline', '../Core/Matrix4', './Material' @@ -15,14 +14,12 @@ define([ destroyObject, BoundingSphere, Cartesian3, - Color, PolylinePipeline, Matrix4, Material) { "use strict"; var EMPTY_OBJECT = {}; - var defaultOutlineColor = new Color(1.0, 1.0, 1.0, 0.0); /** * DOC_TBA @@ -35,14 +32,10 @@ define([ this._show = defaultValue(description.show, true); this._width = defaultValue(description.width, 1.0); - this._color = Color.clone(defaultValue(description.color, Color.WHITE)); - this._outlineColor = Color.clone(defaultValue(description.outlineColor, defaultOutlineColor)); - this._perVertexColors = undefined; - this._perVertexOutlineColors = undefined; this._material = description.material; if (typeof this._material === 'undefined') { - this._material = Material.fromType(undefined, Material.PolylineOutlineType); + this._material = Material.fromType(undefined, Material.ColorType); } var positions = description.positions; @@ -73,10 +66,9 @@ define([ var MISC_INDEX = Polyline.MISC_INDEX = 0; var POSITION_INDEX = Polyline.POSITION_INDEX = 1; - var COLOR_INDEX = Polyline.COLOR_INDEX = 2; - var MATERIAL_INDEX = Polyline.MATERIAL_INDEX = 3; - var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 4; - var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 5; + var MATERIAL_INDEX = Polyline.MATERIAL_INDEX = 2; + var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 3; + var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 4; function makeDirty(polyline, propertyChanged) { ++polyline._propertiesChanged[propertyChanged]; @@ -226,85 +218,6 @@ define([ makeDirty(this, MATERIAL_INDEX); }; - /** - * Returns the default color of the polyline. This color is used if per-vertex - * colors are not defined. - * - * @memberof Polyline - * - * @return {Color} The default color of the polyline. - * - * @see Polyline#setDefaultColor - * @see Polyline#getColors - * @see Polyline#setColors - */ - Polyline.prototype.getDefaultColor = function() { - return this._color; - }; - - /** - * Sets the default color of the polyline. This color is used if per-vertex - * colors are not defined. - * - * @memberof Polyline - * - * @param {Color} value The default color of the polyline. - * - * @exception {DeveloperError} value is required. - * - * @see Polyline#getDefaultColor - * @see Polyline#getColors - * @see Polyline#setColors - */ - Polyline.prototype.setDefaultColor = function(value) { - if (typeof value === 'undefined') { - throw new DeveloperError('value is required.'); - } - - var color = this._color; - if (!Color.equals(color, value)) { - Color.clone(value, color); - makeDirty(this, COLOR_INDEX); - } - }; - - /** - * Returns the polyline's color at each position. - * - * @memberof Polyline - * - * @return {Array} The polyline's color at each position. - * - * @see Polyline#setColors - * @see Polyline#getDefaultColor - * @see Polyline#SetDefaultColor - */ - Polyline.prototype.getColors = function() { - return this._perVertexColors; - }; - - /** - * Defines the color of the polyline at each position. - * - * @memberof Polyline - * - * @param {Array} colors The colors of the polyline at each position. - * - * @exception {DeveloperError} colors must have the same number of elements as the positions. - * - * @see Polyline#getColors - * @see Polyline#getDefaultColor - * @see Polyline#SetDefaultColor - */ - Polyline.prototype.setColors = function(colors) { - if (typeof colors !== 'undefined' && colors.length !== this._positions.length) { - throw new DeveloperError('colors must have the same number of elements as the positions.'); - } - - this._perVertexColors = colors; - makeDirty(this, COLOR_INDEX); - }; - /** * Gets the width of the polyline. * @@ -349,85 +262,6 @@ define([ } }; - /** - * Gets the default outline color of the polyline. This color is used if per-vertex - * outline colors are not defined. - * - * @memberof Polyline - * - * @return {Color} The default outline color of the polyline. - * - * @see Polyline#setDefaultOutlineColor - * @see Polyline#getOutlineColors - * @see Polyline#setOutlineColors - */ - Polyline.prototype.getDefaultOutlineColor = function() { - return this._outlineColor; - }; - - /** - * Sets the default outline color of the polyline. This color is used if per-vertex - * outline colors are not defined. - * - * @memberof Polyline - * - * @param {Color} value The default outline color of the polyline. - * - * @exception {DeveloperError} value is required. - * - * @see Polyline#getDefaultOutlineColor - * @see Polyline#getOutlineColors - * @see Polyline#setOutlineColors - */ - Polyline.prototype.setDefaultOutlineColor = function(value) { - if (typeof value === 'undefined') { - throw new DeveloperError('value is required.'); - } - - var outlineColor = this._outlineColor; - if (!Color.equals(outlineColor, value)) { - Color.clone(value, outlineColor); - makeDirty(this, COLOR_INDEX); - } - }; - - /** - * Returns the polyline's outline color at each position. - * - * @memberof Polyline - * - * @return {Array} The polyline's outline color at each position. - * - * @see Polyline#setOutlineColors - * @see Polyline#getDefaultOutlineColor - * @see Polyline#SetDefaultOutlineColor - */ - Polyline.prototype.getOutlineColors = function() { - return this._perVertexOutlineColors; - }; - - /** - * Defines the outline color of the polyline at each position. - * - * @memberof Polyline - * - * @param {Array} colors The outline colors of the polyline at each position. - * - * @exception {DeveloperError} colors must have the same number of elements as the positions. - * - * @see Polyline#getOutlineColors - * @see Polyline#getDefaultOutlineColor - * @see Polyline#SetDefaultOutlineColor - */ - Polyline.prototype.setOutlineColors = function(colors) { - if (typeof colors !== 'undefined' && colors.length !== this._positions.length) { - throw new DeveloperError('colors must have the same number of elements as the positions.'); - } - - this._perVertexOutlineColors = colors; - makeDirty(this, COLOR_INDEX); - }; - Polyline.prototype.getPickId = function(context) { this._pickId = this._pickId || context.createPickId(this._pickIdThis || this); return this._pickId; @@ -457,11 +291,7 @@ define([ typeof other !== 'undefined' && this._show === other._show && this._width === other._width && - cartesian3ArrayEquals(this._positions, other._positions) && - Color.equals(this._color, other._color) && - Color.equals(this._outlineColor, other._outlineColor) && - colorArrayEquals(this._perVertexColors, this._positions.length, other._perVertexColors, other._positions.length) && - colorArrayEquals(this._perVertexOutlineColors, this._positions.length, other._perVertexOutlineColors, other._positions.length); + cartesian3ArrayEquals(this._positions, other._positions); }; function cartesian3ArrayEquals(a, b) { @@ -476,24 +306,6 @@ define([ return true; } - function colorArrayEquals(a, aPositionsLength, b, bPositionsLength) { - if (typeof a === 'undefined' && typeof b === 'undefined') { - return true; - } - if (a.length !== aPositionsLength && b.length !== bPositionsLength) { - return true; - } - if (a.length !== b.length) { - return false; - } - for ( var i = 0, len = a.length; i < len; ++i) { - if (!Color.equals(a[i], b[i])) { - return false; - } - } - return true; - } - Polyline.prototype._destroy = function() { this._pickId = this._pickId && this._pickId.destroy(); this._material = this._material && this._material.destroy(); diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 81c4227fff2f..3e024df60624 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -53,7 +53,6 @@ define([ var MISC_INDEX = Polyline.MISC_INDEX; var POSITION_INDEX = Polyline.POSITION_INDEX; - var COLOR_INDEX = Polyline.COLOR_INDEX; var MATERIAL_INDEX = Polyline.MATERIAL_INDEX; //POSITION_SIZE_INDEX is needed for when the polyline's position array changes size. //When it does, we need to recreate the indicesBuffer. @@ -68,8 +67,8 @@ define([ position2DLow : 3, prev : 4, next : 5, - color : 6, - misc : 7 + misc : 6, + pickColor : 7 }; /** @@ -159,7 +158,6 @@ define([ this._buffersUsage = [ {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // MISC_INDEX {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // POSITION_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // COLOR_INDEX {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0} // MATERIAL_INDEX ]; @@ -173,11 +171,9 @@ define([ }; this._polylinesToUpdate = []; - this._colorVertexArrays = []; - this._pickColorVertexArrays = []; + this._vertexArrays = []; this._positionBuffer = undefined; this._adjacencyBuffer = undefined; - this._colorBuffer = undefined; this._pickColorBuffer = undefined; this._miscBuffer = undefined; }; @@ -418,9 +414,6 @@ define([ if (properties[POSITION_INDEX]) { bucket.writePositionsUpdate(index, polyline, this._positionBuffer, this._adjacencyBuffer); } - if (properties[COLOR_INDEX]) { - bucket.writeColorUpdate(index, polyline, this._colorBuffer); - } if (properties[MISC_INDEX]) { bucket.writeMiscUpdate(index, polyline, this._miscBuffer); } @@ -466,7 +459,7 @@ define([ this._rs.depthMask = !useDepthTest; this._rs.depthTest.enabled = useDepthTest; - createCommandLists(boundingVolume, modelMatrix, this._colorVertexArrays, this._commandLists.colorList, this._rs, this._uniforms, true); + createCommandLists(boundingVolume, modelMatrix, this._vertexArrays, this._commandLists.colorList, this._rs, this._uniforms, true); } if (pass.pick) { @@ -482,7 +475,7 @@ define([ this._rsPick.depthMask = !useDepthTest; this._rsPick.depthTest.enabled = useDepthTest; - createCommandLists(boundingVolume, modelMatrix, this._pickColorVertexArrays, this._commandLists.pickList, this._rsPick, this._uniforms, false, this._spPick); + createCommandLists(boundingVolume, modelMatrix, this._vertexArrays, this._commandLists.pickList, this._rsPick, this._uniforms, false, this._spPick); } if (!this._commandLists.empty()) { @@ -676,7 +669,6 @@ define([ var positionArray = new Float32Array(2 * totalLength * 3 * 2); var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); - var colorArray = new Float32Array(totalLength * 4 * 2); var pickColorArray = new Uint8Array(totalLength * 4 * 2); var miscArray = new Float32Array(totalLength * 4 * 2); var position3DArray; @@ -688,7 +680,7 @@ define([ for (x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; - bucket.write(positionArray, adjacencyArray, colorArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context); + bucket.write(positionArray, adjacencyArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context); if (mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { @@ -712,11 +704,9 @@ define([ position3DBuffer = context.createVertexBuffer(position3DArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); } collection._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); - collection._colorBuffer = context.createVertexBuffer(colorArray, collection._buffersUsage[COLOR_INDEX].bufferUsage); collection._pickColorBuffer = context.createVertexBuffer(pickColorArray, BufferUsage.STATIC_DRAW); collection._miscBuffer = context.createVertexBuffer(miscArray, collection._buffersUsage[MISC_INDEX].bufferUsage); - var colorSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var pickColorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; @@ -737,7 +727,6 @@ define([ var positionLowOffset = positionSizeInBytes + positionHighOffset; var prevOffset = 2 * (k * (adjacencySizeInBytes * SIXTYFOURK) - vbo * adjacencySizeInBytes); var nextOffset = adjacencySizeInBytes + prevOffset; - var vertexColorBufferOffset = k * (colorSizeInBytes * SIXTYFOURK) - vbo * colorSizeInBytes; var vertexPickColorBufferOffset = k * (pickColorSizeInBytes * SIXTYFOURK) - vbo * pickColorSizeInBytes; var vertexMiscBufferOffset = k * (miscSizeInBytes * SIXTYFOURK) - vbo * miscSizeInBytes; @@ -779,18 +768,19 @@ define([ vertexBuffer : collection._adjacencyBuffer, offsetInBytes : nextOffset, strideInBytes : 2 * adjacencySizeInBytes - }, { - index : attributeIndices.color, - componentsPerAttribute : 4, - componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : collection._colorBuffer, - offsetInBytes : vertexColorBufferOffset }, { index : attributeIndices.misc, componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, vertexBuffer : collection._miscBuffer, offsetInBytes : vertexMiscBufferOffset + }, { + index : attributeIndices.pickColor, + componentsPerAttribute : 4, + componentDatatype : ComponentDatatype.UNSIGNED_BYTE, + vertexBuffer : collection._pickColorBuffer, + offsetInBytes : vertexPickColorBufferOffset, + normalize : true }]; if (mode === SceneMode.SCENE3D) { @@ -811,21 +801,10 @@ define([ } var va = context.createVertexArray(attributes, indexBuffer); - collection._colorVertexArrays.push({ + collection._vertexArrays.push({ va : va, buckets : vertexArrayBuckets[k] }); - - attributes[6].componentDatatype = ComponentDatatype.UNSIGNED_BYTE; - attributes[6].vertexBuffer = collection._pickColorBuffer; - attributes[6].offsetInBytes = vertexPickColorBufferOffset; - attributes[6].normalize = true; - - var vaPickColor = context.createVertexArray(attributes, indexBuffer); - collection._pickColorVertexArrays.push({ - va : vaPickColor, - buckets : vertexArrayBuckets[k] - }); } } } @@ -913,13 +892,11 @@ define([ } function destroyVertexArrays(collection) { - var length = collection._colorVertexArrays.length; + var length = collection._vertexArrays.length; for ( var t = 0; t < length; ++t) { - collection._colorVertexArrays[t].va.destroy(); - collection._pickColorVertexArrays[t].va.destroy(); + collection._vertexArrays[t].va.destroy(); } - collection._colorVertexArrays.length = 0; - collection._pickColorVertexArrays.length = 0; + collection._vertexArrays.length = 0; } PolylineCollection.prototype._updatePolyline = function(polyline, propertyChanged) { @@ -1031,11 +1008,8 @@ define([ var scratchWritePosition = new Cartesian3(); var scratchWriteAdjacency = new Cartesian4(); - var scratchWriteColor = new Color(); - var scratchWriteColorArray = new Array(1); - var scratchWriteOutlineColorArray = new Array(1); - PolylineBucket.prototype.write = function(positionArray, adjacencyArray, colorArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { + PolylineBucket.prototype.write = function(positionArray, adjacencyArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { var mode = this.mode; var polylines = this.polylines; var length = polylines.length; @@ -1048,27 +1022,8 @@ define([ var lengths = segments.lengths; var positionsLength = positions.length; - var colors = polyline.getColors(); - var colorIncrement = 1; - if (typeof colors === 'undefined' || colors.length !== positionsLength) { - colors = scratchWriteColorArray; - colors[0] = polyline.getDefaultColor(); - colorIncrement = 0; - } - - var outlineColors = polyline.getOutlineColors(); - var outlineColorIncrement = 1; - if (typeof outlineColors === 'undefined' || outlineColors.length !== positionsLength) { - outlineColors = scratchWriteOutlineColorArray; - outlineColors[0] = polyline.getDefaultOutlineColor(); - outlineColorIncrement = 0; - } - var pickColor = polyline.getPickId(context).unnormalizedRgb; - var vertexColorIndex = 0; - var vertexOutlineColorIndex = 0; - var segmentIndex = 0; var count = 0; @@ -1103,16 +1058,6 @@ define([ adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; } - var color = colors[vertexColorIndex]; - var outlineColor = outlineColors[vertexOutlineColorIndex]; - - scratchWriteColor.red = color.alpha; - scratchWriteColor.green = outlineColor.alpha; - - colorArray[colorIndex] = Color.encode(color); - colorArray[colorIndex + 1] = Color.encode(outlineColor); - colorArray[colorIndex + 2] = Color.encode(scratchWriteColor); - pickColorArray[colorIndex] = pickColor.red; pickColorArray[colorIndex + 1] = pickColor.green; pickColorArray[colorIndex + 2] = pickColor.blue; @@ -1128,9 +1073,6 @@ define([ colorIndex += 4; miscIndex += 4; } - - vertexColorIndex += colorIncrement; - vertexOutlineColorIndex += outlineColorIncrement; } } }; @@ -1407,60 +1349,6 @@ define([ } }; - var scratchColorAlpha = new Color(); - var scratchColorArray = new Array(1); - var scratchOutlineColorArray = new Array(1); - - PolylineBucket.prototype.writeColorUpdate = function(positionIndex, polyline, buffer) { - var positionsLength = polyline._actualLength; - if (positionsLength) { - positionIndex += this.getPolylineStartIndex(polyline); - - var colors = polyline.getColors(); - var colorIncrement = 1; - if (typeof colors === 'undefined' || colors.length !== positionsLength) { - colors = scratchColorArray; - colors[0] = polyline.getDefaultColor(); - colorIncrement = 0; - } - - var outlineColors = polyline.getOutlineColors(); - var outlineColorIncrement = 1; - if (typeof outlineColors === 'undefined' || outlineColors.length !== positionsLength) { - outlineColors = scratchOutlineColorArray; - outlineColors[0] = polyline.getDefaultOutlineColor(); - outlineColorIncrement = 0; - } - - var index = 0; - var colorIndex = 0; - var outlineColorIndex = 0; - - var colorsArray = new Float32Array(4 * positionsLength * 2); - for ( var j = 0; j < positionsLength; ++j) { - var color = colors[colorIndex]; - var outlineColor = outlineColors[outlineColorIndex]; - scratchColorAlpha.red = color.alpha; - scratchColorAlpha.green = outlineColor.alpha; - - var encodedColor = Color.encode(color); - var encodedOutlineColor = Color.encode(outlineColor); - var encodedAlpha = Color.encode(scratchColorAlpha); - - for (var k = 0; k < 2; ++k) { - colorsArray[index] = encodedColor; - colorsArray[index + 1] = encodedOutlineColor; - colorsArray[index + 2] = encodedAlpha; - index += 4; - } - - colorIndex += colorIncrement; - outlineColorIndex += outlineColorIncrement; - } - buffer.copyFromArrayView(colorsArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); - } - }; - PolylineBucket.prototype.writeMiscUpdate = function(positionIndex, polyline, buffer) { var positionsLength = polyline._actualLength; if (positionsLength) { diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index a67f3b30888f..49eb1b143eff 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -1,6 +1,7 @@ #extension GL_OES_standard_derivatives : enable // TODO check for support -varying vec4 v_color; +uniform vec4 color; + varying float v_width; float getPointOnLine(vec2 p0, vec2 p1, float x) @@ -58,11 +59,11 @@ czm_material czm_getMaterial(czm_materialInput materialInput) val1 = pow(val1, 0.5); //makes the transition nicer vec4 outsideColor = vec4(0.0); - vec4 midColor = (outsideColor + v_color) * 0.5; - vec4 currentColor = mix(outsideColor, v_color, clamp(s + t, 0.0, 1.0)); - vec4 color = mix(midColor, currentColor, val1); + vec4 midColor = (outsideColor + color) * 0.5; + vec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0)); + vec4 outColor = mix(midColor, currentColor, val1); - material.diffuse = color.rgb; - material.alpha = color.a; + material.diffuse = outColor.rgb; + material.alpha = outColor.a; return material; } diff --git a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl index 405ab602f862..76dd249b4612 100644 --- a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl +++ b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl @@ -1,7 +1,7 @@ +uniform vec4 color; +uniform vec4 outlineColor; uniform float outlineWidth; -varying vec4 v_color; -varying vec4 v_outlineColor; varying float v_width; czm_material czm_getMaterial(czm_materialInput materialInput) @@ -26,12 +26,12 @@ czm_material czm_getMaterial(czm_materialInput materialInput) val1 = val1 * val1 * (3.0 - (2.0 * val1)); val1 = pow(val1, 0.5); //makes the transition nicer - vec4 midColor = (v_outlineColor + v_color) * 0.5; - vec4 currentColor = mix(v_outlineColor, v_color, b); - vec4 color = mix(midColor, currentColor, val1); + vec4 midColor = (outlineColor + color) * 0.5; + vec4 currentColor = mix(outlineColor, color, b); + vec4 outColor = mix(midColor, currentColor, val1); - material.diffuse = color.rgb; - material.alpha = color.a; + material.diffuse = outColor.rgb; + material.alpha = outColor.a; return material; } diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 5546d562079b..1bd9b6fcdd2e 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -4,17 +4,15 @@ attribute vec3 position2DHigh; attribute vec3 position2DLow; attribute vec4 prev; attribute vec4 next; -attribute vec4 color; attribute vec4 misc; +attribute vec4 pickColor; #ifndef RENDER_FOR_PICK -varying vec4 v_color; -varying vec4 v_outlineColor; -varying vec2 v_textureCoordinates; +varying vec2 v_textureCoordinates; varying float v_width; -varying vec3 v_positionEC; +varying vec3 v_positionEC; #else -varying vec4 v_pickColor; +varying vec4 v_pickColor; #endif uniform float u_morphTime; @@ -110,13 +108,10 @@ void main() gl_Position = czm_projection * czm_windowToEyeCoordinates(positionWC) * show; #ifndef RENDER_FOR_PICK - vec3 alphas = czm_decodeColor(color.b); - v_color = vec4(czm_decodeColor(color.r), alphas.r); - v_outlineColor = vec4(czm_decodeColor(color.g), alphas.g); v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); v_width = width; v_positionEC = positionEC.xyz; #else - v_pickColor = color; + v_pickColor = pickColor; #endif } From f0a1237243eaafe1855549607f2e9d6be330ea0a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 16:02:55 -0400 Subject: [PATCH 066/114] Remove unused code. --- Source/Core/Color.js | 26 --------------------- Source/Shaders/BuiltinFunctions.glsl | 28 ----------------------- Source/Widgets/Dojo/CesiumViewerWidget.js | 13 ++++------- Specs/Core/ColorSpec.js | 20 ---------------- Specs/Renderer/BuiltinFunctionsSpec.js | 25 -------------------- Specs/Scene/PolylineCollectionSpec.js | 8 +++---- 6 files changed, 9 insertions(+), 111 deletions(-) diff --git a/Source/Core/Color.js b/Source/Core/Color.js index 28d8b1b2fc64..eb455fc0e8a9 100644 --- a/Source/Core/Color.js +++ b/Source/Core/Color.js @@ -2,12 +2,10 @@ define([ './defaultValue', './freezeObject', - './Cartesian3', './DeveloperError' ], function( defaultValue, freezeObject, - Cartesian3, DeveloperError) { "use strict"; @@ -213,30 +211,6 @@ define([ return number === 1.0 ? 255.0 : (number * 256.0) | 0; }; - var scale = new Cartesian3(1.0, 1.0 / Math.pow(2, 8), 1.0 / Math.pow(2, 16)); - var scratch = new Cartesian3(); - - /** - * Encodes the red, green, and blue components of a color into a 32 bit floating point number. - * - * @param {Color} color The color to be encoded. - * @returns {Number} A floating point number representing the encoded red, green, and blue values of the color. - * - * @exception {DeveloperError} color is required. - * - * @see czm_decodeColor - */ - Color.encode = function(color) { - if (typeof color === 'undefined') { - throw new DeveloperError('color is required.'); - } - - scratch.x = Color.floatToByte(color.red); - scratch.y = Color.floatToByte(color.green); - scratch.z = Color.floatToByte(color.blue); - return Cartesian3.dot(scratch, scale); - }; - /** * Duplicates a Color. * @memberof Color diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index 373ad2b1f48b..9698cc0d04b8 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -575,34 +575,6 @@ vec3 czm_multiplyWithColorBalance(vec3 left, vec3 right) return ((leftLuminance + rightLuminance) / (2.0 * targetLuminance)) * target; } -/** - * Unpacks an encoded color from a floating point number to an RGB vector. - * - * @name czm_decodeColor - * @glslFunction - * - * @param {float} The encoded color. - * - * @returns {vec3} The decoded color. - * - * @example - * attribute float encodedColor; - * //... - * varying vec4 v_color; - * //... - * v_color = vec4(czm_decodeColor(encodedColor), 1.0); - */ -vec3 czm_decodeColor(float encoded) -{ - const vec3 scale = vec3(1.0, 256.0, 65536.0); - vec3 decoded = scale * encoded; - float r = floor(decoded.r) / 256.0; - float g = fract(decoded.r); - float b = fract(decoded.g); - - return vec3(r, g, b); -} - /////////////////////////////////////////////////////////////////////////////// /** diff --git a/Source/Widgets/Dojo/CesiumViewerWidget.js b/Source/Widgets/Dojo/CesiumViewerWidget.js index ce131f79407a..c53343265e7b 100644 --- a/Source/Widgets/Dojo/CesiumViewerWidget.js +++ b/Source/Widgets/Dojo/CesiumViewerWidget.js @@ -1011,13 +1011,12 @@ define([ (typeof this.highlightedObject.isDestroyed !== 'function' || !this.highlightedObject.isDestroyed())) { if (typeof this.highlightedObject.material !== 'undefined') { this.highlightedObject.material = this._originalMaterial; + } else if (typeof this.highlightedObject.setMaterial !== 'undefined') { + this.highlightedObject.setMaterial(this._originalMaterial); } else if (typeof this.highlightedObject.outerMaterial !== 'undefined') { this.highlightedObject.outerMaterial = this._originalMaterial; } else if (typeof this.highlightedObject.setColor !== 'undefined') { this.highlightedObject.setColor(this._originalColor); - } else if (typeof this.highlightedObject.setDefaultColor !== 'undefined') { - this.highlightedObject.setDefaultColor(this._originalColor); - this.highlightedObject.setColors(this._colors); } } this.highlightedObject = selectedObject; @@ -1025,17 +1024,15 @@ define([ if (typeof selectedObject.material !== 'undefined') { this._originalMaterial = selectedObject.material; selectedObject.material = this.highlightMaterial; + } else if (typeof selectedObject.getMaterial !== 'undefined') { + this._originalMaterial = selectedObject.getMaterial(); + selectedObject.setMaterial(this.highlightMaterial); } else if (typeof selectedObject.outerMaterial !== 'undefined') { this._originalMaterial = selectedObject.outerMaterial; selectedObject.outerMaterial = this.highlightMaterial; } else if (typeof selectedObject.setColor !== 'undefined') { this._originalColor = Color.clone(selectedObject.getColor(), this._originalColor); selectedObject.setColor(this.highlightColor); - } else if (typeof selectedObject.setDefaultColor !== 'undefined') { - this._originalColor = Color.clone(selectedObject.getDefaultColor(), this._originalColor); - this._colors = (typeof selectedObject.setColors !== 'undefined') ? selectedObject.getColors() : undefined; - selectedObject.setDefaultColor(this.highlightColor); - selectedObject.setColors(undefined); } } } diff --git a/Specs/Core/ColorSpec.js b/Specs/Core/ColorSpec.js index 44aa1a6bb67c..753d99135673 100644 --- a/Specs/Core/ColorSpec.js +++ b/Specs/Core/ColorSpec.js @@ -61,26 +61,6 @@ defineSuite(['Core/Color', expect(Color.floatToByte(127 / 255)).toEqual(127); }); - it('encodes a color', function() { - var color = new Color(0.75, 0.5, 0.25); - var encoded = Color.encode(color); - - var red = Math.floor(encoded) / 256.0; - var green = encoded - Math.floor(encoded); - var blue = encoded * 256.0; - blue = blue - Math.floor(blue); - - expect(red).toEqualEpsilon(color.red, CesiumMath.EPSILON3); - expect(green).toEqualEpsilon(color.green, CesiumMath.EPSILON3); - expect(blue).toEqualEpsilon(color.blue, CesiumMath.EPSILON3); - }); - - it('encode throws without a color', function() { - expect(function() { - return Color.encode(); - }).toThrow(); - }); - it('clone with no parameters returns a new identical copy.', function() { var v = new Color(0.1, 0.2, 0.3, 0.4); var v2 = v.clone(); diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index fa95865f5ddf..1a1e176ccc5c 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -202,29 +202,4 @@ defineSuite([ verifyDraw(fs, uniformMap); }); - - it('has czm_decodeColor', function() { - var color = new Color(0.75, 0.5, 0.25, 1.0); - var encoded = Color.encode(color); - - var uniformMap = { - u_encoded : function() { - return encoded; - }, - u_color : function() { - return color; - } - }; - - var fs = - 'uniform float u_encoded;' + - 'uniform vec4 u_color;' + - 'void main() {' + - ' vec3 color = czm_decodeColor(u_encoded);' + - ' vec3 diff = abs(color - u_color.rgb);' + - ' gl_FragColor = vec4(all(lessThan(diff, vec3(czm_epsilon3))));' + - '}'; - - verifyDraw(fs, uniformMap); - }); }, 'WebGL'); \ No newline at end of file diff --git a/Specs/Scene/PolylineCollectionSpec.js b/Specs/Scene/PolylineCollectionSpec.js index f725793d9c36..64fa22865d1e 100644 --- a/Specs/Scene/PolylineCollectionSpec.js +++ b/Specs/Scene/PolylineCollectionSpec.js @@ -1067,7 +1067,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).not.toEqual([0, 0, 0, 0]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); p.setShow(false); context.clear(); @@ -1100,7 +1100,7 @@ defineSuite([ expect(context.readPixels()).toEqual([0, 0, 0, 0]); render(context, frameState, polylines); - expect(context.readPixels()).not.toEqual([0, 0, 0, 0]); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); polylines.remove(p); @@ -1817,12 +1817,12 @@ defineSuite([ }); var pickedObject = pick(context, frameState, polylines, 0, 0); - expect(pickedObject).not.toBeDefined(); + expect(pickedObject).toNotBeDefined(); }); it('does not equal undefined', function() { var polyline = polylines.add(); - expect(polyline).not.toEqual(undefined); + expect(polyline).toNotEqual(undefined); }); it('throws when accessing without an index', function() { From cb852dac9a07c1c9158c6ae3b3e05a48bab1fa92 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 16:56:45 -0400 Subject: [PATCH 067/114] Update dynamic scene path and polyline. --- Source/DynamicScene/DynamicPath.js | 70 +++------- Source/DynamicScene/DynamicPathVisualizer.js | 25 ++-- Source/DynamicScene/DynamicPolyline.js | 70 +++------- .../DynamicScene/DynamicPolylineVisualizer.js | 29 ++-- Specs/DynamicScene/DynamicPathSpec.js | 130 ++++++++---------- .../DynamicScene/DynamicPathVisualizerSpec.js | 24 ++-- Specs/DynamicScene/DynamicPolylineSpec.js | 84 +++++------ .../DynamicPolylineVisualizerSpec.js | 24 ++-- 8 files changed, 175 insertions(+), 281 deletions(-) diff --git a/Source/DynamicScene/DynamicPath.js b/Source/DynamicScene/DynamicPath.js index 9b6f6bf2b243..5b99dc11e9a1 100644 --- a/Source/DynamicScene/DynamicPath.js +++ b/Source/DynamicScene/DynamicPath.js @@ -4,15 +4,15 @@ define([ '../Core/defaultValue', './CzmlBoolean', './CzmlNumber', - './CzmlColor', - './DynamicProperty'], -function( + './DynamicProperty', + './DynamicMaterialProperty' + ], function( TimeInterval, defaultValue, CzmlBoolean, CzmlNumber, - CzmlColor, - DynamicProperty) { + DynamicProperty, + DynamicMaterialProperty) { "use strict"; /** @@ -31,21 +31,6 @@ function( * @see CzmlDefaults */ var DynamicPath = function() { - /** - * A DynamicProperty of type CzmlColor which determines the line's color. - * @type DynamicProperty - */ - this.color = undefined; - /** - * A DynamicProperty of type CzmlColor which determines the line's outline color. - * @type DynamicProperty - */ - this.outlineColor = undefined; - /** - * A DynamicProperty of type CzmlNumber which determines the line's outline width. - * @type DynamicProperty - */ - this.outlineWidth = undefined; /** * A DynamicProperty of type CzmlBoolean which determines the lines's visibility. * @type DynamicProperty @@ -56,6 +41,11 @@ function( * @type DynamicProperty */ this.width = undefined; + /** + * A DynamicMaterialProperty which determines the line's material. + * @type DynamicMaterialProperty + */ + this.material = undefined; /** * A DynamicProperty of type CzmlNumber which determines the maximum step size, in seconds, to take when sampling the position. * @type DynamicProperty @@ -106,15 +96,6 @@ function( interval = TimeInterval.fromIso8601(interval); } - if (typeof pathData.color !== 'undefined') { - var color = path.color; - if (typeof color === 'undefined') { - path.color = color = new DynamicProperty(CzmlColor); - pathUpdated = true; - } - color.processCzmlIntervals(pathData.color, interval); - } - if (typeof pathData.width !== 'undefined') { var width = path.width; if (typeof width === 'undefined') { @@ -133,24 +114,6 @@ function( resolution.processCzmlIntervals(pathData.resolution, interval); } - if (typeof pathData.outlineColor !== 'undefined') { - var outlineColor = path.outlineColor; - if (typeof outlineColor === 'undefined') { - path.outlineColor = outlineColor = new DynamicProperty(CzmlColor); - pathUpdated = true; - } - outlineColor.processCzmlIntervals(pathData.outlineColor, interval); - } - - if (typeof pathData.outlineWidth !== 'undefined') { - var outlineWidth = path.outlineWidth; - if (typeof outlineWidth === 'undefined') { - path.outlineWidth = outlineWidth = new DynamicProperty(CzmlNumber); - pathUpdated = true; - } - outlineWidth.processCzmlIntervals(pathData.outlineWidth, interval); - } - if (typeof pathData.show !== 'undefined') { var show = path.show; if (typeof show === 'undefined') { @@ -160,6 +123,15 @@ function( show.processCzmlIntervals(pathData.show, interval); } + if (typeof pathData.material !== 'undefined') { + var material = path.material; + if (typeof material === 'undefined') { + path.material = material = new DynamicMaterialProperty(); + pathUpdated = true; + } + material.processCzmlIntervals(pathData.material, interval); + } + if (typeof pathData.leadTime !== 'undefined') { var leadTime = path.leadTime; if (typeof leadTime === 'undefined') { @@ -201,12 +173,10 @@ function( targetObject.path = targetpath = new DynamicPath(); } - targetpath.color = defaultValue(targetpath.color, pathToMerge.color); targetpath.width = defaultValue(targetpath.width, pathToMerge.width); targetpath.resolution = defaultValue(targetpath.resolution, pathToMerge.resolution); - targetpath.outlineColor = defaultValue(targetpath.outlineColor, pathToMerge.outlineColor); - targetpath.outlineWidth = defaultValue(targetpath.outlineWidth, pathToMerge.outlineWidth); targetpath.show = defaultValue(targetpath.show, pathToMerge.show); + targetpath.material = defaultValue(targetpath.material, pathToMerge.material); targetpath.leadTime = defaultValue(targetpath.leadTime, pathToMerge.leadTime); targetpath.trailTime = defaultValue(targetpath.trailTime, pathToMerge.trailTime); } diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 05eece01e960..32523b7067e5 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -8,7 +8,8 @@ define([ '../Core/Transforms', '../Core/ReferenceFrame', '../Scene/SceneMode', - '../Scene/PolylineCollection' + '../Scene/PolylineCollection', + '../Scene/Material' ], function( DeveloperError, destroyObject, @@ -18,7 +19,8 @@ define([ Transforms, ReferenceFrame, SceneMode, - PolylineCollection) { + PolylineCollection, + Material) { "use strict"; var PolylineUpdater = function(scene, referenceFrame) { @@ -121,6 +123,7 @@ define([ return; } + var context = this._scene.getContext(); if (typeof pathVisualizerIndex === 'undefined') { var unusedIndexes = this._unusedIndexes; var length = unusedIndexes.length; @@ -135,8 +138,7 @@ define([ polyline.dynamicObject = dynamicObject; // CZML_TODO Determine official defaults - polyline.setDefaultColor(Color.WHITE); - polyline.setDefaultOutlineColor(Color.BLACK); + polyline.setMaterial(Material.fromType(context, Material.ColorType)); polyline.setWidth(1); } else { polyline = this._polylineCollection.get(pathVisualizerIndex); @@ -152,16 +154,6 @@ define([ polyline.setPositions(positionProperty._getValueRangeInReferenceFrame(sampleStart, sampleStop, time, this._referenceFrame, resolution, polyline.getPositions())); - property = dynamicPath.color; - if (typeof property !== 'undefined') { - polyline.setDefaultColor(property.getValue(time, polyline.getDefaultColor())); - } - - property = dynamicPath.outlineColor; - if (typeof property !== 'undefined') { - polyline.setDefaultOutlineColor(property.getValue(time, polyline.getDefaultOutlineColor())); - } - property = dynamicPath.width; if (typeof property !== 'undefined') { var width = property.getValue(time); @@ -169,6 +161,11 @@ define([ polyline.setWidth(width); } } + + var material = dynamicPath.material; + if (typeof material !== 'undefined') { + polyline.setMaterial(material.getValue(time, context, polyline.getMaterial())); + } }; PolylineUpdater.prototype.removeObject = function(dynamicObject) { diff --git a/Source/DynamicScene/DynamicPolyline.js b/Source/DynamicScene/DynamicPolyline.js index 4c46170a04cb..072219a0c1f1 100644 --- a/Source/DynamicScene/DynamicPolyline.js +++ b/Source/DynamicScene/DynamicPolyline.js @@ -4,15 +4,15 @@ define([ '../Core/defaultValue', './CzmlBoolean', './CzmlNumber', - './CzmlColor', - './DynamicProperty'], -function( + './DynamicProperty', + './DynamicMaterialProperty' + ], function( TimeInterval, defaultValue, CzmlBoolean, CzmlNumber, - CzmlColor, - DynamicProperty) { + DynamicProperty, + DynamicMaterialProperty) { "use strict"; /** @@ -31,21 +31,6 @@ function( * @see CzmlDefaults */ var DynamicPolyline = function() { - /** - * A DynamicProperty of type CzmlColor which determines the line's color. - * @type DynamicProperty - */ - this.color = undefined; - /** - * A DynamicProperty of type CzmlColor which determines the line's outline color. - * @type DynamicProperty - */ - this.outlineColor = undefined; - /** - * A DynamicProperty of type CzmlNumber which determines the line's outline width. - * @type DynamicProperty - */ - this.outlineWidth = undefined; /** * A DynamicProperty of type CzmlBoolean which determines the lines's visibility. * @type DynamicProperty @@ -56,6 +41,11 @@ function( * @type DynamicProperty */ this.width = undefined; + /** + * A DynamicMaterialProperty which determines the line's material. + * @type DynamicMaterialProperty + */ + this.material = undefined; }; /** @@ -91,15 +81,6 @@ function( interval = TimeInterval.fromIso8601(interval); } - if (typeof polylineData.color !== 'undefined') { - var color = polyline.color; - if (typeof color === 'undefined') { - polyline.color = color = new DynamicProperty(CzmlColor); - polylineUpdated = true; - } - color.processCzmlIntervals(polylineData.color, interval); - } - if (typeof polylineData.width !== 'undefined') { var width = polyline.width; if (typeof width === 'undefined') { @@ -109,24 +90,6 @@ function( width.processCzmlIntervals(polylineData.width, interval); } - if (typeof polylineData.outlineColor !== 'undefined') { - var outlineColor = polyline.outlineColor; - if (typeof outlineColor === 'undefined') { - polyline.outlineColor = outlineColor = new DynamicProperty(CzmlColor); - polylineUpdated = true; - } - outlineColor.processCzmlIntervals(polylineData.outlineColor, interval); - } - - if (typeof polylineData.outlineWidth !== 'undefined') { - var outlineWidth = polyline.outlineWidth; - if (typeof outlineWidth === 'undefined') { - polyline.outlineWidth = outlineWidth = new DynamicProperty(CzmlNumber); - polylineUpdated = true; - } - outlineWidth.processCzmlIntervals(polylineData.outlineWidth, interval); - } - if (typeof polylineData.show !== 'undefined') { var show = polyline.show; if (typeof show === 'undefined') { @@ -135,6 +98,15 @@ function( } show.processCzmlIntervals(polylineData.show, interval); } + + if (typeof polylineData.material !== 'undefined') { + var material = polyline.material; + if (typeof material === 'undefined') { + polyline.material = material = new DynamicMaterialProperty(); + polylineUpdated = true; + } + material.processCzmlIntervals(polylineData.material, interval); + } return polylineUpdated; }; @@ -158,11 +130,9 @@ function( targetObject.polyline = targetPolyline = new DynamicPolyline(); } - targetPolyline.color = defaultValue(targetPolyline.color, polylineToMerge.color); targetPolyline.width = defaultValue(targetPolyline.width, polylineToMerge.width); - targetPolyline.outlineColor = defaultValue(targetPolyline.outlineColor, polylineToMerge.outlineColor); - targetPolyline.outlineWidth = defaultValue(targetPolyline.outlineWidth, polylineToMerge.outlineWidth); targetPolyline.show = defaultValue(targetPolyline.show, polylineToMerge.show); + targetPolyline.material = defaultValue(targetPolyline.material, polylineToMerge.material); } }; diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index 7cf0f37bb4bf..0586aedf5a9a 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -3,14 +3,14 @@ define([ '../Core/DeveloperError', '../Core/destroyObject', '../Core/Cartesian3', - '../Core/Color', - '../Scene/PolylineCollection' + '../Scene/PolylineCollection', + '../Scene/Material' ], function( DeveloperError, destroyObject, Cartesian3, - Color, - PolylineCollection) { + PolylineCollection, + Material) { "use strict"; /** @@ -195,6 +195,7 @@ define([ return; } + var context = this._scene.getContext(); if (typeof polylineVisualizerIndex === 'undefined') { var unusedIndexes = this._unusedIndexes; var length = unusedIndexes.length; @@ -209,8 +210,7 @@ define([ polyline.dynamicObject = dynamicObject; // CZML_TODO Determine official defaults - polyline.setDefaultColor(Color.WHITE); - polyline.setDefaultOutlineColor(Color.BLACK); + polyline.setMaterial(Material.fromType(context, Material.ColorType)); polyline.setWidth(1); } else { polyline = this._polylineCollection.get(polylineVisualizerIndex); @@ -230,23 +230,18 @@ define([ polyline._visualizerPositions = vertexPositions; } - var property = dynamicPolyline.color; - if (typeof property !== 'undefined') { - polyline.setDefaultColor(property.getValue(time, polyline.getDefaultColor())); - } - - property = dynamicPolyline.outlineColor; - if (typeof property !== 'undefined') { - polyline.setDefaultOutlineColor(property.getValue(time, polyline.getDefaultOutlineColor())); - } - - property = dynamicPolyline.width; + var property = dynamicPolyline.width; if (typeof property !== 'undefined') { var width = property.getValue(time); if (typeof width !== 'undefined') { polyline.setWidth(width); } } + + var material = dynamicPolyline.material; + if (typeof material !== 'undefined') { + polyline.setMaterial(material.getValue(time, context, polyline.getMaterial())); + } }; DynamicPolylineVisualizer.prototype._onObjectsRemoved = function(dynamicObjectCollection, dynamicObjects) { diff --git a/Specs/DynamicScene/DynamicPathSpec.js b/Specs/DynamicScene/DynamicPathSpec.js index 6e0dc40c5a84..aa4671cb9a51 100644 --- a/Specs/DynamicScene/DynamicPathSpec.js +++ b/Specs/DynamicScene/DynamicPathSpec.js @@ -19,15 +19,15 @@ defineSuite([ it('processCzmlPacket adds data for infinite path.', function() { var pathPacket = { path : { - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - }, width : 1.0, - resolution : 23.0, - outlineColor : { - rgbaf : [0.2, 0.2, 0.2, 0.2] + material : { + solidColor : { + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] + } + } }, - outlineWidth : 1.0, + resolution : 23.0, leadTime : 2.0, trailTime : 3.0, show : true @@ -38,11 +38,9 @@ defineSuite([ expect(DynamicPath.processCzmlPacket(dynamicObject, pathPacket)).toEqual(true); expect(dynamicObject.path).toBeDefined(); - expect(dynamicObject.path.color.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.width.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.width); + expect(dynamicObject.path.material.getValue(Iso8601.MINIMUM_VALUE).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.resolution.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.resolution); - expect(dynamicObject.path.outlineColor.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); - expect(dynamicObject.path.outlineWidth.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.outlineWidth); expect(dynamicObject.path.leadTime.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.leadTime); expect(dynamicObject.path.trailTime.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.trailTime); expect(dynamicObject.path.show.getValue(Iso8601.MINIMUM_VALUE)).toEqual(true); @@ -52,15 +50,15 @@ defineSuite([ var pathPacket = { path : { interval : '2000-01-01/2001-01-01', - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - }, width : 1.0, - resolution : 23.0, - outlineColor : { - rgbaf : [0.2, 0.2, 0.2, 0.2] + material : { + solidColor : { + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] + } + } }, - outlineWidth : 1.0, + resolution : 23.0, leadTime : 2.0, trailTime : 3.0, show : true @@ -74,19 +72,15 @@ defineSuite([ expect(DynamicPath.processCzmlPacket(dynamicObject, pathPacket)).toEqual(true); expect(dynamicObject.path).toBeDefined(); - expect(dynamicObject.path.color.getValue(validTime)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.width.getValue(validTime)).toEqual(pathPacket.path.width); + expect(dynamicObject.path.material.getValue(validTime).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.resolution.getValue(validTime)).toEqual(pathPacket.path.resolution); - expect(dynamicObject.path.outlineColor.getValue(validTime)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); - expect(dynamicObject.path.outlineWidth.getValue(validTime)).toEqual(pathPacket.path.outlineWidth); expect(dynamicObject.path.leadTime.getValue(validTime)).toEqual(pathPacket.path.leadTime); expect(dynamicObject.path.trailTime.getValue(validTime)).toEqual(pathPacket.path.trailTime); expect(dynamicObject.path.show.getValue(validTime)).toEqual(true); - expect(dynamicObject.path.color.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.width.getValue(invalidTime)).toBeUndefined(); - expect(dynamicObject.path.outlineColor.getValue(invalidTime)).toBeUndefined(); - expect(dynamicObject.path.outlineWidth.getValue(invalidTime)).toBeUndefined(); + expect(dynamicObject.path.material.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.leadTime.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.trailTime.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.show.getValue(invalidTime)).toBeUndefined(); @@ -102,60 +96,51 @@ defineSuite([ it('mergeProperties does not change a fully configured path', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.path = new DynamicPath(); - objectToMerge.path.color = 1; - objectToMerge.path.width = 2; - objectToMerge.path.outlineColor = 3; - objectToMerge.path.outlineWidth = 4; - objectToMerge.path.show = 5; - objectToMerge.path.leadTime = 6; - objectToMerge.path.trailTime = 7; - objectToMerge.path.resolution = 8; + objectToMerge.path.width = 1; + objectToMerge.path.material = 2; + objectToMerge.path.show = 3; + objectToMerge.path.leadTime = 4; + objectToMerge.path.trailTime = 5; + objectToMerge.path.resolution = 6; var targetObject = new DynamicObject('targetObject'); targetObject.path = new DynamicPath(); - targetObject.path.color = 9; - targetObject.path.width = 10; - targetObject.path.outlineColor = 11; - targetObject.path.outlineWidth = 12; - targetObject.path.show = 13; - targetObject.path.leadTime = 14; - targetObject.path.trailTime = 15; - targetObject.path.resolution = 16; + targetObject.path.width = 7; + targetObject.path.material = 8; + targetObject.path.show = 9; + targetObject.path.leadTime = 10; + targetObject.path.trailTime = 11; + targetObject.path.resolution = 12; DynamicPath.mergeProperties(targetObject, objectToMerge); - expect(targetObject.path.color).toEqual(9); - expect(targetObject.path.width).toEqual(10); - expect(targetObject.path.outlineColor).toEqual(11); - expect(targetObject.path.outlineWidth).toEqual(12); - expect(targetObject.path.show).toEqual(13); - expect(targetObject.path.leadTime).toEqual(14); - expect(targetObject.path.trailTime).toEqual(15); - expect(targetObject.path.resolution).toEqual(16); + expect(targetObject.path.width).toEqual(7); + expect(targetObject.path.material).toEqual(8); + expect(targetObject.path.show).toEqual(9); + expect(targetObject.path.leadTime).toEqual(10); + expect(targetObject.path.trailTime).toEqual(11); + expect(targetObject.path.resolution).toEqual(12); }); it('mergeProperties creates and configures an undefined path', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.path = new DynamicPath(); - objectToMerge.path.color = 1; - objectToMerge.path.width = 2; - objectToMerge.path.outlineColor = 3; - objectToMerge.path.outlineWidth = 4; - objectToMerge.path.show = 5; - objectToMerge.path.leadTime = 6; - objectToMerge.path.trailTime = 7; - objectToMerge.path.resolution = 8; + objectToMerge.path.width = 1; + objectToMerge.path.material = 2; + objectToMerge.path.show = 3; + objectToMerge.path.leadTime = 4; + objectToMerge.path.trailTime = 5; + objectToMerge.path.resolution = 6; var targetObject = new DynamicObject('targetObject'); DynamicPath.mergeProperties(targetObject, objectToMerge); - expect(targetObject.path.color).toEqual(objectToMerge.path.color); expect(targetObject.path.width).toEqual(objectToMerge.path.width); - expect(targetObject.path.outlineColor).toEqual(objectToMerge.path.outlineColor); - expect(targetObject.path.outlineWidth).toEqual(objectToMerge.path.outlineWidth); + expect(targetObject.path.material).toEqual(objectToMerge.path.material); expect(targetObject.path.show).toEqual(objectToMerge.path.show); expect(targetObject.path.leadTime).toEqual(objectToMerge.path.leadTime); expect(targetObject.path.trailTime).toEqual(objectToMerge.path.trailTime); + expect(targetObject.path.resolution).toEqual(objectToMerge.path.resolution); }); it('mergeProperties does not change when used with an undefined path', function() { @@ -163,25 +148,20 @@ defineSuite([ var targetObject = new DynamicObject('targetObject'); targetObject.path = new DynamicPath(); - targetObject.path = new DynamicPath(); - targetObject.path.color = 1; - targetObject.path.width = 2; - targetObject.path.outlineColor = 3; - targetObject.path.outlineWidth = 4; - targetObject.path.show = 5; - targetObject.path.leadTime = 6; - targetObject.path.trailTime = 7; - targetObject.path.resolution = 8; + targetObject.path.width = 1; + targetObject.path.material = 2; + targetObject.path.show = 3; + targetObject.path.leadTime = 4; + targetObject.path.trailTime = 5; + targetObject.path.resolution = 6; DynamicPath.mergeProperties(targetObject, objectToMerge); - expect(targetObject.path.color).toEqual(1); - expect(targetObject.path.width).toEqual(2); - expect(targetObject.path.outlineColor).toEqual(3); - expect(targetObject.path.outlineWidth).toEqual(4); - expect(targetObject.path.show).toEqual(5); - expect(targetObject.path.leadTime).toEqual(6); - expect(targetObject.path.trailTime).toEqual(7); - expect(targetObject.path.resolution).toEqual(8); + expect(targetObject.path.width).toEqual(1); + expect(targetObject.path.material).toEqual(2); + expect(targetObject.path.show).toEqual(3); + expect(targetObject.path.leadTime).toEqual(4); + expect(targetObject.path.trailTime).toEqual(5); + expect(targetObject.path.resolution).toEqual(6); }); it('undefineProperties works', function() { diff --git a/Specs/DynamicScene/DynamicPathVisualizerSpec.js b/Specs/DynamicScene/DynamicPathVisualizerSpec.js index de37a0c4b872..e390a146f4b5 100644 --- a/Specs/DynamicScene/DynamicPathVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPathVisualizerSpec.js @@ -11,7 +11,8 @@ defineSuite([ 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Color', - 'Scene/Scene' + 'Scene/Scene', + 'Scene/Material' ], function( DynamicPathVisualizer, createScene, @@ -24,7 +25,8 @@ defineSuite([ Cartesian2, Cartesian3, Color, - Scene) { + Scene, + Material) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ @@ -113,12 +115,12 @@ defineSuite([ var path = testObject.path = new DynamicPath(); path.show = new MockProperty(true); - path.color = new MockProperty(new Color(0.8, 0.7, 0.6, 0.5)); path.width = new MockProperty(12.5); - path.outlineColor = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); - path.outlineWidth = new MockProperty(2.5); path.leadTime = new MockProperty(25); path.trailTime = new MockProperty(10); + var colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); + colorMaterial.uniforms.color = new Color(0.7, 0.6, 0.5, 0.4); + path.material = new MockProperty(colorMaterial); visualizer.update(time); @@ -130,22 +132,20 @@ defineSuite([ expect(testObject.position.lastStop).toEqual(time.addSeconds(path.leadTime.getValue())); expect(primitive.getShow()).toEqual(testObject.path.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); - expect(primitive.getDefaultColor()).toEqual(testObject.path.color.getValue(time)); - expect(primitive.getDefaultOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); + expect(primitive.getMaterial()).toEqual(testObject.path.material.getValue(time)); testObject.position = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); - path.color = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); path.width = new MockProperty(2.5); - path.outlineColor = new MockProperty(new Color(0.5, 0.6, 0.7, 0.8)); - path.outlineWidth = new MockProperty(12.5); + colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); + colorMaterial.uniforms.color = new Color(0.1, 0.2, 0.4, 0.3); + path.material = new MockProperty(colorMaterial); visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.path.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); - expect(primitive.getDefaultColor()).toEqual(testObject.path.color.getValue(time)); - expect(primitive.getDefaultOutlineColor()).toEqual(testObject.path.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); + expect(primitive.getMaterial()).toEqual(testObject.path.material.getValue(time)); path.show = new MockProperty(false); visualizer.update(time); diff --git a/Specs/DynamicScene/DynamicPolylineSpec.js b/Specs/DynamicScene/DynamicPolylineSpec.js index edc604901a64..7fa08b907fe6 100644 --- a/Specs/DynamicScene/DynamicPolylineSpec.js +++ b/Specs/DynamicScene/DynamicPolylineSpec.js @@ -19,14 +19,14 @@ defineSuite([ it('processCzmlPacket adds data for infinite polyline.', function() { var polylinePacket = { polyline : { - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - }, width : 1.0, - outlineColor : { - rgbaf : [0.2, 0.2, 0.2, 0.2] + material : { + solidColor : { + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] + } + } }, - outlineWidth : 1.0, show : true } }; @@ -35,10 +35,8 @@ defineSuite([ expect(DynamicPolyline.processCzmlPacket(dynamicObject, polylinePacket)).toEqual(true); expect(dynamicObject.polyline).toBeDefined(); - expect(dynamicObject.polyline.color.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.polyline.width.getValue(Iso8601.MINIMUM_VALUE)).toEqual(polylinePacket.polyline.width); - expect(dynamicObject.polyline.outlineColor.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); - expect(dynamicObject.polyline.outlineWidth.getValue(Iso8601.MINIMUM_VALUE)).toEqual(polylinePacket.polyline.outlineWidth); + expect(dynamicObject.polyline.material.getValue(Iso8601.MINIMUM_VALUE).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.polyline.show.getValue(Iso8601.MINIMUM_VALUE)).toEqual(true); }); @@ -46,14 +44,14 @@ defineSuite([ var polylinePacket = { polyline : { interval : '2000-01-01/2001-01-01', - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - }, width : 1.0, - outlineColor : { - rgbaf : [0.2, 0.2, 0.2, 0.2] + material : { + solidColor : { + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] + } + } }, - outlineWidth : 1.0, show : true } }; @@ -65,16 +63,12 @@ defineSuite([ expect(DynamicPolyline.processCzmlPacket(dynamicObject, polylinePacket)).toEqual(true); expect(dynamicObject.polyline).toBeDefined(); - expect(dynamicObject.polyline.color.getValue(validTime)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.polyline.width.getValue(validTime)).toEqual(polylinePacket.polyline.width); - expect(dynamicObject.polyline.outlineColor.getValue(validTime)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); - expect(dynamicObject.polyline.outlineWidth.getValue(validTime)).toEqual(polylinePacket.polyline.outlineWidth); + expect(dynamicObject.polyline.material.getValue(validTime).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.polyline.show.getValue(validTime)).toEqual(true); - expect(dynamicObject.polyline.color.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.polyline.width.getValue(invalidTime)).toBeUndefined(); - expect(dynamicObject.polyline.outlineColor.getValue(invalidTime)).toBeUndefined(); - expect(dynamicObject.polyline.outlineWidth.getValue(invalidTime)).toBeUndefined(); + expect(dynamicObject.polyline.material.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.polyline.show.getValue(invalidTime)).toBeUndefined(); }); @@ -88,37 +82,29 @@ defineSuite([ it('mergeProperties does not change a fully configured polyline', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.polyline = new DynamicPolyline(); - objectToMerge.polyline.color = 1; - objectToMerge.polyline.width = 2; - objectToMerge.polyline.outlineColor = 3; - objectToMerge.polyline.outlineWidth = 4; - objectToMerge.polyline.show = 5; + objectToMerge.polyline.width = 1; + objectToMerge.polyline.material = 2; + objectToMerge.polyline.show = 3; var targetObject = new DynamicObject('targetObject'); targetObject.polyline = new DynamicPolyline(); - targetObject.polyline.color = 6; - targetObject.polyline.width = 7; - targetObject.polyline.outlineColor = 8; - targetObject.polyline.outlineWidth = 9; - targetObject.polyline.show = 10; + targetObject.polyline.width = 4; + targetObject.polyline.material = 5; + targetObject.polyline.show = 6; DynamicPolyline.mergeProperties(targetObject, objectToMerge); - expect(targetObject.polyline.color).toEqual(6); - expect(targetObject.polyline.width).toEqual(7); - expect(targetObject.polyline.outlineColor).toEqual(8); - expect(targetObject.polyline.outlineWidth).toEqual(9); - expect(targetObject.polyline.show).toEqual(10); + expect(targetObject.polyline.width).toEqual(4); + expect(targetObject.polyline.material).toEqual(5); + expect(targetObject.polyline.show).toEqual(6); }); it('mergeProperties creates and configures an undefined polyline', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.polyline = new DynamicPolyline(); - objectToMerge.polyline.color = 1; - objectToMerge.polyline.width = 2; - objectToMerge.polyline.outlineColor = 3; - objectToMerge.polyline.outlineWidth = 4; - objectToMerge.polyline.show = 5; + objectToMerge.polyline.width = 1; + objectToMerge.polyline.material = 2; + objectToMerge.polyline.show = 3; var targetObject = new DynamicObject('targetObject'); @@ -136,19 +122,15 @@ defineSuite([ var targetObject = new DynamicObject('targetObject'); targetObject.polyline = new DynamicPolyline(); - targetObject.polyline.color = 6; - targetObject.polyline.width = 7; - targetObject.polyline.outlineColor = 8; - targetObject.polyline.outlineWidth = 9; - targetObject.polyline.show = 10; + targetObject.polyline.width = 4; + targetObject.polyline.material = 5; + targetObject.polyline.show = 6; DynamicPolyline.mergeProperties(targetObject, objectToMerge); - expect(targetObject.polyline.color).toEqual(6); - expect(targetObject.polyline.width).toEqual(7); - expect(targetObject.polyline.outlineColor).toEqual(8); - expect(targetObject.polyline.outlineWidth).toEqual(9); - expect(targetObject.polyline.show).toEqual(10); + expect(targetObject.polyline.width).toEqual(4); + expect(targetObject.polyline.material).toEqual(5); + expect(targetObject.polyline.show).toEqual(6); }); it('undefineProperties works', function() { diff --git a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js index 600ae1f5cc19..a9a6a2de8c76 100644 --- a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js @@ -12,7 +12,8 @@ defineSuite([ 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Color', - 'Scene/Scene' + 'Scene/Scene', + 'Scene/Material' ], function( DynamicPolylineVisualizer, createScene, @@ -26,7 +27,8 @@ defineSuite([ Cartesian2, Cartesian3, Color, - Scene) { + Scene, + Material) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ @@ -185,10 +187,10 @@ defineSuite([ var polyline = testObject.polyline = new DynamicPolyline(); polyline.show = new MockProperty(true); - polyline.color = new MockProperty(new Color(0.8, 0.7, 0.6, 0.5)); polyline.width = new MockProperty(12.5); - polyline.outlineColor = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); - polyline.outlineWidth = new MockProperty(2.5); + var colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); + colorMaterial.uniforms.color = new Color(0.7, 0.6, 0.5, 0.4); + polyline.material = new MockProperty(colorMaterial); visualizer.update(time); @@ -199,22 +201,20 @@ defineSuite([ visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); - expect(primitive.getDefaultColor()).toEqual(testObject.polyline.color.getValue(time)); - expect(primitive.getDefaultOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); + expect(primitive.getMaterial()).toEqual(testObject.polyline.material.getValue(time)); testObject.vertexPositions = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); - polyline.color = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); polyline.width = new MockProperty(2.5); - polyline.outlineColor = new MockProperty(new Color(0.5, 0.6, 0.7, 0.8)); - polyline.outlineWidth = new MockProperty(12.5); + colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); + colorMaterial.uniforms.color = new Color(0.1, 0.2, 0.4, 0.3); + polyline.material = new MockProperty(colorMaterial); visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); - expect(primitive.getDefaultColor()).toEqual(testObject.polyline.color.getValue(time)); - expect(primitive.getDefaultOutlineColor()).toEqual(testObject.polyline.outlineColor.getValue(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); + expect(primitive.getMaterial()).toEqual(testObject.polyline.material.getValue(time)); polyline.show = new MockProperty(false); visualizer.update(time); From c53347a2457a5cf386f02c2f558211b79c8da1f8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 17:14:21 -0400 Subject: [PATCH 068/114] Update tests. --- Apps/Sandcastle/gallery/Polylines.html | 3 - Source/Scene/Material.js | 6 +- Source/Scene/Polyline.js | 3 + Source/Scene/PolylineCollection.js | 3 - Specs/Scene/PolylineCollectionSpec.js | 307 ++----------------------- 5 files changed, 31 insertions(+), 291 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.html b/Apps/Sandcastle/gallery/Polylines.html index 5a98c075429e..9ed6f366321a 100644 --- a/Apps/Sandcastle/gallery/Polylines.html +++ b/Apps/Sandcastle/gallery/Polylines.html @@ -71,8 +71,6 @@ // Set the polyline's material to have an outline var outlineMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineOutlineType); - outlineMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 1.0, 1.0); - outlineMaterial.uniforms.outlineColor = new Cesium.Color(1.0, 0.0, 0.0, 1.0); outlineMaterial.uniforms.outlineWidth = 5.0; widePolyline.setMaterial(outlineMaterial); @@ -91,7 +89,6 @@ ]); localPolyline.setWidth(10.0); var arrowMaterial = Cesium.Material.fromType(undefined, Cesium.Material.PolylineArrowType); - arrowMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 1.0, 1.0); localPolyline.setMaterial(arrowMaterial); primitives.add(localPolylines); } diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 18cc8047c258..e1c4c4b0c620 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -1206,7 +1206,7 @@ define([ Material._materialCache.addMaterial(Material.PolylineArrowType, { type : Material.PolylineArrowType, uniforms : { - color : new Color(1.0, 0.0, 0.0, 1.0) + color : new Color(1.0, 1.0, 1.0, 1.0) }, source : PolylineArrowMaterial }); @@ -1215,8 +1215,8 @@ define([ Material._materialCache.addMaterial(Material.PolylineOutlineType, { type : Material.PolylineOutlineType, uniforms : { - color : new Color(1.0, 0.0, 0.0, 1.0), - outlineColor : new Color(1.0, 1.0, 1.0, 1.0), + color : new Color(1.0, 1.0, 1.0, 1.0), + outlineColor : new Color(1.0, 0.0, 0.0, 1.0), outlineWidth : 0.0 }, source : PolylineOutlineMaterial diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index e59198a76c72..cc2e0e7e89c4 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -5,6 +5,7 @@ define([ '../Core/destroyObject', '../Core/BoundingSphere', '../Core/Cartesian3', + '../Core/Color', '../Core/PolylinePipeline', '../Core/Matrix4', './Material' @@ -14,6 +15,7 @@ define([ destroyObject, BoundingSphere, Cartesian3, + Color, PolylinePipeline, Matrix4, Material) { @@ -36,6 +38,7 @@ define([ this._material = description.material; if (typeof this._material === 'undefined') { this._material = Material.fromType(undefined, Material.ColorType); + this._material.uniforms.color = new Color(1.0, 1.0, 1.0, 1.0); } var positions = description.positions; diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 3e024df60624..16d093184cd5 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -10,7 +10,6 @@ define([ '../Core/ComponentDatatype', '../Core/IndexDatatype', '../Core/PrimitiveType', - '../Core/Color', '../Core/BoundingSphere', '../Core/Intersect', '../Renderer/BlendingState', @@ -35,7 +34,6 @@ define([ ComponentDatatype, IndexDatatype, PrimitiveType, - Color, BoundingSphere, Intersect, BlendingState, @@ -205,7 +203,6 @@ define([ * positions : ellipsoid.cartographicDegreesToCartesians([ * new Cartographic2(-75.10, 39.57), * new Cartographic2(-77.02, 38.53)]), - * color : { red : 1.0, green : 1.0, blue : 1.0, alpha : 1.0 }, * width : 1 * }); * diff --git a/Specs/Scene/PolylineCollectionSpec.js b/Specs/Scene/PolylineCollectionSpec.js index 64fa22865d1e..08430dcb4b5b 100644 --- a/Specs/Scene/PolylineCollectionSpec.js +++ b/Specs/Scene/PolylineCollectionSpec.js @@ -13,11 +13,13 @@ defineSuite([ 'Core/BoundingSphere', 'Core/Cartesian3', 'Core/Cartographic', + 'Core/Color', 'Core/Matrix4', 'Core/Math', 'Core/JulianDate', 'Renderer/BufferUsage', - 'Scene/SceneMode' + 'Scene/SceneMode', + 'Scene/Material' ], function( PolylineCollection, Polyline, @@ -32,11 +34,13 @@ defineSuite([ BoundingSphere, Cartesian3, Cartographic, + Color, Matrix4, CesiumMath, JulianDate, BufferUsage, - SceneMode) { + SceneMode, + Material) { "use strict"; /*global it,expect,beforeEach,afterEach,beforeAll,afterAll*/ @@ -67,80 +71,43 @@ defineSuite([ var p = polylines.add(); expect(p.getShow()).toEqual(true); expect(p.getPositions().length).toEqual(0); - expect(p.getDefaultColor().red).toEqual(1.0); - expect(p.getDefaultColor().green).toEqual(1.0); - expect(p.getDefaultColor().blue).toEqual(1.0); - expect(p.getDefaultColor().alpha).toEqual(1.0); - expect(p.getDefaultOutlineColor().red).toEqual(1.0); - expect(p.getDefaultOutlineColor().green).toEqual(1.0); - expect(p.getDefaultOutlineColor().blue).toEqual(1.0); - expect(p.getDefaultOutlineColor().alpha).toEqual(0.0); expect(p.getWidth()).toEqual(1.0); + expect(p.getMaterial().uniforms.color).toEqual(new Color(1.0, 1.0, 1.0, 1.0)); }); it('explicitly constructs a polyline', function() { + var material = Material.fromType(context, Material.PolylineOutlineType); var p = polylines.add({ show : false, positions : [new Cartesian3(1.0, 2.0, 3.0), new Cartesian3(4.0, 5.0, 6.0)], width : 2, - color : { - red : 1.0, - green : 2.0, - blue : 3.0, - alpha : 4.0 - }, - outlineColor: { - red : 6.0, - green : 7.0, - blue : 8.0, - alpha : 9.0 - } + material : material }); expect(p.getShow()).toEqual(false); expect(p.getPositions()[0]).toEqual(new Cartesian3(1.0, 2.0, 3.0)); expect(p.getPositions()[1]).toEqual(new Cartesian3(4.0, 5.0, 6.0)); - expect(p.getDefaultColor().red).toEqual(1.0); - expect(p.getDefaultColor().green).toEqual(2.0); - expect(p.getDefaultColor().blue).toEqual(3.0); - expect(p.getDefaultColor().alpha).toEqual(4.0); expect(p.getWidth()).toEqual(2); - expect(p.getDefaultOutlineColor().red).toEqual(6.0); - expect(p.getDefaultOutlineColor().green).toEqual(7.0); - expect(p.getDefaultOutlineColor().blue).toEqual(8.0); - expect(p.getDefaultOutlineColor().alpha).toEqual(9.0); + expect(p.getMaterial().uniforms.color).toEqual(material.uniforms.color); + expect(p.getMaterial().uniforms.outlineColor).toEqual(material.uniforms.outlineColor); + expect(p.getMaterial().uniforms.outlineWidth).toEqual(material.uniforms.outlineWidth); }); it('sets polyline properties', function() { + var material = Material.fromType(context, Material.PolylineOutlineType); var p = polylines.add(); p.setShow(false); p.setPositions([new Cartesian3(1.0, 2.0, 3.0), new Cartesian3(4.0, 5.0, 6.0)]); - p.setDefaultColor({ - red : 1.0, - green : 2.0, - blue : 3.0, - alpha : 4.0 - }); - p.setDefaultOutlineColor({ - red : 5.0, - green : 6.0, - blue : 7.0, - alpha : 8.0 - }); p.setWidth(2); + p.setMaterial(material); expect(p.getShow()).toEqual(false); expect(p.getPositions()[0]).toEqual(new Cartesian3(1.0, 2.0, 3.0)); expect(p.getPositions()[1]).toEqual(new Cartesian3(4.0, 5.0, 6.0)); - expect(p.getDefaultColor().red).toEqual(1.0); - expect(p.getDefaultColor().green).toEqual(2.0); - expect(p.getDefaultColor().blue).toEqual(3.0); - expect(p.getDefaultColor().alpha).toEqual(4.0); expect(p.getWidth()).toEqual(2); - expect(p.getDefaultOutlineColor().red).toEqual(5.0); - expect(p.getDefaultOutlineColor().green).toEqual(6.0); - expect(p.getDefaultOutlineColor().blue).toEqual(7.0); - expect(p.getDefaultOutlineColor().alpha).toEqual(8.0); + expect(p.getMaterial().uniforms.color).toEqual(material.uniforms.color); + expect(p.getMaterial().uniforms.outlineColor).toEqual(material.uniforms.outlineColor); + expect(p.getMaterial().uniforms.outlineWidth).toEqual(material.uniforms.outlineWidth); }); it('sets removed polyline properties', function() { @@ -713,7 +680,7 @@ defineSuite([ render(context, frameState, polylines); expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - //should call PolylineCollection.writeShowUpdate + //should call PolylineCollection.writeMiscUpdate p2.setShow(true); context.clear(); @@ -724,7 +691,7 @@ defineSuite([ }); - it('renders an updated polyline with no positions using setDefaultColor', function() { + it('renders an updated polyline with no positions using setMaterial', function() { var positions = []; for ( var i = 0; i < 100; ++i) { positions.push({ @@ -740,13 +707,7 @@ defineSuite([ } polylines.add({ - positions : positions, - color : { - red : 1, - green : 0, - blue : 0, - alpha : 1 - } + positions : positions }); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -755,13 +716,7 @@ defineSuite([ expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); var p2 = polylines.add({ - positions : [], - color : { - red : 0, - green : 1, - blue : 0, - alpha : 1 - } + positions : [] }); context.clear(); @@ -771,26 +726,7 @@ defineSuite([ expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); //recreates vertex array because buffer usage changed - p2.setDefaultColor({ - red : 1.0, - blue : 1.0, - green : 0.1, - alpha : 1.0 - }); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - //should call PolylineCollection.writeColorUpdate - p2.setDefaultColor({ - red : 1.0, - blue : 0.5, - green : 0.1, - alpha : 1.0 - }); + p2.setMaterial(Material.fromType(context, Material.PolylineOutlineType)); context.clear(); expect(context.readPixels()).toEqual([0, 0, 0, 0]); @@ -843,81 +779,6 @@ defineSuite([ }); - it('renders an updated polyline with no positions using setDefaultOutlineColor', function() { - var positions = []; - for ( var i = 0; i < 100; ++i) { - positions.push({ - x : 0, - y : -1, - z : 0 - }); - positions.push({ - x : 0, - y : 1, - z : 0 - }); - } - - polylines.add({ - positions : positions, - color : { - red : 1, - green : 0, - blue : 0, - alpha : 1 - } - }); - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - var p2 = polylines.add({ - positions : [], - color : { - red : 0, - green : 1, - blue : 0, - alpha : 1 - } - }); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - //recreates vertex array because buffer usage changed - p2.setDefaultOutlineColor({ - red : 1.0, - blue : 1.0, - green : 0.1, - alpha : 1.0 - }); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - //should call PolylineCollection.writeColorUpdate - p2.setDefaultOutlineColor({ - red : 1.0, - blue : 0.5, - green : 0.1, - alpha : 1.0 - }); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - }); - it('renders more than 64K vertices of different polylines', function() { var positions = []; for ( var i = 0; i < 64 * 1024; ++i) { @@ -1365,96 +1226,6 @@ defineSuite([ expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); - it('renders using polyline color property', function() { - var p = polylines.add({ - positions : [{ - x : 0.0, - y : -1.0, - z : 0.0 - }, { - x : 0.0, - y : 1.0, - z : 0.0 - }] - }); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - p.setDefaultColor({ - red : 1.0, - green : 0.0, - blue : 1.0, - alpha : 1.0 - }); - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - // Update a second time since it goes through a different vertex array update path - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - p.setDefaultColor({ - red : 0.0, - green : 1.0, - blue : 0.0, - alpha : 1.0 - }); - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - }); - - it('renders using polyline outlineColor property', function() { - var p = polylines.add({ - positions : [{ - x : 0.0, - y : -1.0, - z : 0.0 - }, { - x : 0.0, - y : 1.0, - z : 0.0 - }] - }); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - p.setDefaultOutlineColor({ - red : 1.0, - green : 0.0, - blue : 1.0, - alpha : 1.0 - }); - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - - // Update a second time since it goes through a different vertex array update path - context.clear(); - expect(context.readPixels()).toEqual([0, 0, 0, 0]); - - p.setDefaultOutlineColor({ - red : 0.0, - green : 1.0, - blue : 0.0, - alpha : 1.0 - }); - render(context, frameState, polylines); - expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - }); - it('renders and updates one polyline from many polylines using show property', function() { var positions = []; for(var i = 0; i < 200; i++){ @@ -1643,22 +1414,10 @@ defineSuite([ } polylines.add({ positions : positions, - color:{ - red : 1.0, - green : 0.0, - blue : 0.0, - alpha : 1.0 - }, width : 3 }); polylines.add({ positions : positions, - color:{ - red : 1.0, - green : 0.0, - blue : 0.0, - alpha : 1.0 - }, width : 4 }); var p2 = polylines.add({ @@ -1671,12 +1430,6 @@ defineSuite([ y : 1.0, z : 0.0 }], - color:{ - red : 0.0, - green : 0.0, - blue : 1.0, - alpha : 1.0 - }, width : 7 }); context.clear(); @@ -1685,21 +1438,11 @@ defineSuite([ render(context, frameState, polylines); expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - p2.setDefaultColor({ - red : 1.0, - green : 1.0, - blue : 0.0, - alpha : 1.0 - }); + p2.setMaterial(Material.fromType(context, Material.PolylineOutlineType)); render(context, frameState, polylines); expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); - p2.setDefaultColor({ - red : 1.0, - green : 0.0, - blue : 0.0, - alpha : 1.0 - }); + p2.setMaterial(Material.fromType(context, Material.ColorType)); render(context, frameState, polylines); expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); @@ -1817,7 +1560,7 @@ defineSuite([ }); var pickedObject = pick(context, frameState, polylines, 0, 0); - expect(pickedObject).toNotBeDefined(); + expect(pickedObject).toBeUndefined(); }); it('does not equal undefined', function() { From 1ee20fb58f53f9cfa9f7f96982a15c42f73b224e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 17:28:16 -0400 Subject: [PATCH 069/114] Update polyline arrow material shader. --- Source/Shaders/Materials/PolylineArrowMaterial.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index 49eb1b143eff..00817ab034ce 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -1,4 +1,4 @@ -#extension GL_OES_standard_derivatives : enable // TODO check for support +#extension GL_OES_standard_derivatives : enable // TODO Is there an alternative if standard derivatives aren't supported? uniform vec4 color; @@ -16,7 +16,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) vec2 st = materialInput.st; - float base = 1.0 - dFdx(st.s) * 10.0; + float base = 1.0 - abs(dFdx(st.s)) * 10.0; vec2 center = vec2(1.0, 0.5); float ptOnUpperLine = getPointOnLine(vec2(base, 1.0), center, st.s); float ptOnLowerLine = getPointOnLine(vec2(base, 0.0), center, st.s); From 40f63924bc58d61cedfbe38f0d32354e17a068a4 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 17:51:55 -0400 Subject: [PATCH 070/114] Fix polylines in 2D. --- Source/Shaders/Materials/PolylineArrowMaterial.glsl | 3 ++- Source/Shaders/PolylineVS.glsl | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index 00817ab034ce..19cfc9386af3 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -1,4 +1,5 @@ -#extension GL_OES_standard_derivatives : enable // TODO Is there an alternative if standard derivatives aren't supported? +// TODO Is there an alternative if standard derivatives aren't supported? +#extension GL_OES_standard_derivatives : enable uniform vec4 color; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 1bd9b6fcdd2e..d829f237cce2 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -104,8 +104,8 @@ void main() expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0); } - vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, endPointWC.zw); - gl_Position = czm_projection * czm_windowToEyeCoordinates(positionWC) * show; + vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, -endPointWC.z, 1.0); + gl_Position = czm_viewportOrthographic * positionWC * show; #ifndef RENDER_FOR_PICK v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); From e7fe99c049ada6b56fffdb718a3155663ca29392 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 20 Mar 2013 18:07:20 -0400 Subject: [PATCH 071/114] Update CHANGES.md --- CHANGES.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f97d943fc938..41340ad7f577 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,12 +10,16 @@ Beta Releases * `Billboard.computeScreenSpacePosition` now takes `Context` and `FrameState` arguments instead of a `UniformState` argument. * Removed `clampToPixel` property from `BillboardCollection` and `LabelCollection`. This options is no longer be needed due to overall LabelCollection visualization improvements. * Removed `Widgets/Dojo/CesiumWidget` and replaced it with `Widgets/CesiumWidget`, which has no Dojo dependancies. - * `destroyObject` no longer deletes properties from the object being destroyed. + * `destroyObject` no longer deletes properties from the object being destroyed. + * Removed the color, outline color, and outline width properties of polylines. Instead, use materials for polyline color and outline properties. * Added `BoundingSphere.fromCornerPoints`. * Added `fromArray` and `distance` functions to `Cartesian2`, `Cartesian3`, and `Cartesian4`. * Added `DynamicPath.resolution` property for setting the maximum step size, in seconds, to take when sampling a position for path visualization. * Added `TileCoordinatesImageryProvider` that renders imagery with tile X, Y, Level coordinates on the surface of the globe. This is mostly useful for debugging. * Added `DynamicEllipse` and `DynamicObject.ellipse` property to render CZML ellipses on the globe. +* Added wide polylines that work with and without ANGLE. +* Polylines now use materials to describe their surface appearance. See the [Fabric](https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric) wiki page for more details on how to create materials. +* Added new `PolylineOutline`, `PolylineArrow`, and `Fade` materials. ### b14 - 2013-03-01 From 7a6ebcae7911eed1d4155535dc078ab88b546c40 Mon Sep 17 00:00:00 2001 From: mramato Date: Wed, 20 Mar 2013 22:58:16 -0400 Subject: [PATCH 072/114] Update DynamicScene to use new Polyline materials. --- Source/DynamicScene/DynamicPath.js | 70 +++++++--- Source/DynamicScene/DynamicPathVisualizer.js | 37 +++-- Source/DynamicScene/DynamicPolyline.js | 70 +++++++--- .../DynamicScene/DynamicPolylineVisualizer.js | 41 ++++-- Specs/DynamicScene/DynamicPathSpec.js | 130 ++++++++++-------- .../DynamicScene/DynamicPathVisualizerSpec.js | 29 ++-- Specs/DynamicScene/DynamicPolylineSpec.js | 84 ++++++----- .../DynamicPolylineVisualizerSpec.js | 30 ++-- 8 files changed, 316 insertions(+), 175 deletions(-) diff --git a/Source/DynamicScene/DynamicPath.js b/Source/DynamicScene/DynamicPath.js index 5b99dc11e9a1..9b6f6bf2b243 100644 --- a/Source/DynamicScene/DynamicPath.js +++ b/Source/DynamicScene/DynamicPath.js @@ -4,15 +4,15 @@ define([ '../Core/defaultValue', './CzmlBoolean', './CzmlNumber', - './DynamicProperty', - './DynamicMaterialProperty' - ], function( + './CzmlColor', + './DynamicProperty'], +function( TimeInterval, defaultValue, CzmlBoolean, CzmlNumber, - DynamicProperty, - DynamicMaterialProperty) { + CzmlColor, + DynamicProperty) { "use strict"; /** @@ -31,6 +31,21 @@ define([ * @see CzmlDefaults */ var DynamicPath = function() { + /** + * A DynamicProperty of type CzmlColor which determines the line's color. + * @type DynamicProperty + */ + this.color = undefined; + /** + * A DynamicProperty of type CzmlColor which determines the line's outline color. + * @type DynamicProperty + */ + this.outlineColor = undefined; + /** + * A DynamicProperty of type CzmlNumber which determines the line's outline width. + * @type DynamicProperty + */ + this.outlineWidth = undefined; /** * A DynamicProperty of type CzmlBoolean which determines the lines's visibility. * @type DynamicProperty @@ -41,11 +56,6 @@ define([ * @type DynamicProperty */ this.width = undefined; - /** - * A DynamicMaterialProperty which determines the line's material. - * @type DynamicMaterialProperty - */ - this.material = undefined; /** * A DynamicProperty of type CzmlNumber which determines the maximum step size, in seconds, to take when sampling the position. * @type DynamicProperty @@ -96,6 +106,15 @@ define([ interval = TimeInterval.fromIso8601(interval); } + if (typeof pathData.color !== 'undefined') { + var color = path.color; + if (typeof color === 'undefined') { + path.color = color = new DynamicProperty(CzmlColor); + pathUpdated = true; + } + color.processCzmlIntervals(pathData.color, interval); + } + if (typeof pathData.width !== 'undefined') { var width = path.width; if (typeof width === 'undefined') { @@ -114,6 +133,24 @@ define([ resolution.processCzmlIntervals(pathData.resolution, interval); } + if (typeof pathData.outlineColor !== 'undefined') { + var outlineColor = path.outlineColor; + if (typeof outlineColor === 'undefined') { + path.outlineColor = outlineColor = new DynamicProperty(CzmlColor); + pathUpdated = true; + } + outlineColor.processCzmlIntervals(pathData.outlineColor, interval); + } + + if (typeof pathData.outlineWidth !== 'undefined') { + var outlineWidth = path.outlineWidth; + if (typeof outlineWidth === 'undefined') { + path.outlineWidth = outlineWidth = new DynamicProperty(CzmlNumber); + pathUpdated = true; + } + outlineWidth.processCzmlIntervals(pathData.outlineWidth, interval); + } + if (typeof pathData.show !== 'undefined') { var show = path.show; if (typeof show === 'undefined') { @@ -123,15 +160,6 @@ define([ show.processCzmlIntervals(pathData.show, interval); } - if (typeof pathData.material !== 'undefined') { - var material = path.material; - if (typeof material === 'undefined') { - path.material = material = new DynamicMaterialProperty(); - pathUpdated = true; - } - material.processCzmlIntervals(pathData.material, interval); - } - if (typeof pathData.leadTime !== 'undefined') { var leadTime = path.leadTime; if (typeof leadTime === 'undefined') { @@ -173,10 +201,12 @@ define([ targetObject.path = targetpath = new DynamicPath(); } + targetpath.color = defaultValue(targetpath.color, pathToMerge.color); targetpath.width = defaultValue(targetpath.width, pathToMerge.width); targetpath.resolution = defaultValue(targetpath.resolution, pathToMerge.resolution); + targetpath.outlineColor = defaultValue(targetpath.outlineColor, pathToMerge.outlineColor); + targetpath.outlineWidth = defaultValue(targetpath.outlineWidth, pathToMerge.outlineWidth); targetpath.show = defaultValue(targetpath.show, pathToMerge.show); - targetpath.material = defaultValue(targetpath.material, pathToMerge.material); targetpath.leadTime = defaultValue(targetpath.leadTime, pathToMerge.leadTime); targetpath.trailTime = defaultValue(targetpath.trailTime, pathToMerge.trailTime); } diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 32523b7067e5..d4a8f2cf8576 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -7,9 +7,9 @@ define([ '../Core/Color', '../Core/Transforms', '../Core/ReferenceFrame', + '../Scene/Material', '../Scene/SceneMode', - '../Scene/PolylineCollection', - '../Scene/Material' + '../Scene/PolylineCollection' ], function( DeveloperError, destroyObject, @@ -18,9 +18,9 @@ define([ Color, Transforms, ReferenceFrame, + Material, SceneMode, - PolylineCollection, - Material) { + PolylineCollection) { "use strict"; var PolylineUpdater = function(scene, referenceFrame) { @@ -123,7 +123,6 @@ define([ return; } - var context = this._scene.getContext(); if (typeof pathVisualizerIndex === 'undefined') { var unusedIndexes = this._unusedIndexes; var length = unusedIndexes.length; @@ -138,8 +137,12 @@ define([ polyline.dynamicObject = dynamicObject; // CZML_TODO Determine official defaults - polyline.setMaterial(Material.fromType(context, Material.ColorType)); polyline.setWidth(1); + var material = polyline.getMaterial(); + if (typeof material === 'undefined' || (material.type !== Material.PolylineOutlineType)) { + material = Material.fromType(this._scene.getContext(), Material.PolylineOutlineType); + polyline.setMaterial(material); + } } else { polyline = this._polylineCollection.get(pathVisualizerIndex); } @@ -154,6 +157,23 @@ define([ polyline.setPositions(positionProperty._getValueRangeInReferenceFrame(sampleStart, sampleStop, time, this._referenceFrame, resolution, polyline.getPositions())); + var uniforms = polyline.getMaterial().uniforms; + + property = dynamicPath.color; + if (typeof property !== 'undefined') { + uniforms.color = property.getValue(time, uniforms.color); + } + + property = dynamicPath.outlineColor; + if (typeof property !== 'undefined') { + uniforms.outlineColor = property.getValue(time, uniforms.outlineColor); + } + + property = dynamicPath.outlineWidth; + if (typeof property !== 'undefined') { + uniforms.outlineWidth = property.getValue(time, uniforms.outlineWidth); + } + property = dynamicPath.width; if (typeof property !== 'undefined') { var width = property.getValue(time); @@ -161,11 +181,6 @@ define([ polyline.setWidth(width); } } - - var material = dynamicPath.material; - if (typeof material !== 'undefined') { - polyline.setMaterial(material.getValue(time, context, polyline.getMaterial())); - } }; PolylineUpdater.prototype.removeObject = function(dynamicObject) { diff --git a/Source/DynamicScene/DynamicPolyline.js b/Source/DynamicScene/DynamicPolyline.js index 072219a0c1f1..4c46170a04cb 100644 --- a/Source/DynamicScene/DynamicPolyline.js +++ b/Source/DynamicScene/DynamicPolyline.js @@ -4,15 +4,15 @@ define([ '../Core/defaultValue', './CzmlBoolean', './CzmlNumber', - './DynamicProperty', - './DynamicMaterialProperty' - ], function( + './CzmlColor', + './DynamicProperty'], +function( TimeInterval, defaultValue, CzmlBoolean, CzmlNumber, - DynamicProperty, - DynamicMaterialProperty) { + CzmlColor, + DynamicProperty) { "use strict"; /** @@ -31,6 +31,21 @@ define([ * @see CzmlDefaults */ var DynamicPolyline = function() { + /** + * A DynamicProperty of type CzmlColor which determines the line's color. + * @type DynamicProperty + */ + this.color = undefined; + /** + * A DynamicProperty of type CzmlColor which determines the line's outline color. + * @type DynamicProperty + */ + this.outlineColor = undefined; + /** + * A DynamicProperty of type CzmlNumber which determines the line's outline width. + * @type DynamicProperty + */ + this.outlineWidth = undefined; /** * A DynamicProperty of type CzmlBoolean which determines the lines's visibility. * @type DynamicProperty @@ -41,11 +56,6 @@ define([ * @type DynamicProperty */ this.width = undefined; - /** - * A DynamicMaterialProperty which determines the line's material. - * @type DynamicMaterialProperty - */ - this.material = undefined; }; /** @@ -81,6 +91,15 @@ define([ interval = TimeInterval.fromIso8601(interval); } + if (typeof polylineData.color !== 'undefined') { + var color = polyline.color; + if (typeof color === 'undefined') { + polyline.color = color = new DynamicProperty(CzmlColor); + polylineUpdated = true; + } + color.processCzmlIntervals(polylineData.color, interval); + } + if (typeof polylineData.width !== 'undefined') { var width = polyline.width; if (typeof width === 'undefined') { @@ -90,6 +109,24 @@ define([ width.processCzmlIntervals(polylineData.width, interval); } + if (typeof polylineData.outlineColor !== 'undefined') { + var outlineColor = polyline.outlineColor; + if (typeof outlineColor === 'undefined') { + polyline.outlineColor = outlineColor = new DynamicProperty(CzmlColor); + polylineUpdated = true; + } + outlineColor.processCzmlIntervals(polylineData.outlineColor, interval); + } + + if (typeof polylineData.outlineWidth !== 'undefined') { + var outlineWidth = polyline.outlineWidth; + if (typeof outlineWidth === 'undefined') { + polyline.outlineWidth = outlineWidth = new DynamicProperty(CzmlNumber); + polylineUpdated = true; + } + outlineWidth.processCzmlIntervals(polylineData.outlineWidth, interval); + } + if (typeof polylineData.show !== 'undefined') { var show = polyline.show; if (typeof show === 'undefined') { @@ -98,15 +135,6 @@ define([ } show.processCzmlIntervals(polylineData.show, interval); } - - if (typeof polylineData.material !== 'undefined') { - var material = polyline.material; - if (typeof material === 'undefined') { - polyline.material = material = new DynamicMaterialProperty(); - polylineUpdated = true; - } - material.processCzmlIntervals(polylineData.material, interval); - } return polylineUpdated; }; @@ -130,9 +158,11 @@ define([ targetObject.polyline = targetPolyline = new DynamicPolyline(); } + targetPolyline.color = defaultValue(targetPolyline.color, polylineToMerge.color); targetPolyline.width = defaultValue(targetPolyline.width, polylineToMerge.width); + targetPolyline.outlineColor = defaultValue(targetPolyline.outlineColor, polylineToMerge.outlineColor); + targetPolyline.outlineWidth = defaultValue(targetPolyline.outlineWidth, polylineToMerge.outlineWidth); targetPolyline.show = defaultValue(targetPolyline.show, polylineToMerge.show); - targetPolyline.material = defaultValue(targetPolyline.material, polylineToMerge.material); } }; diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index 0586aedf5a9a..b2482ba695a3 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -3,14 +3,16 @@ define([ '../Core/DeveloperError', '../Core/destroyObject', '../Core/Cartesian3', - '../Scene/PolylineCollection', - '../Scene/Material' + '../Core/Color', + '../Scene/Material', + '../Scene/PolylineCollection' ], function( DeveloperError, destroyObject, Cartesian3, - PolylineCollection, - Material) { + Color, + Material, + PolylineCollection) { "use strict"; /** @@ -195,7 +197,6 @@ define([ return; } - var context = this._scene.getContext(); if (typeof polylineVisualizerIndex === 'undefined') { var unusedIndexes = this._unusedIndexes; var length = unusedIndexes.length; @@ -210,8 +211,12 @@ define([ polyline.dynamicObject = dynamicObject; // CZML_TODO Determine official defaults - polyline.setMaterial(Material.fromType(context, Material.ColorType)); polyline.setWidth(1); + var material = polyline.getMaterial(); + if (typeof material === 'undefined' || (material.type !== Material.PolylineOutlineType)) { + material = Material.fromType(this._scene.getContext(), Material.PolylineOutlineType); + polyline.setMaterial(material); + } } else { polyline = this._polylineCollection.get(polylineVisualizerIndex); } @@ -230,18 +235,30 @@ define([ polyline._visualizerPositions = vertexPositions; } - var property = dynamicPolyline.width; + var uniforms = polyline.getMaterial().uniforms; + + var property = dynamicPolyline.color; + if (typeof property !== 'undefined') { + uniforms.color = property.getValue(time, uniforms.color); + } + + property = dynamicPolyline.outlineColor; + if (typeof property !== 'undefined') { + uniforms.outlineColor = property.getValue(time, uniforms.outlineColor); + } + + property = dynamicPolyline.outlineWidth; + if (typeof property !== 'undefined') { + uniforms.outlineWidth = property.getValue(time, uniforms.outlineWidth); + } + + property = dynamicPolyline.width; if (typeof property !== 'undefined') { var width = property.getValue(time); if (typeof width !== 'undefined') { polyline.setWidth(width); } } - - var material = dynamicPolyline.material; - if (typeof material !== 'undefined') { - polyline.setMaterial(material.getValue(time, context, polyline.getMaterial())); - } }; DynamicPolylineVisualizer.prototype._onObjectsRemoved = function(dynamicObjectCollection, dynamicObjects) { diff --git a/Specs/DynamicScene/DynamicPathSpec.js b/Specs/DynamicScene/DynamicPathSpec.js index aa4671cb9a51..6e0dc40c5a84 100644 --- a/Specs/DynamicScene/DynamicPathSpec.js +++ b/Specs/DynamicScene/DynamicPathSpec.js @@ -19,15 +19,15 @@ defineSuite([ it('processCzmlPacket adds data for infinite path.', function() { var pathPacket = { path : { - width : 1.0, - material : { - solidColor : { - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - } - } + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] }, + width : 1.0, resolution : 23.0, + outlineColor : { + rgbaf : [0.2, 0.2, 0.2, 0.2] + }, + outlineWidth : 1.0, leadTime : 2.0, trailTime : 3.0, show : true @@ -38,9 +38,11 @@ defineSuite([ expect(DynamicPath.processCzmlPacket(dynamicObject, pathPacket)).toEqual(true); expect(dynamicObject.path).toBeDefined(); + expect(dynamicObject.path.color.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.width.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.width); - expect(dynamicObject.path.material.getValue(Iso8601.MINIMUM_VALUE).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.resolution.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.resolution); + expect(dynamicObject.path.outlineColor.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); + expect(dynamicObject.path.outlineWidth.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.outlineWidth); expect(dynamicObject.path.leadTime.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.leadTime); expect(dynamicObject.path.trailTime.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pathPacket.path.trailTime); expect(dynamicObject.path.show.getValue(Iso8601.MINIMUM_VALUE)).toEqual(true); @@ -50,15 +52,15 @@ defineSuite([ var pathPacket = { path : { interval : '2000-01-01/2001-01-01', - width : 1.0, - material : { - solidColor : { - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - } - } + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] }, + width : 1.0, resolution : 23.0, + outlineColor : { + rgbaf : [0.2, 0.2, 0.2, 0.2] + }, + outlineWidth : 1.0, leadTime : 2.0, trailTime : 3.0, show : true @@ -72,15 +74,19 @@ defineSuite([ expect(DynamicPath.processCzmlPacket(dynamicObject, pathPacket)).toEqual(true); expect(dynamicObject.path).toBeDefined(); + expect(dynamicObject.path.color.getValue(validTime)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.width.getValue(validTime)).toEqual(pathPacket.path.width); - expect(dynamicObject.path.material.getValue(validTime).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.path.resolution.getValue(validTime)).toEqual(pathPacket.path.resolution); + expect(dynamicObject.path.outlineColor.getValue(validTime)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); + expect(dynamicObject.path.outlineWidth.getValue(validTime)).toEqual(pathPacket.path.outlineWidth); expect(dynamicObject.path.leadTime.getValue(validTime)).toEqual(pathPacket.path.leadTime); expect(dynamicObject.path.trailTime.getValue(validTime)).toEqual(pathPacket.path.trailTime); expect(dynamicObject.path.show.getValue(validTime)).toEqual(true); + expect(dynamicObject.path.color.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.width.getValue(invalidTime)).toBeUndefined(); - expect(dynamicObject.path.material.getValue(invalidTime)).toBeUndefined(); + expect(dynamicObject.path.outlineColor.getValue(invalidTime)).toBeUndefined(); + expect(dynamicObject.path.outlineWidth.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.leadTime.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.trailTime.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.path.show.getValue(invalidTime)).toBeUndefined(); @@ -96,51 +102,60 @@ defineSuite([ it('mergeProperties does not change a fully configured path', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.path = new DynamicPath(); - objectToMerge.path.width = 1; - objectToMerge.path.material = 2; - objectToMerge.path.show = 3; - objectToMerge.path.leadTime = 4; - objectToMerge.path.trailTime = 5; - objectToMerge.path.resolution = 6; + objectToMerge.path.color = 1; + objectToMerge.path.width = 2; + objectToMerge.path.outlineColor = 3; + objectToMerge.path.outlineWidth = 4; + objectToMerge.path.show = 5; + objectToMerge.path.leadTime = 6; + objectToMerge.path.trailTime = 7; + objectToMerge.path.resolution = 8; var targetObject = new DynamicObject('targetObject'); targetObject.path = new DynamicPath(); - targetObject.path.width = 7; - targetObject.path.material = 8; - targetObject.path.show = 9; - targetObject.path.leadTime = 10; - targetObject.path.trailTime = 11; - targetObject.path.resolution = 12; + targetObject.path.color = 9; + targetObject.path.width = 10; + targetObject.path.outlineColor = 11; + targetObject.path.outlineWidth = 12; + targetObject.path.show = 13; + targetObject.path.leadTime = 14; + targetObject.path.trailTime = 15; + targetObject.path.resolution = 16; DynamicPath.mergeProperties(targetObject, objectToMerge); - expect(targetObject.path.width).toEqual(7); - expect(targetObject.path.material).toEqual(8); - expect(targetObject.path.show).toEqual(9); - expect(targetObject.path.leadTime).toEqual(10); - expect(targetObject.path.trailTime).toEqual(11); - expect(targetObject.path.resolution).toEqual(12); + expect(targetObject.path.color).toEqual(9); + expect(targetObject.path.width).toEqual(10); + expect(targetObject.path.outlineColor).toEqual(11); + expect(targetObject.path.outlineWidth).toEqual(12); + expect(targetObject.path.show).toEqual(13); + expect(targetObject.path.leadTime).toEqual(14); + expect(targetObject.path.trailTime).toEqual(15); + expect(targetObject.path.resolution).toEqual(16); }); it('mergeProperties creates and configures an undefined path', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.path = new DynamicPath(); - objectToMerge.path.width = 1; - objectToMerge.path.material = 2; - objectToMerge.path.show = 3; - objectToMerge.path.leadTime = 4; - objectToMerge.path.trailTime = 5; - objectToMerge.path.resolution = 6; + objectToMerge.path.color = 1; + objectToMerge.path.width = 2; + objectToMerge.path.outlineColor = 3; + objectToMerge.path.outlineWidth = 4; + objectToMerge.path.show = 5; + objectToMerge.path.leadTime = 6; + objectToMerge.path.trailTime = 7; + objectToMerge.path.resolution = 8; var targetObject = new DynamicObject('targetObject'); DynamicPath.mergeProperties(targetObject, objectToMerge); + expect(targetObject.path.color).toEqual(objectToMerge.path.color); expect(targetObject.path.width).toEqual(objectToMerge.path.width); - expect(targetObject.path.material).toEqual(objectToMerge.path.material); + expect(targetObject.path.outlineColor).toEqual(objectToMerge.path.outlineColor); + expect(targetObject.path.outlineWidth).toEqual(objectToMerge.path.outlineWidth); expect(targetObject.path.show).toEqual(objectToMerge.path.show); expect(targetObject.path.leadTime).toEqual(objectToMerge.path.leadTime); expect(targetObject.path.trailTime).toEqual(objectToMerge.path.trailTime); - expect(targetObject.path.resolution).toEqual(objectToMerge.path.resolution); }); it('mergeProperties does not change when used with an undefined path', function() { @@ -148,20 +163,25 @@ defineSuite([ var targetObject = new DynamicObject('targetObject'); targetObject.path = new DynamicPath(); - targetObject.path.width = 1; - targetObject.path.material = 2; - targetObject.path.show = 3; - targetObject.path.leadTime = 4; - targetObject.path.trailTime = 5; - targetObject.path.resolution = 6; + targetObject.path = new DynamicPath(); + targetObject.path.color = 1; + targetObject.path.width = 2; + targetObject.path.outlineColor = 3; + targetObject.path.outlineWidth = 4; + targetObject.path.show = 5; + targetObject.path.leadTime = 6; + targetObject.path.trailTime = 7; + targetObject.path.resolution = 8; DynamicPath.mergeProperties(targetObject, objectToMerge); - expect(targetObject.path.width).toEqual(1); - expect(targetObject.path.material).toEqual(2); - expect(targetObject.path.show).toEqual(3); - expect(targetObject.path.leadTime).toEqual(4); - expect(targetObject.path.trailTime).toEqual(5); - expect(targetObject.path.resolution).toEqual(6); + expect(targetObject.path.color).toEqual(1); + expect(targetObject.path.width).toEqual(2); + expect(targetObject.path.outlineColor).toEqual(3); + expect(targetObject.path.outlineWidth).toEqual(4); + expect(targetObject.path.show).toEqual(5); + expect(targetObject.path.leadTime).toEqual(6); + expect(targetObject.path.trailTime).toEqual(7); + expect(targetObject.path.resolution).toEqual(8); }); it('undefineProperties works', function() { diff --git a/Specs/DynamicScene/DynamicPathVisualizerSpec.js b/Specs/DynamicScene/DynamicPathVisualizerSpec.js index e390a146f4b5..b6fa543ad42f 100644 --- a/Specs/DynamicScene/DynamicPathVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPathVisualizerSpec.js @@ -11,8 +11,7 @@ defineSuite([ 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Color', - 'Scene/Scene', - 'Scene/Material' + 'Scene/Scene' ], function( DynamicPathVisualizer, createScene, @@ -25,8 +24,7 @@ defineSuite([ Cartesian2, Cartesian3, Color, - Scene, - Material) { + Scene) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ @@ -115,12 +113,12 @@ defineSuite([ var path = testObject.path = new DynamicPath(); path.show = new MockProperty(true); + path.color = new MockProperty(new Color(0.8, 0.7, 0.6, 0.5)); path.width = new MockProperty(12.5); + path.outlineColor = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); + path.outlineWidth = new MockProperty(2.5); path.leadTime = new MockProperty(25); path.trailTime = new MockProperty(10); - var colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); - colorMaterial.uniforms.color = new Color(0.7, 0.6, 0.5, 0.4); - path.material = new MockProperty(colorMaterial); visualizer.update(time); @@ -133,19 +131,26 @@ defineSuite([ expect(primitive.getShow()).toEqual(testObject.path.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); - expect(primitive.getMaterial()).toEqual(testObject.path.material.getValue(time)); + + var material = primitive.getMaterial(); + expect(material.uniforms.color).toEqual(testObject.path.color.getValue(time)); + expect(material.uniforms.outlineColor).toEqual(testObject.path.outlineColor.getValue(time)); + expect(material.uniforms.outlineWidth).toEqual(testObject.path.outlineWidth.getValue(time)); testObject.position = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); + path.color = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); path.width = new MockProperty(2.5); - colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); - colorMaterial.uniforms.color = new Color(0.1, 0.2, 0.4, 0.3); - path.material = new MockProperty(colorMaterial); + path.outlineColor = new MockProperty(new Color(0.5, 0.6, 0.7, 0.8)); + path.outlineWidth = new MockProperty(12.5); visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.path.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.position.getValueRangeCartesian(time)); expect(primitive.getWidth()).toEqual(testObject.path.width.getValue(time)); - expect(primitive.getMaterial()).toEqual(testObject.path.material.getValue(time)); + + expect(material.uniforms.color).toEqual(testObject.path.color.getValue(time)); + expect(material.uniforms.outlineColor).toEqual(testObject.path.outlineColor.getValue(time)); + expect(material.uniforms.outlineWidth).toEqual(testObject.path.outlineWidth.getValue(time)); path.show = new MockProperty(false); visualizer.update(time); diff --git a/Specs/DynamicScene/DynamicPolylineSpec.js b/Specs/DynamicScene/DynamicPolylineSpec.js index 7fa08b907fe6..edc604901a64 100644 --- a/Specs/DynamicScene/DynamicPolylineSpec.js +++ b/Specs/DynamicScene/DynamicPolylineSpec.js @@ -19,14 +19,14 @@ defineSuite([ it('processCzmlPacket adds data for infinite polyline.', function() { var polylinePacket = { polyline : { + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] + }, width : 1.0, - material : { - solidColor : { - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - } - } + outlineColor : { + rgbaf : [0.2, 0.2, 0.2, 0.2] }, + outlineWidth : 1.0, show : true } }; @@ -35,8 +35,10 @@ defineSuite([ expect(DynamicPolyline.processCzmlPacket(dynamicObject, polylinePacket)).toEqual(true); expect(dynamicObject.polyline).toBeDefined(); + expect(dynamicObject.polyline.color.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.polyline.width.getValue(Iso8601.MINIMUM_VALUE)).toEqual(polylinePacket.polyline.width); - expect(dynamicObject.polyline.material.getValue(Iso8601.MINIMUM_VALUE).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); + expect(dynamicObject.polyline.outlineColor.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); + expect(dynamicObject.polyline.outlineWidth.getValue(Iso8601.MINIMUM_VALUE)).toEqual(polylinePacket.polyline.outlineWidth); expect(dynamicObject.polyline.show.getValue(Iso8601.MINIMUM_VALUE)).toEqual(true); }); @@ -44,14 +46,14 @@ defineSuite([ var polylinePacket = { polyline : { interval : '2000-01-01/2001-01-01', + color : { + rgbaf : [0.1, 0.1, 0.1, 0.1] + }, width : 1.0, - material : { - solidColor : { - color : { - rgbaf : [0.1, 0.1, 0.1, 0.1] - } - } + outlineColor : { + rgbaf : [0.2, 0.2, 0.2, 0.2] }, + outlineWidth : 1.0, show : true } }; @@ -63,12 +65,16 @@ defineSuite([ expect(DynamicPolyline.processCzmlPacket(dynamicObject, polylinePacket)).toEqual(true); expect(dynamicObject.polyline).toBeDefined(); + expect(dynamicObject.polyline.color.getValue(validTime)).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(dynamicObject.polyline.width.getValue(validTime)).toEqual(polylinePacket.polyline.width); - expect(dynamicObject.polyline.material.getValue(validTime).uniforms.color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); + expect(dynamicObject.polyline.outlineColor.getValue(validTime)).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); + expect(dynamicObject.polyline.outlineWidth.getValue(validTime)).toEqual(polylinePacket.polyline.outlineWidth); expect(dynamicObject.polyline.show.getValue(validTime)).toEqual(true); + expect(dynamicObject.polyline.color.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.polyline.width.getValue(invalidTime)).toBeUndefined(); - expect(dynamicObject.polyline.material.getValue(invalidTime)).toBeUndefined(); + expect(dynamicObject.polyline.outlineColor.getValue(invalidTime)).toBeUndefined(); + expect(dynamicObject.polyline.outlineWidth.getValue(invalidTime)).toBeUndefined(); expect(dynamicObject.polyline.show.getValue(invalidTime)).toBeUndefined(); }); @@ -82,29 +88,37 @@ defineSuite([ it('mergeProperties does not change a fully configured polyline', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.polyline = new DynamicPolyline(); - objectToMerge.polyline.width = 1; - objectToMerge.polyline.material = 2; - objectToMerge.polyline.show = 3; + objectToMerge.polyline.color = 1; + objectToMerge.polyline.width = 2; + objectToMerge.polyline.outlineColor = 3; + objectToMerge.polyline.outlineWidth = 4; + objectToMerge.polyline.show = 5; var targetObject = new DynamicObject('targetObject'); targetObject.polyline = new DynamicPolyline(); - targetObject.polyline.width = 4; - targetObject.polyline.material = 5; - targetObject.polyline.show = 6; + targetObject.polyline.color = 6; + targetObject.polyline.width = 7; + targetObject.polyline.outlineColor = 8; + targetObject.polyline.outlineWidth = 9; + targetObject.polyline.show = 10; DynamicPolyline.mergeProperties(targetObject, objectToMerge); - expect(targetObject.polyline.width).toEqual(4); - expect(targetObject.polyline.material).toEqual(5); - expect(targetObject.polyline.show).toEqual(6); + expect(targetObject.polyline.color).toEqual(6); + expect(targetObject.polyline.width).toEqual(7); + expect(targetObject.polyline.outlineColor).toEqual(8); + expect(targetObject.polyline.outlineWidth).toEqual(9); + expect(targetObject.polyline.show).toEqual(10); }); it('mergeProperties creates and configures an undefined polyline', function() { var objectToMerge = new DynamicObject('objectToMerge'); objectToMerge.polyline = new DynamicPolyline(); - objectToMerge.polyline.width = 1; - objectToMerge.polyline.material = 2; - objectToMerge.polyline.show = 3; + objectToMerge.polyline.color = 1; + objectToMerge.polyline.width = 2; + objectToMerge.polyline.outlineColor = 3; + objectToMerge.polyline.outlineWidth = 4; + objectToMerge.polyline.show = 5; var targetObject = new DynamicObject('targetObject'); @@ -122,15 +136,19 @@ defineSuite([ var targetObject = new DynamicObject('targetObject'); targetObject.polyline = new DynamicPolyline(); - targetObject.polyline.width = 4; - targetObject.polyline.material = 5; - targetObject.polyline.show = 6; + targetObject.polyline.color = 6; + targetObject.polyline.width = 7; + targetObject.polyline.outlineColor = 8; + targetObject.polyline.outlineWidth = 9; + targetObject.polyline.show = 10; DynamicPolyline.mergeProperties(targetObject, objectToMerge); - expect(targetObject.polyline.width).toEqual(4); - expect(targetObject.polyline.material).toEqual(5); - expect(targetObject.polyline.show).toEqual(6); + expect(targetObject.polyline.color).toEqual(6); + expect(targetObject.polyline.width).toEqual(7); + expect(targetObject.polyline.outlineColor).toEqual(8); + expect(targetObject.polyline.outlineWidth).toEqual(9); + expect(targetObject.polyline.show).toEqual(10); }); it('undefineProperties works', function() { diff --git a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js index a9a6a2de8c76..bbc37a717174 100644 --- a/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js +++ b/Specs/DynamicScene/DynamicPolylineVisualizerSpec.js @@ -12,8 +12,7 @@ defineSuite([ 'Core/Cartesian2', 'Core/Cartesian3', 'Core/Color', - 'Scene/Scene', - 'Scene/Material' + 'Scene/Scene' ], function( DynamicPolylineVisualizer, createScene, @@ -27,8 +26,7 @@ defineSuite([ Cartesian2, Cartesian3, Color, - Scene, - Material) { + Scene) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ @@ -187,10 +185,10 @@ defineSuite([ var polyline = testObject.polyline = new DynamicPolyline(); polyline.show = new MockProperty(true); + polyline.color = new MockProperty(new Color(0.8, 0.7, 0.6, 0.5)); polyline.width = new MockProperty(12.5); - var colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); - colorMaterial.uniforms.color = new Color(0.7, 0.6, 0.5, 0.4); - polyline.material = new MockProperty(colorMaterial); + polyline.outlineColor = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); + polyline.outlineWidth = new MockProperty(2.5); visualizer.update(time); @@ -202,19 +200,27 @@ defineSuite([ expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); - expect(primitive.getMaterial()).toEqual(testObject.polyline.material.getValue(time)); + + var material = primitive.getMaterial(); + expect(material.uniforms.color).toEqual(testObject.polyline.color.getValue(time)); + expect(material.uniforms.outlineColor).toEqual(testObject.polyline.outlineColor.getValue(time)); + expect(material.uniforms.outlineWidth).toEqual(testObject.polyline.outlineWidth.getValue(time)); testObject.vertexPositions = new MockProperty([new Cartesian3(5678, 1234, 1101112), new Cartesian3(1234, 5678, 9101112)]); + polyline.color = new MockProperty(new Color(0.1, 0.2, 0.3, 0.4)); polyline.width = new MockProperty(2.5); - colorMaterial = Material.fromType(scene.getContext(), Material.ColorType); - colorMaterial.uniforms.color = new Color(0.1, 0.2, 0.4, 0.3); - polyline.material = new MockProperty(colorMaterial); + polyline.outlineColor = new MockProperty(new Color(0.5, 0.6, 0.7, 0.8)); + polyline.outlineWidth = new MockProperty(12.5); visualizer.update(time); expect(primitive.getShow()).toEqual(testObject.polyline.show.getValue(time)); expect(primitive.getPositions()).toEqual(testObject.vertexPositions.getValueCartesian(time)); expect(primitive.getWidth()).toEqual(testObject.polyline.width.getValue(time)); - expect(primitive.getMaterial()).toEqual(testObject.polyline.material.getValue(time)); + + material = primitive.getMaterial(); + expect(material.uniforms.color).toEqual(testObject.polyline.color.getValue(time)); + expect(material.uniforms.outlineColor).toEqual(testObject.polyline.outlineColor.getValue(time)); + expect(material.uniforms.outlineWidth).toEqual(testObject.polyline.outlineWidth.getValue(time)); polyline.show = new MockProperty(false); visualizer.update(time); From a6f5e61c4ab819e175e07800d27fe0864a413e29 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Mar 2013 14:38:55 -0400 Subject: [PATCH 073/114] Rename czm_pixelSize to czm_pixelSizeInMeters. Update CHANGES.md. --- CHANGES.md | 25 ++++++++++++++++++++++++- Source/Renderer/ShaderProgram.js | 10 +++++----- Source/Renderer/UniformState.js | 2 +- Source/Shaders/PolylineVS.glsl | 2 +- Specs/Renderer/AutomaticUniformSpec.js | 4 ++-- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index aa7a258c2418..2360867c212f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,29 @@ Beta Releases * Removed `clampToPixel` property from `BillboardCollection` and `LabelCollection`. This options is no longer be needed due to overall LabelCollection visualization improvements. * Removed `Widgets/Dojo/CesiumWidget` and replaced it with `Widgets/CesiumWidget`, which has no Dojo dependancies. * `destroyObject` no longer deletes properties from the object being destroyed. - * Removed the color, outline color, and outline width properties of polylines. Instead, use materials for polyline color and outline properties. + * Removed the color, outline color, and outline width properties of polylines. Instead, use materials for polyline color and outline properties. Code that looked like: + + var polyline = polylineCollection.add({ + positions : positions, + color : new Color(1.0, 1.0, 1.0, 1.0), + outlineColor : new Color(1.0, 0.0, 0.0, 1.0), + width : 1.0, + outlineWidth : 3.0 + }); + + should now look like: + + var outlineMaterial = Material.fromType(context, Material.PolylineOutlineType); + outlineMaterial.uniforms.color = new Color(1.0, 1.0, 1.0, 1.0); + outlineMaterial.uniforms.outlineColor = new Color(1.0, 0.0, 0.0, 1.0); + outlineMaterial.uniforms.outlinewidth = 2.0; + + var polyline = polylineCollection.add({ + positions : positions, + width : 3.0, + material : outlineMaterial + }); + * Added `BoundingSphere.fromCornerPoints`. * Added `fromArray` and `distance` functions to `Cartesian2`, `Cartesian3`, and `Cartesian4`. * Added `DynamicPath.resolution` property for setting the maximum step size, in seconds, to take when sampling a position for path visualization. @@ -20,6 +42,7 @@ Beta Releases * Added wide polylines that work with and without ANGLE. * Polylines now use materials to describe their surface appearance. See the [Fabric](https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric) wiki page for more details on how to create materials. * Added new `PolylineOutline`, `PolylineArrow`, and `Fade` materials. +* Added `czm_pixelSizeInMeters` automatic GLSL uniform. * Added `sampleTerrain` function to sample the terrain height of a list of `Cartographic` positions. * Imagery layers with an `alpha` of exactly 0.0 are no longer rendered. Previously these invisible layers were rendered normally, which was a waste of resources. Unlike the `show` property, imagery tiles in a layer with an `alpha` of 0.0 are still downloaded, so the layer will become visible more quickly when its `alpha` is increased. diff --git a/Source/Renderer/ShaderProgram.js b/Source/Renderer/ShaderProgram.js index c2d2ef262043..69564549b082 100644 --- a/Source/Renderer/ShaderProgram.js +++ b/Source/Renderer/ShaderProgram.js @@ -1227,21 +1227,21 @@ define([ * An automatic GLSL uniform representing the size of a pixel in meters at a distance of one meter * from the camera. The pixel size is linearly proportional to the distance from the camera. *

- * Like all automatic uniforms, czm_pixelSize does not need to be explicitly declared. + * Like all automatic uniforms, czm_pixelSizeInMeters does not need to be explicitly declared. * However, it can be explicitly declared when a shader is also used by other applications such * as a third-party authoring tool. * - * @alias czm_pixelSize + * @alias czm_pixelSizeInMeters * @glslUniform * * @example * // GLSL declaration - * uniform float czm_pixelSize; + * uniform float czm_pixelSizeInMeters; * * // Example: the pixel size at a position in eye coordinates - * float pixelSize = czm_pixelSize * positionEC.z; + * float pixelSize = czm_pixelSizeInMeters * positionEC.z; */ - czm_pixelSize : { + czm_pixelSizeInMeters : { getSize : function() { return 1; }, diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index ebbecf7bff7d..6b1b63d0ee23 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -895,7 +895,7 @@ define([ * * @return {Number} Returns the size of a pixel in meters at a distance of one meter from the camera. * - * @see czm_pixelSize + * @see czm_pixelSizeInMeters */ UniformState.prototype.getPixelSize = function() { return this._pixelSize; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index d829f237cce2..5e8db20c4294 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -62,7 +62,7 @@ void main() vec4 positionEC = czm_modelViewRelativeToEye * p; vec4 endPointWC = czm_eyeToWindowCoordinates(positionEC); - float pixelSize = czm_pixelSize * abs(positionEC.z); + float pixelSize = czm_pixelSizeInMeters * abs(positionEC.z); float expandWidth = width * 0.5; vec4 prevEC, nextEC, p0, p1; vec2 direction, nextWC, prevWC; diff --git a/Specs/Renderer/AutomaticUniformSpec.js b/Specs/Renderer/AutomaticUniformSpec.js index 806f2f036abf..8428dea3075c 100644 --- a/Specs/Renderer/AutomaticUniformSpec.js +++ b/Specs/Renderer/AutomaticUniformSpec.js @@ -686,11 +686,11 @@ defineSuite([ verifyDraw(fs); }); - it('has czm_pixelSize', function() { + it('has czm_pixelSizeInMeters', function() { var us = context.getUniformState(); us.update(createFrameState(createMockCamera())); - var fs = 'void main() { gl_FragColor = vec4(czm_pixelSize == 1.0); }'; + var fs = 'void main() { gl_FragColor = vec4(czm_pixelSizeInMeters == 1.0); }'; verifyDraw(fs); }); From 493f755e0094f4df0934a18df682cc95561ffc00 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Mar 2013 15:18:21 -0400 Subject: [PATCH 074/114] Update Material doc and tests. --- Source/Scene/Material.js | 21 +++++++++++++- Specs/Scene/MaterialSpec.js | 55 +++++++++++++++++++++++++++++++++++-- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index e1c4c4b0c620..af66da249278 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -269,6 +269,25 @@ define([ *
  • color: diffuse color and alpha.
  • *
  • time: Time of erosion. 1.0 is no erosion; 0.0 is fully eroded.
  • * + *
  • Fade
  • + *
      + *
    • fadeInColor: diffuse color and alpha at time
    • + *
    • fadeOutColor: diffuse color and alpha at maxDistance from time
    • + *
    • maxDistance: Number between 0.0 and 1.0 where the fadeInColor becomes the fadeOutColor. A value of 0.0 gives the entire material a color of fadeOutColor and a value of 1.0 gives the the entire material a color of fadeInColor
    • + *
    • repeat: true if the fade should wrap around the texture coodinates.
    • + *
    • fadeDirection: Object with x and y values specifying if the fade should be in the x and y directions.
    • + *
    • time: Object with x and y values between 0.0 and 1.0 of the fadeInColor position
    • + *
    + *
  • PolylineArrow
  • + *
      + *
    • color: diffuse color and alpha.
    • + *
    + *
  • PolylineOutline
  • + *
      + *
    • color: diffuse color and alpha for the interior of the line.
    • + *
    • outlineColor: diffuse color and alpha for the outline.
    • + *
    • outlineWidth: width of the outline in pixels.
    • + *
    * * * @@ -1197,7 +1216,7 @@ define([ x : true, y : true }, - time : Cartesian2.ZERO.clone() + time : new Cartesian2(0.5, 0.5) }, source : FadeMaterial }); diff --git a/Specs/Scene/MaterialSpec.js b/Specs/Scene/MaterialSpec.js index 3cf77f565ae2..e08c6700a6b0 100644 --- a/Specs/Scene/MaterialSpec.js +++ b/Specs/Scene/MaterialSpec.js @@ -2,6 +2,7 @@ defineSuite([ 'Scene/Material', 'Scene/Polygon', + 'Scene/PolylineCollection', 'Specs/createContext', 'Specs/destroyContext', 'Specs/createCamera', @@ -18,6 +19,7 @@ defineSuite([ ], function( Material, Polygon, + PolylineCollection, createContext, destroyContext, createCamera, @@ -36,6 +38,8 @@ defineSuite([ var context; var polygon; + var polylines; + var polyline; var us; beforeAll(function() { @@ -60,14 +64,24 @@ defineSuite([ ellipsoid.cartographicToCartesian(Cartographic.fromDegrees(50.0, 50.0, 0.0)), ellipsoid.cartographicToCartesian(Cartographic.fromDegrees(-50.0, 50.0, 0.0)) ]); + + polylines = new PolylineCollection(); + polyline = polylines.add({ + positions : [ + ellipsoid.cartographicToCartesian(Cartographic.fromDegrees(-50.0, 0.0, 0.0)), + ellipsoid.cartographicToCartesian(Cartographic.fromDegrees( 50.0, 0.0, 0.0)) + ], + width : 5.0 + }); }); afterEach(function() { polygon = polygon && polygon.destroy(); + polylines = polylines && polylines.destroy(); us = undefined; }); - var renderMaterial = function(material) { + function renderMaterial(material) { polygon.material = material; context.clear(); @@ -75,7 +89,17 @@ defineSuite([ render(context, frameState, polygon); return context.readPixels(); - }; + } + + function renderPolylineMaterial(material) { + polyline.setMaterial(material); + + context.clear(); + expect(context.readPixels()).toEqual([0, 0, 0, 0]); + + render(context, frameState, polylines); + return context.readPixels(); + } function verifyMaterial(type) { var material = new Material({ @@ -85,7 +109,19 @@ defineSuite([ type : type } }); - var pixel = renderMaterial(material, context); + var pixel = renderMaterial(material); + expect(pixel).not.toEqual([0, 0, 0, 0]); + } + + function verifyPolylineMaterial(type) { + var material = new Material({ + context : context, + strict : true, + fabric : { + type : type + } + }); + var pixel = renderPolylineMaterial(material); expect(pixel).not.toEqual([0, 0, 0, 0]); } @@ -189,6 +225,18 @@ defineSuite([ verifyMaterial('Erosion'); }); + it('draws Fade built-in material', function() { + verifyMaterial('Fade'); + }); + + it('draws PolylineArrow built-in material', function() { + verifyPolylineMaterial('PolylineArrow'); + }); + + it('draws PolylineOutline built-in material', function() { + verifyPolylineMaterial('PolylineOutline'); + }); + it('gets the material type', function() { var material = new Material({ context : context, @@ -326,6 +374,7 @@ defineSuite([ var pixel = renderMaterial(material); expect(pixel).not.toEqual([0, 0, 0, 0]); }); + it('creates a material with a boolean uniform', function () { var material = new Material({ context : context, From 9bb855ee493fc520e9e8b86e78bd2fd426afc877 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Mar 2013 15:27:01 -0400 Subject: [PATCH 075/114] Remove Polyline equals method. Change default outline width. --- Source/Scene/Material.js | 2 +- Source/Scene/Polyline.js | 31 ------------------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index af66da249278..1985e1f6e803 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -1236,7 +1236,7 @@ define([ uniforms : { color : new Color(1.0, 1.0, 1.0, 1.0), outlineColor : new Color(1.0, 0.0, 0.0, 1.0), - outlineWidth : 0.0 + outlineWidth : 1.0 }, source : PolylineOutlineMaterial }); diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index cc2e0e7e89c4..6280cdf7d73b 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -278,37 +278,6 @@ define([ } }; - - /** - * Determines if this polyline equals another polyline. Polylines are equal if all their properties - * are equal. Polylines in different collections can be equal. - * - * @memberof Polyline - * - * @param {Polyline} other The polyline to compare for equality. - * - * @return {Boolean} true if the polylines are equal; otherwise, false. - */ - Polyline.prototype.equals = function(other) { - return this === other || - typeof other !== 'undefined' && - this._show === other._show && - this._width === other._width && - cartesian3ArrayEquals(this._positions, other._positions); - }; - - function cartesian3ArrayEquals(a, b) { - if (a.length !== b.length) { - return false; - } - for ( var i = 0, len = a.length; i < len; ++i) { - if (!Cartesian3.equals(a[i], b[i])) { - return false; - } - } - return true; - } - Polyline.prototype._destroy = function() { this._pickId = this._pickId && this._pickId.destroy(); this._material = this._material && this._material.destroy(); From debe70ac1b80c67e4b3b1dc9456f5ce2a0c6d3a8 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Mar 2013 15:41:11 -0400 Subject: [PATCH 076/114] Rename maxDistance uniform of the Fade material to maximumDistance. --- Source/Scene/Material.js | 6 +++--- Source/Shaders/Materials/FadeMaterial.glsl | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Material.js b/Source/Scene/Material.js index 1985e1f6e803..6b7c745e923b 100644 --- a/Source/Scene/Material.js +++ b/Source/Scene/Material.js @@ -272,8 +272,8 @@ define([ *
  • Fade
  • *
      *
    • fadeInColor: diffuse color and alpha at time
    • - *
    • fadeOutColor: diffuse color and alpha at maxDistance from time
    • - *
    • maxDistance: Number between 0.0 and 1.0 where the fadeInColor becomes the fadeOutColor. A value of 0.0 gives the entire material a color of fadeOutColor and a value of 1.0 gives the the entire material a color of fadeInColor
    • + *
    • fadeOutColor: diffuse color and alpha at maximumDistance from time
    • + *
    • maximumDistance: Number between 0.0 and 1.0 where the fadeInColor becomes the fadeOutColor. A value of 0.0 gives the entire material a color of fadeOutColor and a value of 1.0 gives the the entire material a color of fadeInColor
    • *
    • repeat: true if the fade should wrap around the texture coodinates.
    • *
    • fadeDirection: Object with x and y values specifying if the fade should be in the x and y directions.
    • *
    • time: Object with x and y values between 0.0 and 1.0 of the fadeInColor position
    • @@ -1210,7 +1210,7 @@ define([ uniforms : { fadeInColor : new Color(1.0, 0.0, 0.0, 1.0), fadeOutColor : new Color(0.0, 0.0, 0.0, 0.0), - maxDistance : 0.5, + maximumDistance : 0.5, repeat : true, fadeDirection : { x : true, diff --git a/Source/Shaders/Materials/FadeMaterial.glsl b/Source/Shaders/Materials/FadeMaterial.glsl index 711cda805304..d2283cd40c59 100644 --- a/Source/Shaders/Materials/FadeMaterial.glsl +++ b/Source/Shaders/Materials/FadeMaterial.glsl @@ -1,13 +1,13 @@ uniform vec4 fadeInColor; uniform vec4 fadeOutColor; -uniform float maxDistance; +uniform float maximumDistance; uniform bool repeat; uniform vec2 fadeDirection; uniform vec2 time; float getTime(float t, float coord) { - float scalar = 1.0 / maxDistance; + float scalar = 1.0 / maximumDistance; float q = distance(t, coord) * scalar; if (repeat) { From d7b7583d6b7530b5c64e7b8d70417c817d093eab Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 21 Mar 2013 16:02:50 -0400 Subject: [PATCH 077/114] Rename everything that was associated the 'misc' vertex attribute to use more descriptive names. --- Source/Scene/Polyline.js | 15 +++--- Source/Scene/PolylineCollection.js | 82 ++++++++++++++++-------------- Source/Shaders/PolylineVS.glsl | 10 ++-- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 6280cdf7d73b..8bde295f03e0 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -67,11 +67,12 @@ define([ this._boundingVolume2D = new BoundingSphere(); // modified in PolylineCollection }; - var MISC_INDEX = Polyline.MISC_INDEX = 0; - var POSITION_INDEX = Polyline.POSITION_INDEX = 1; - var MATERIAL_INDEX = Polyline.MATERIAL_INDEX = 2; - var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 3; - var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 4; + var SHOW_INDEX = Polyline.SHOW_INDEX = 0; + var WIDTH_INDEX = Polyline.WIDTH_INDEX = 1; + var POSITION_INDEX = Polyline.POSITION_INDEX = 2; + var MATERIAL_INDEX = Polyline.MATERIAL_INDEX = 3; + var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 4; + var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES = 5; function makeDirty(polyline, propertyChanged) { ++polyline._propertiesChanged[propertyChanged]; @@ -115,7 +116,7 @@ define([ if (value !== this._show) { this._show = value; - makeDirty(this, MISC_INDEX); + makeDirty(this, SHOW_INDEX); } }; @@ -261,7 +262,7 @@ define([ var width = this._width; if (value !== width) { this._width = value; - makeDirty(this, MISC_INDEX); + makeDirty(this, WIDTH_INDEX); } }; diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 16d093184cd5..e99feaadda69 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -49,7 +49,8 @@ define([ PolylineFSPick) { "use strict"; - var MISC_INDEX = Polyline.MISC_INDEX; + var SHOW_INDEX = Polyline.SHOW_INDEX; + var WIDTH_INDEX = Polyline.WIDTH_INDEX; var POSITION_INDEX = Polyline.POSITION_INDEX; var MATERIAL_INDEX = Polyline.MATERIAL_INDEX; //POSITION_SIZE_INDEX is needed for when the polyline's position array changes size. @@ -65,7 +66,7 @@ define([ position2DLow : 3, prev : 4, next : 5, - misc : 6, + texCoordExpandWidthAndShow : 6, pickColor : 7 }; @@ -154,9 +155,9 @@ define([ // The buffer usage for each attribute is determined based on the usage of the attribute over time. this._buffersUsage = [ - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // MISC_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // POSITION_INDEX - {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0} // MATERIAL_INDEX + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // SHOW_INDEX + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0}, // WIDTH_INDEX + {bufferUsage: BufferUsage.STATIC_DRAW, frameCount:0} // POSITION_INDEX ]; this._mode = undefined; @@ -173,7 +174,7 @@ define([ this._positionBuffer = undefined; this._adjacencyBuffer = undefined; this._pickColorBuffer = undefined; - this._miscBuffer = undefined; + this._texCoordExpandWidthAndShowBuffer = undefined; }; /** @@ -411,8 +412,8 @@ define([ if (properties[POSITION_INDEX]) { bucket.writePositionsUpdate(index, polyline, this._positionBuffer, this._adjacencyBuffer); } - if (properties[MISC_INDEX]) { - bucket.writeMiscUpdate(index, polyline, this._miscBuffer); + if (properties[SHOW_INDEX] || properties[WIDTH_INDEX]) { + bucket.writeTexCoordExpandWidthAndShowUpdate(index, polyline, this._texCoordExpandWidthAndShowBuffer); } break; } @@ -607,8 +608,8 @@ define([ var usageChanged = false; var properties = collection._propertiesChanged; - //subtract 1 from NUMBER_OF_PROPERTIES because we don't care about POSITION_SIZE_INDEX property change. - for ( var k = 0; k < NUMBER_OF_PROPERTIES - 1; ++k) { + //subtract 2 from NUMBER_OF_PROPERTIES because we don't care about POSITION_SIZE_INDEX or MATERIAL_INDEX property change. + for ( var k = 0; k < NUMBER_OF_PROPERTIES - 2; ++k) { var bufferUsage = buffersUsage[k]; if (properties[k]) { if (bufferUsage.bufferUsage !== BufferUsage.STREAM_DRAW) { @@ -667,17 +668,17 @@ define([ var positionArray = new Float32Array(2 * totalLength * 3 * 2); var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); var pickColorArray = new Uint8Array(totalLength * 4 * 2); - var miscArray = new Float32Array(totalLength * 4 * 2); + var texCoordExpandWidthAndShowArray = new Float32Array(totalLength * 4 * 2); var position3DArray; var positionIndex = 0; var adjacencyIndex = 0; var colorIndex = 0; - var miscIndex = 0; + var texCoordExpandWidthAndShowIndex = 0; for (x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; - bucket.write(positionArray, adjacencyArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context); + bucket.write(positionArray, adjacencyArray, pickColorArray, texCoordExpandWidthAndShowArray, positionIndex, adjacencyIndex, colorIndex, texCoordExpandWidthAndShowIndex, context); if (mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { @@ -690,24 +691,29 @@ define([ positionIndex += 2 * bucketLength * 3 * 2; adjacencyIndex += 2 * bucketLength * 4 * 2; colorIndex += bucketLength * 4 * 2; - miscIndex += bucketLength * 4 * 2; + texCoordExpandWidthAndShowIndex += bucketLength * 4 * 2; offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); } } - collection._positionBuffer = context.createVertexBuffer(positionArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); + var positionBufferUsage = collection._buffersUsage[POSITION_INDEX].bufferUsage; + var showBufferUsage = collection._buffersUsage[SHOW_INDEX].bufferUsage; + var widthBufferUsage = collection._buffersUsage[WIDTH_INDEX].bufferUsage; + var texCoordExpandWidthAndShowBufferUsage = (showBufferUsage === BufferUsage.STREAM_DRAW || widthBufferUsage === BufferUsage.STREAM_DRAW) ? BufferUsage.STREAM_DRAW : BufferUsage.STATIC_DRAW; + + collection._positionBuffer = context.createVertexBuffer(positionArray, positionBufferUsage); var position3DBuffer; if (typeof position3DArray !== 'undefined') { - position3DBuffer = context.createVertexBuffer(position3DArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); + position3DBuffer = context.createVertexBuffer(position3DArray, positionBufferUsage); } - collection._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, collection._buffersUsage[POSITION_INDEX].bufferUsage); + collection._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, positionBufferUsage); collection._pickColorBuffer = context.createVertexBuffer(pickColorArray, BufferUsage.STATIC_DRAW); - collection._miscBuffer = context.createVertexBuffer(miscArray, collection._buffersUsage[MISC_INDEX].bufferUsage); + collection._texCoordExpandWidthAndShowBuffer = context.createVertexBuffer(texCoordExpandWidthAndShowArray, texCoordExpandWidthAndShowBufferUsage); var pickColorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; - var miscSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; + var texCoordExpandWidthAndShowSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var vbo = 0; var numberOfIndicesArrays = totalIndices.length; @@ -725,7 +731,7 @@ define([ var prevOffset = 2 * (k * (adjacencySizeInBytes * SIXTYFOURK) - vbo * adjacencySizeInBytes); var nextOffset = adjacencySizeInBytes + prevOffset; var vertexPickColorBufferOffset = k * (pickColorSizeInBytes * SIXTYFOURK) - vbo * pickColorSizeInBytes; - var vertexMiscBufferOffset = k * (miscSizeInBytes * SIXTYFOURK) - vbo * miscSizeInBytes; + var vertexTexCoordExpandWidthAndShowBufferOffset = k * (texCoordExpandWidthAndShowSizeInBytes * SIXTYFOURK) - vbo * texCoordExpandWidthAndShowSizeInBytes; var attributes = [{ index : attributeIndices.position3DHigh, @@ -766,11 +772,11 @@ define([ offsetInBytes : nextOffset, strideInBytes : 2 * adjacencySizeInBytes }, { - index : attributeIndices.misc, + index : attributeIndices.texCoordExpandWidthAndShow, componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : collection._miscBuffer, - offsetInBytes : vertexMiscBufferOffset + vertexBuffer : collection._texCoordExpandWidthAndShowBuffer, + offsetInBytes : vertexTexCoordExpandWidthAndShowBufferOffset }, { index : attributeIndices.pickColor, componentsPerAttribute : 4, @@ -1006,7 +1012,7 @@ define([ var scratchWritePosition = new Cartesian3(); var scratchWriteAdjacency = new Cartesian4(); - PolylineBucket.prototype.write = function(positionArray, adjacencyArray, pickColorArray, miscArray, positionIndex, adjacencyIndex, colorIndex, miscIndex, context) { + PolylineBucket.prototype.write = function(positionArray, adjacencyArray, pickColorArray, texCoordExpandWidthAndShowArray, positionIndex, adjacencyIndex, colorIndex, texCoordExpandWidthAndShowIndex, context) { var mode = this.mode; var polylines = this.polylines; var length = polylines.length; @@ -1060,15 +1066,15 @@ define([ pickColorArray[colorIndex + 2] = pickColor.blue; pickColorArray[colorIndex + 3] = 255; - miscArray[miscIndex] = j / (positionsLength - 1); // s tex coord - miscArray[miscIndex + 1] = 2 * k - 1; // expand direction - miscArray[miscIndex + 2] = width; - miscArray[miscIndex + 3] = show; + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex] = j / (positionsLength - 1); // s tex coord + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * k - 1; // expand direction + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 2] = width; + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 3] = show; positionIndex += 6; adjacencyIndex += 8; colorIndex += 4; - miscIndex += 4; + texCoordExpandWidthAndShowIndex += 4; } } } @@ -1346,25 +1352,25 @@ define([ } }; - PolylineBucket.prototype.writeMiscUpdate = function(positionIndex, polyline, buffer) { + PolylineBucket.prototype.writeTexCoordExpandWidthAndShowUpdate = function(positionIndex, polyline, buffer) { var positionsLength = polyline._actualLength; if (positionsLength) { positionIndex += this.getPolylineStartIndex(polyline); var show = polyline.getShow(); var width = polyline.getWidth(); - var miscArray = new Float32Array(4 * positionsLength * 2); - var miscIndex = 0; + var texCoordExpandWidthAndShowArray = new Float32Array(4 * positionsLength * 2); + var texCoordExpandWidthAndShowIndex = 0; for ( var j = 0; j < positionsLength; ++j) { for (var k = 0; k < 2; ++k) { - miscArray[miscIndex] = j / positionsLength; // s tex coord - miscArray[miscIndex + 1] = 2 * k - 1; // expand direction - miscArray[miscIndex + 2] = width; - miscArray[miscIndex + 3] = show; + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex] = j / (positionsLength - 1); // s tex coord + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * k - 1; // expand direction + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 2] = width; + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 3] = show; - miscIndex += 4; + texCoordExpandWidthAndShowIndex += 4; } } - buffer.copyFromArrayView(miscArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); + buffer.copyFromArrayView(texCoordExpandWidthAndShowArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); } }; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 5e8db20c4294..8a894ca759a8 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -4,7 +4,7 @@ attribute vec3 position2DHigh; attribute vec3 position2DLow; attribute vec4 prev; attribute vec4 next; -attribute vec4 misc; +attribute vec4 texCoordExpandWidthAndShow; attribute vec4 pickColor; #ifndef RENDER_FOR_PICK @@ -19,10 +19,10 @@ uniform float u_morphTime; void main() { - float texCoord = misc.x; - float expandDir = misc.y; - float width = misc.z; - float show = misc.w; + float texCoord = texCoordExpandWidthAndShow.x; + float expandDir = texCoordExpandWidthAndShow.y; + float width = texCoordExpandWidthAndShow.z; + float show = texCoordExpandWidthAndShow.w; vec4 p; vec4 prevDir; From ce5ae327cd5bb31eb8633283753ca2c67c099fed Mon Sep 17 00:00:00 2001 From: mramato Date: Thu, 21 Mar 2013 21:09:41 -0400 Subject: [PATCH 078/114] Update visualizers to set CZML defaults. --- Source/DynamicScene/DynamicPathVisualizer.js | 8 ++++++-- Source/DynamicScene/DynamicPolylineVisualizer.js | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index d4a8f2cf8576..2f407c8e7cb1 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -123,6 +123,7 @@ define([ return; } + var uniforms; if (typeof pathVisualizerIndex === 'undefined') { var unusedIndexes = this._unusedIndexes; var length = unusedIndexes.length; @@ -143,8 +144,13 @@ define([ material = Material.fromType(this._scene.getContext(), Material.PolylineOutlineType); polyline.setMaterial(material); } + uniforms = material.uniforms; + Color.clone(Color.WHITE, uniforms.color); + Color.clone(Color.BLACK, uniforms.outlineColor); + uniforms.outlineWidth = 0; } else { polyline = this._polylineCollection.get(pathVisualizerIndex); + uniforms = polyline.getMaterial().uniforms; } polyline.setShow(true); @@ -157,8 +163,6 @@ define([ polyline.setPositions(positionProperty._getValueRangeInReferenceFrame(sampleStart, sampleStop, time, this._referenceFrame, resolution, polyline.getPositions())); - var uniforms = polyline.getMaterial().uniforms; - property = dynamicPath.color; if (typeof property !== 'undefined') { uniforms.color = property.getValue(time, uniforms.color); diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index b2482ba695a3..b5e150ae899d 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -197,6 +197,7 @@ define([ return; } + var uniforms; if (typeof polylineVisualizerIndex === 'undefined') { var unusedIndexes = this._unusedIndexes; var length = unusedIndexes.length; @@ -217,8 +218,13 @@ define([ material = Material.fromType(this._scene.getContext(), Material.PolylineOutlineType); polyline.setMaterial(material); } + uniforms = material.uniforms; + Color.clone(Color.WHITE, uniforms.color); + Color.clone(Color.BLACK, uniforms.outlineColor); + uniforms.outlineWidth = 0; } else { polyline = this._polylineCollection.get(polylineVisualizerIndex); + uniforms = polyline.getMaterial().uniforms; } polyline.setShow(true); @@ -235,8 +241,6 @@ define([ polyline._visualizerPositions = vertexPositions; } - var uniforms = polyline.getMaterial().uniforms; - var property = dynamicPolyline.color; if (typeof property !== 'undefined') { uniforms.color = property.getValue(time, uniforms.color); From 304ebc426af5197ab8d07380400da60ed338fca4 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 22 Mar 2013 18:05:26 -0400 Subject: [PATCH 079/114] Fix line clipping issue. Remove phong lighting. --- Source/Shaders/PolylineFS.glsl | 9 +-------- Source/Shaders/PolylineVS.glsl | 14 ++++++++++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Source/Shaders/PolylineFS.glsl b/Source/Shaders/PolylineFS.glsl index 9b9a75a3cdf7..e8bc451f2209 100644 --- a/Source/Shaders/PolylineFS.glsl +++ b/Source/Shaders/PolylineFS.glsl @@ -1,5 +1,4 @@ varying vec2 v_textureCoordinates; -varying vec3 v_positionEC; void main() { @@ -9,12 +8,6 @@ void main() materialInput.st = v_textureCoordinates; materialInput.str = vec3(v_textureCoordinates, 0.0); - materialInput.normalEC = vec3(0.0, 0.0, 1.0); - - vec3 positionToEyeEC = -v_positionEC; - materialInput.positionToEyeEC = positionToEyeEC; - czm_material material = czm_getMaterial(materialInput); - - gl_FragColor = czm_phong(normalize(positionToEyeEC), material); + gl_FragColor = vec4(material.diffuse + material.emission, material.alpha); } \ No newline at end of file diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 8a894ca759a8..b24125106e97 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -10,7 +10,6 @@ attribute vec4 pickColor; #ifndef RENDER_FOR_PICK varying vec2 v_textureCoordinates; varying float v_width; -varying vec3 v_positionEC; #else varying vec4 v_pickColor; #endif @@ -104,13 +103,20 @@ void main() expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0); } - vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, -endPointWC.z, 1.0); - gl_Position = czm_viewportOrthographic * positionWC * show; + vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, endPointWC.zw); + + vec4 position; + position.x = 2.0 * (positionWC.x - czm_viewport.x) / czm_viewport.z - 1.0; + position.y = 2.0 * (positionWC.y - czm_viewport.y) / czm_viewport.w - 1.0; + position.z = (positionWC.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2]; + position.w = 1.0; + position /= positionWC.w; + + gl_Position = position * show; #ifndef RENDER_FOR_PICK v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); v_width = width; - v_positionEC = positionEC.xyz; #else v_pickColor = pickColor; #endif From 5b796e7350a489b910a295b7d3449ac67b7352c1 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Mar 2013 14:55:19 -0400 Subject: [PATCH 080/114] Fix apparent z-fighting shown in the Client CZML sandcastle example. --- Source/Shaders/PolylineVS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index b24125106e97..a6a4e9f2fac1 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -73,7 +73,7 @@ void main() nextWC = normalize(p1.xy - endPointWC.xy); direction = normalize(vec2(-nextWC.y, nextWC.x)); } - else if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7)) + else if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7) || czm_equalsEpsilon(nextDir, -prevDir, czm_epsilon1)) { prevEC = czm_modelView * prevDir; p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); From 05a1c8075fa4a6ebf10a0ad2e4306362b7ae071e Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Mar 2013 15:08:14 -0400 Subject: [PATCH 081/114] Modify the current material color when highlighting objects. --- Source/Widgets/Dojo/CesiumViewerWidget.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Source/Widgets/Dojo/CesiumViewerWidget.js b/Source/Widgets/Dojo/CesiumViewerWidget.js index ac3d0b8c0f3d..b2f1004e1f09 100644 --- a/Source/Widgets/Dojo/CesiumViewerWidget.js +++ b/Source/Widgets/Dojo/CesiumViewerWidget.js @@ -1012,16 +1012,22 @@ define([ */ highlightObject : function(selectedObject) { if (this.highlightedObject !== selectedObject) { + var material; if (typeof this.highlightedObject !== 'undefined' && (typeof this.highlightedObject.isDestroyed !== 'function' || !this.highlightedObject.isDestroyed())) { if (typeof this.highlightedObject.material !== 'undefined') { this.highlightedObject.material = this._originalMaterial; - } else if (typeof this.highlightedObject.setMaterial !== 'undefined') { - this.highlightedObject.setMaterial(this._originalMaterial); } else if (typeof this.highlightedObject.outerMaterial !== 'undefined') { this.highlightedObject.outerMaterial = this._originalMaterial; } else if (typeof this.highlightedObject.setColor !== 'undefined') { this.highlightedObject.setColor(this._originalColor); + } else if (typeof this.highlightedObject.setMaterial !== 'undefined') { + material = this.highlightedObject.getMaterial(); + if (typeof material.uniforms.color !== 'undefined') { + material.uniforms.color = Color.clone(this._originalColor, material.uniforms.color); + } else { + this.highlightedObject.setMaterial(this._originalMaterial); + } } } this.highlightedObject = selectedObject; @@ -1029,15 +1035,21 @@ define([ if (typeof selectedObject.material !== 'undefined') { this._originalMaterial = selectedObject.material; selectedObject.material = this.highlightMaterial; - } else if (typeof selectedObject.getMaterial !== 'undefined') { - this._originalMaterial = selectedObject.getMaterial(); - selectedObject.setMaterial(this.highlightMaterial); } else if (typeof selectedObject.outerMaterial !== 'undefined') { this._originalMaterial = selectedObject.outerMaterial; selectedObject.outerMaterial = this.highlightMaterial; } else if (typeof selectedObject.setColor !== 'undefined') { this._originalColor = Color.clone(selectedObject.getColor(), this._originalColor); selectedObject.setColor(this.highlightColor); + } else if (typeof selectedObject.getMaterial !== 'undefined') { + material = selectedObject.getMaterial(); + if (typeof material.uniforms.color !== 'undefined') { + this._originalColor = Color.clone(material.uniforms.color, this._originalColor); + material.uniforms.color = Color.clone(this.highlightColor, material.uniforms.color); + } else { + this._originalMaterial = material; + selectedObject.setMaterial(this.highlightMaterial); + } } } } From 5c2d7bf4214324aa3cc04c322973d0d4c62782f7 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Mar 2013 16:38:14 -0400 Subject: [PATCH 082/114] Cache draw commands. --- Source/Scene/PolylineCollection.js | 48 ++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index e99feaadda69..d8401556aca3 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -145,6 +145,10 @@ define([ this._boundingVolume2D = undefined; this._commandLists = new CommandLists(); + this._cachedColorCommands = []; + this._cachedPickCommands = []; + this._colorCommands = []; + this._pickCommands = []; this._polylinesUpdated = false; this._polylinesRemoved = false; @@ -371,6 +375,8 @@ define([ return this._polylines.length; }; + var emptyArray = []; + /** * @private */ @@ -445,7 +451,9 @@ define([ var pass = frameState.passes; var useDepthTest = (this.morphTime !== 0.0); - this._commandLists.removeAll(); + var commandLists = this._commandLists; + commandLists.colorList = emptyArray; + commandLists.pickList = emptyArray; if (pass.color) { if (typeof this._rs === 'undefined') { @@ -457,7 +465,11 @@ define([ this._rs.depthMask = !useDepthTest; this._rs.depthTest.enabled = useDepthTest; - createCommandLists(boundingVolume, modelMatrix, this._vertexArrays, this._commandLists.colorList, this._rs, this._uniforms, true); + var cachedColorList = this._cachedColorCommands; + var colorList = this._colorCommands; + commandLists.colorList = colorList; + + createCommandLists(colorList, cachedColorList, boundingVolume, modelMatrix, this._vertexArrays, this._rs, this._uniforms, true); } if (pass.pick) { @@ -473,7 +485,11 @@ define([ this._rsPick.depthMask = !useDepthTest; this._rsPick.depthTest.enabled = useDepthTest; - createCommandLists(boundingVolume, modelMatrix, this._vertexArrays, this._commandLists.pickList, this._rsPick, this._uniforms, false, this._spPick); + var cachedPickList = this._cachedPickCommands; + var pickList = this._pickCommands; + commandLists.pickList = pickList; + + createCommandLists(pickList, cachedPickList, boundingVolume, modelMatrix, this._vertexArrays, this._rsPick, this._uniforms, false, this._spPick); } if (!this._commandLists.empty()) { @@ -481,9 +497,13 @@ define([ } }; - function createCommandLists(boundingVolume, modelMatrix, vertexArrays, commands, renderState, uniforms, combineUniforms, shaderProgram) { + function createCommandLists(commands, cachedCommands, boundingVolume, modelMatrix, vertexArrays, renderState, uniforms, combineUniforms, shaderProgram) { var length = vertexArrays.length; + var cachedCommandsLength = cachedCommands.length; + commands.length = 0; + var cacheIndex = 0; + for ( var m = 0; m < length; ++m) { var va = vertexArrays[m]; var buckets = va.buckets; @@ -507,7 +527,13 @@ define([ var mId = createMaterialId(polyline._material); if (mId !== currentId) { if (typeof currentId !== 'undefined') { - command = new DrawCommand(); + if (cacheIndex >= cachedCommandsLength) { + command = new DrawCommand(); + cachedCommands.push(command); + } else { + command = cachedCommands[cacheIndex++]; + } + command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; command.primitiveType = PrimitiveType.TRIANGLES; @@ -540,7 +566,13 @@ define([ } if (typeof currentId !== 'undefined' && count > 0) { - command = new DrawCommand(); + if (cacheIndex >= cachedCommandsLength) { + command = new DrawCommand(); + cachedCommands.push(command); + } else { + command = cachedCommands[cacheIndex++]; + } + command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; command.primitiveType = PrimitiveType.TRIANGLES; @@ -558,6 +590,10 @@ define([ currentId = undefined; } } + + if (commands.length < cachedCommands.length / 2.0) { + cachedCommands.length = commands.length; + } } /** From 278045bcb7a7db7d07643ae7cf0109b2fc0d1526 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Mar 2013 19:00:22 -0400 Subject: [PATCH 083/114] Add czm_antialias GLSL function. --- Source/Shaders/BuiltinFunctions.glsl | 40 +++++++++++++++++++ .../Materials/CheckerboardMaterial.glsl | 12 +----- .../Materials/PolylineArrowMaterial.glsl | 18 ++------- .../Materials/PolylineOutlineMaterial.glsl | 13 +----- Source/Shaders/Materials/StripeMaterial.glsl | 14 ++----- 5 files changed, 51 insertions(+), 46 deletions(-) diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index 9698cc0d04b8..4e405ca67181 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -575,6 +575,46 @@ vec3 czm_multiplyWithColorBalance(vec3 left, vec3 right) return ((leftLuminance + rightLuminance) / (2.0 * targetLuminance)) * target; } +/** + * Procedural anti-aliasing by blurring two colors that meet at a sharp edge. + * + * @name czm_antialias + * @glslFunction + * + * @param {vec4} color1 The color on one side of the edge. + * @param {vec4} color2 The color on the other side of the edge. + * @param {vec4} currentcolor The current color, either color1 or color2. + * @param {float} dist The distance to the edge in texture coordinates. + * @param {float} [fuzzFactor=0.1] Controls the blurriness between the two colors. + * @returns {vec4} The anti-aliased color. + * + * @example + * // GLSL declarations + * vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist, float fuzzFactor); + * vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist); + * + * // get the color for a material that has a sharp edge at the line y = 0.5 in texture space + * float dist = abs(textureCoordinates.t - 0.5); + * vec4 currentColor = mix(bottomColor, topColor, step(0.5, textureCoordinates.t)); + * vec4 color = czm_antialias(bottomColor, topColor, currentColor, dist, 0.1); + */ +vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist, float fuzzFactor) +{ + float val1 = clamp(dist / fuzzFactor, 0.0, 1.0); + float val2 = clamp((dist - 0.5) / fuzzFactor, 0.0, 1.0); + val1 = val1 * (1.0 - val2); + val1 = val1 * val1 * (3.0 - (2.0 * val1)); + val1 = pow(val1, 0.5); //makes the transition nicer + + vec4 midColor = (color1 + color2) * 0.5; + return mix(midColor, currentColor, val1); +} + +vec4 czm_antialias(vec4 color1, vec4 color2, vec4 currentColor, float dist) +{ + return czm_antialias(color1, color2, currentColor, dist, 0.1); +} + /////////////////////////////////////////////////////////////////////////////// /** diff --git a/Source/Shaders/Materials/CheckerboardMaterial.glsl b/Source/Shaders/Materials/CheckerboardMaterial.glsl index 6acaf0f9e473..56d1fdb230aa 100644 --- a/Source/Shaders/Materials/CheckerboardMaterial.glsl +++ b/Source/Shaders/Materials/CheckerboardMaterial.glsl @@ -6,9 +6,7 @@ czm_material czm_getMaterial(czm_materialInput materialInput) { czm_material material = czm_getDefaultMaterial(materialInput); - // Fuzz Factor - Controls blurriness between light and dark colors vec2 st = materialInput.st; - const float fuzz = 0.03; // From Stefan Gustavson's Procedural Textures in GLSL in OpenGL Insights float b = mod(floor(repeat.s * st.s) + floor(repeat.t * st.t), 2.0); // 0.0 or 1.0 @@ -20,17 +18,9 @@ czm_material czm_getMaterial(czm_materialInput materialInput) scaledHeight = abs(scaledHeight - floor(scaledHeight + 0.5)); float value = min(scaledWidth, scaledHeight); - //anti-aliasing - float val1 = clamp(value / fuzz, 0.0, 1.0); - float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); - val1 = val1 * (1.0 - val2); - val1 = val1 * val1 * (3.0 - (2.0 * val1)); - val1 = pow(val1, 0.5); //makes the transition nicer - - vec4 midColor = (lightColor + darkColor) / 2.0; vec4 currentColor = mix(lightColor, darkColor, b); + vec4 color = czm_antialias(lightColor, darkColor, currentColor, value, 0.03); - vec4 color = mix(midColor, currentColor, val1); material.diffuse = color.rgb; material.alpha = color.a; diff --git a/Source/Shaders/Materials/PolylineArrowMaterial.glsl b/Source/Shaders/Materials/PolylineArrowMaterial.glsl index 19cfc9386af3..c2188b55b558 100644 --- a/Source/Shaders/Materials/PolylineArrowMaterial.glsl +++ b/Source/Shaders/Materials/PolylineArrowMaterial.glsl @@ -1,4 +1,3 @@ -// TODO Is there an alternative if standard derivatives aren't supported? #extension GL_OES_standard_derivatives : enable uniform vec4 color; @@ -32,12 +31,12 @@ czm_material czm_getMaterial(czm_materialInput materialInput) t *= step(ptOnLowerLine, st.t); // Find the distance from the closest separator (region between two colors) - float value; + float dist; if (st.s < base) { float d1 = abs(st.t - (0.5 - halfWidth)); float d2 = abs(st.t - (0.5 + halfWidth)); - value = min(d1, d2); + dist = min(d1, d2); } else { @@ -48,21 +47,12 @@ czm_material czm_getMaterial(czm_materialInput materialInput) } float d2 = abs(st.t - ptOnUpperLine); float d3 = abs(st.t - ptOnLowerLine); - value = min(min(d1, d2), d3); + dist = min(min(d1, d2), d3); } - //anti-aliasing - const float fuzz = 0.1; - float val1 = clamp(value / fuzz, 0.0, 1.0); - float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); - val1 = val1 * (1.0 - val2); - val1 = val1 * val1 * (3.0 - (2.0 * val1)); - val1 = pow(val1, 0.5); //makes the transition nicer - vec4 outsideColor = vec4(0.0); - vec4 midColor = (outsideColor + color) * 0.5; vec4 currentColor = mix(outsideColor, color, clamp(s + t, 0.0, 1.0)); - vec4 outColor = mix(midColor, currentColor, val1); + vec4 outColor = czm_antialias(outsideColor, color, currentColor, dist); material.diffuse = outColor.rgb; material.alpha = outColor.a; diff --git a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl index 76dd249b4612..afda276626fb 100644 --- a/Source/Shaders/Materials/PolylineOutlineMaterial.glsl +++ b/Source/Shaders/Materials/PolylineOutlineMaterial.glsl @@ -16,19 +16,10 @@ czm_material czm_getMaterial(czm_materialInput materialInput) // Find the distance from the closest separator (region between two colors) float d1 = abs(st.t - (0.5 - halfInteriorWidth)); float d2 = abs(st.t - (0.5 + halfInteriorWidth)); - float value = min(d1, d2); + float dist = min(d1, d2); - //anti-aliasing - const float fuzz = 0.1; - float val1 = clamp(value / fuzz, 0.0, 1.0); - float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); - val1 = val1 * (1.0 - val2); - val1 = val1 * val1 * (3.0 - (2.0 * val1)); - val1 = pow(val1, 0.5); //makes the transition nicer - - vec4 midColor = (outlineColor + color) * 0.5; vec4 currentColor = mix(outlineColor, color, b); - vec4 outColor = mix(midColor, currentColor, val1); + vec4 outColor = czm_antialias(outlineColor, color, currentColor, dist); material.diffuse = outColor.rgb; material.alpha = outColor.a; diff --git a/Source/Shaders/Materials/StripeMaterial.glsl b/Source/Shaders/Materials/StripeMaterial.glsl index dafdbeb3ec74..c896f04b9e28 100644 --- a/Source/Shaders/Materials/StripeMaterial.glsl +++ b/Source/Shaders/Materials/StripeMaterial.glsl @@ -9,19 +9,13 @@ czm_material czm_getMaterial(czm_materialInput materialInput) czm_material material = czm_getDefaultMaterial(materialInput); // Based on the Stripes Fragment Shader in the Orange Book (11.1.2) - // Fuzz Factor - Controls blurriness between light and dark colors - const float fuzz = 0.1; - float coord = mix(materialInput.st.s, materialInput.st.t, float(horizontal)); float value = fract((coord - offset) * (repeat * 0.5)); + float dist = min(value, min(abs(value - 0.5), 1.0 - value)); + + vec4 currentColor = mix(lightColor, darkColor, step(0.5, value)); + vec4 color = czm_antialias(lightColor, darkColor, currentColor, dist); - //anti-aliasing - float val1 = clamp(value / fuzz, 0.0, 1.0); - float val2 = clamp((value - 0.5) / fuzz, 0.0, 1.0); - val1 = val1 * (1.0 - val2); - val1 = val1 * val1 * (3.0 - (2.0 * val1)); - - vec4 color = mix(lightColor, darkColor, val1); material.diffuse = color.rgb; material.alpha = color.a; From acd1a79494a4d1c3cdb436a4e98c4d8572bd8a77 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Mar 2013 19:35:15 -0400 Subject: [PATCH 084/114] Fix crash on scene mode change. --- Source/Scene/Polyline.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 8bde295f03e0..2fa15d7a0e2c 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -165,6 +165,8 @@ define([ this._positions = value; this._boundingVolume = BoundingSphere.fromPoints(this._positions, this._boundingVolume); makeDirty(this, POSITION_INDEX); + + this.update(); }; /** @@ -176,7 +178,7 @@ define([ modelMatrix = this._polylineCollection.modelMatrix; } - var length = this._segments.lengths.length; + var length = this._segments.positions.length; this._modelMatrix = modelMatrix; var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; @@ -184,7 +186,7 @@ define([ this._segments = PolylinePipeline.wrapLongitude(this._positions, modelMatrix); } - if (this._segments.lengths.length !== length) { + if (this._segments.positions.length !== length) { makeDirty(this, POSITION_SIZE_INDEX); } }; From 77c938e03269955e539c5df2142eeb95fde3fcae Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 26 Mar 2013 20:02:25 -0400 Subject: [PATCH 085/114] Add polyline material examples to Sandcastle. --- Apps/Sandcastle/gallery/Materials.html | 126 +++++++++++++++++++------ 1 file changed, 96 insertions(+), 30 deletions(-) diff --git a/Apps/Sandcastle/gallery/Materials.html b/Apps/Sandcastle/gallery/Materials.html index 6ca31e4f1d9a..92ec60335569 100644 --- a/Apps/Sandcastle/gallery/Materials.html +++ b/Apps/Sandcastle/gallery/Materials.html @@ -37,6 +37,7 @@ var polygon; var worldPolygon; + var polyline; function applyAlphaMapMaterial(primitive, scene) { Sandcastle.declare(applyAlphaMapMaterial); // For highlighting in Sandcastle. @@ -458,6 +459,19 @@ Sandcastle.declare(applyRimLightingMaterial); // For highlighting in Sandcastle. primitive.material = new Cesium.Material.fromType(scene.getContext(), 'RimLighting'); } + + function applyPolylineArrowMaterial(primitive, scene) { + Sandcastle.declare(applyPolylineArrowMaterial); // For highlighting in Sandcastle. + var material = new Cesium.Material.fromType(scene.getContext(), 'PolylineArrow'); + primitive.setMaterial(material); + } + + function applyPolylineOutlineMaterial(primitive, scene) { + Sandcastle.declare(applyPolylineOutlineMaterial); // For highlighting in Sandcastle. + var material = new Cesium.Material.fromType(scene.getContext(), 'PolylineOutline'); + material.uniforms.outlineWidth = primitive.getWidth() / 2.0; + primitive.setMaterial(material); + } function createButtons(widget) { var scene = widget.scene; @@ -468,16 +482,30 @@ var baseMaterialMenu = new DropDownMenu({ style: "display: none;"}); var miscMaterialMenu = new DropDownMenu({ style: "display: none;"}); var compositeMaterialMenu = new DropDownMenu({ style: "display: none;"}); + var polylineMaterialMenu = new DropDownMenu({ style: "display: none;"}); - function togglePolygonVisibility(polygonToShow, polygonToHide) { - polygonToShow.show = true; - polygonToHide.show = false; + function togglePolygonVisibility() { + polygon.show = true; + worldPolygon.show = false; + polyline.setShow(false); + } + + function toggleWorldPolygonVisibility() { + worldPolygon.show = true; + polygon.show = false; + polyline.setShow(false); + } + + function togglePolylineVisibility() { + polyline.setShow(true); + worldPolygon.show = false; + polygon.show = false; } baseMaterialMenu.addChild(new MenuItem({ label: 'Alpha Map', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyAlphaMapMaterial(polygon, scene); Sandcastle.highlight(applyAlphaMapMaterial); } @@ -486,7 +514,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Asphalt', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyAsphaltMaterial(polygon, scene); Sandcastle.highlight(applyAsphaltMaterial); } @@ -495,7 +523,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Blob', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyBlobMaterial(polygon, scene); Sandcastle.highlight(applyBlobMaterial); } @@ -504,7 +532,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Brick', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyBrickMaterial(polygon, scene); Sandcastle.highlight(applyBrickMaterial); } @@ -513,7 +541,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Bump Map', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyBumpMapMaterial(polygon, scene); Sandcastle.highlight(applyBumpMapMaterial); } @@ -522,7 +550,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Cement', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyCementMaterial(polygon, scene); Sandcastle.highlight(applyCementMaterial); } @@ -531,7 +559,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Checkerboard', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyCheckerboardMaterial(polygon, scene); Sandcastle.highlight(applyCheckerboardMaterial); } @@ -540,7 +568,7 @@ compositeMaterialMenu.addChild(new MenuItem({ label: 'Composite Example 1', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyCompositeMaterial1(polygon, scene); Sandcastle.highlight(applyCompositeMaterial1); } @@ -549,7 +577,7 @@ compositeMaterialMenu.addChild(new MenuItem({ label: 'Composite Example 2', onClick: function() { - togglePolygonVisibility(worldPolygon, polygon); + toggleWorldPolygonVisibility(); applyCompositeMaterial2(worldPolygon, scene); Sandcastle.highlight(applyCompositeMaterial2); } @@ -558,7 +586,7 @@ commonMaterialMenu.addChild(new MenuItem({ label: 'Color', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyColorMaterial(polygon, scene); Sandcastle.highlight(applyColorMaterial); } @@ -567,7 +595,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Diffuse', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyDiffuseMaterial(polygon, scene); Sandcastle.highlight(applyDiffuseMaterial); } @@ -576,7 +604,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Dot', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyDotMaterial(polygon, scene); Sandcastle.highlight(applyDotMaterial); } @@ -585,7 +613,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Emission Map', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyEmissionMapMaterial(polygon, scene); Sandcastle.highlight(applyEmissionMapMaterial); } @@ -594,7 +622,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Facet', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyFacetMaterial(polygon, scene); Sandcastle.highlight(applyFacetMaterial); } @@ -603,7 +631,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Fresnel', onClick: function() { - togglePolygonVisibility(worldPolygon, polygon); + toggleWorldPolygonVisibility(); applyFresnelMaterial(worldPolygon, scene); Sandcastle.highlight(applyFresnelMaterial); } @@ -612,7 +640,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Grass', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyGrassMaterial(polygon, scene); Sandcastle.highlight(applyGrassMaterial); } @@ -621,7 +649,7 @@ commonMaterialMenu.addChild(new MenuItem({ label: 'Image', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyImageMaterial(polygon, scene); Sandcastle.highlight(applyImageMaterial); } @@ -630,7 +658,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Normal Map', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyNormalMapMaterial(polygon, scene); Sandcastle.highlight(applyNormalMapMaterial); } @@ -639,7 +667,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Reflection', onClick: function() { - togglePolygonVisibility(worldPolygon, polygon); + toggleWorldPolygonVisibility(); applyReflectionMaterial(worldPolygon, scene); Sandcastle.highlight(applyReflectionMaterial); } @@ -648,7 +676,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Refraction', onClick: function() { - togglePolygonVisibility(worldPolygon, polygon); + toggleWorldPolygonVisibility(); applyRefractionMaterial(worldPolygon, scene); Sandcastle.highlight(applyRefractionMaterial); } @@ -657,7 +685,7 @@ baseMaterialMenu.addChild(new MenuItem({ label: 'Specular Map', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applySpecularMapMaterial(polygon, scene); Sandcastle.highlight(applySpecularMapMaterial); } @@ -666,7 +694,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Stripe', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyStripeMaterial(polygon, scene); Sandcastle.highlight(applyStripeMaterial); } @@ -675,7 +703,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'TieDye', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyTieDyeMaterial(polygon, scene); Sandcastle.highlight(applyTieDyeMaterial); } @@ -684,7 +712,7 @@ proceduralTextureMenu.addChild(new MenuItem({ label: 'Wood', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyWoodMaterial(polygon, scene); Sandcastle.highlight(applyWoodMaterial); } @@ -693,7 +721,7 @@ miscMaterialMenu.addChild(new MenuItem({ label: 'Water', onClick: function() { - togglePolygonVisibility(worldPolygon, polygon); + toggleWorldPolygonVisibility(); applyWaterMaterial(worldPolygon, scene); Sandcastle.highlight(applyWaterMaterial); } @@ -702,7 +730,7 @@ miscMaterialMenu.addChild(new MenuItem({ label: 'Erosion', onClick: function() { - togglePolygonVisibility(polygon, worldPolygon); + togglePolygonVisibility(); applyErosionMaterial(polygon, scene); Sandcastle.highlight(applyErosionMaterial); } @@ -711,11 +739,29 @@ miscMaterialMenu.addChild(new MenuItem({ label: 'RimLighting', onClick: function() { - togglePolygonVisibility(worldPolygon, polygon); + toggleWorldPolygonVisibility(); applyRimLightingMaterial(worldPolygon, scene); Sandcastle.highlight(applyRimLightingMaterial); } })); + + polylineMaterialMenu.addChild(new MenuItem({ + label: 'PolylineArrow', + onClick: function() { + togglePolylineVisibility(); + applyPolylineArrowMaterial(polyline, scene); + Sandcastle.highlight(applyPolylineArrowMaterial); + } + })); + + polylineMaterialMenu.addChild(new MenuItem({ + label: 'PolylineOutline', + onClick: function() { + togglePolylineVisibility(); + applyPolylineOutlineMaterial(polyline, scene); + Sandcastle.highlight(applyPolylineOutlineMaterial); + } + })); new DropDownButton({ label : 'Common materials', @@ -746,11 +792,18 @@ dropDown: compositeMaterialMenu, maxHeight: -1 }).placeAt('toolbar'); + + new DropDownButton({ + label : 'Polyline materials', + dropDown : polylineMaterialMenu, + maxHeight : -1 + }).placeAt('toolbar'); } function createPrimitives(widget) { var scene = widget.scene; var primitives = scene.getPrimitives(); + var ellipsoid = widget.centralBody.getEllipsoid(); polygon = new Cesium.Polygon(); polygon.configureExtent(new Cesium.Extent( @@ -768,6 +821,19 @@ Cesium.Math.toRadians(90.0))); worldPolygon.show = false; primitives.add(worldPolygon); + + var polylines = new Cesium.PolylineCollection(); + polyline = polylines.add({ + positions : [ + ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-110.0, 42.0)), + ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees( -85.0, 36.0)), + ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-100.0, 25.0)), + ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees( -77.0, 12.0)) + ], + width : 10.0, + show : false + }); + primitives.add(polylines); } var widget = new Cesium.CesiumWidget('cesiumContainer'); From 23827077a1cb378a6bef8c07b14acbef705bc93b Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Mar 2013 13:51:00 -0400 Subject: [PATCH 086/114] Update the vertex arrays when the segment lengths change to update the indices. --- Source/Scene/Polyline.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 2fa15d7a0e2c..ce09a307c386 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -165,8 +165,6 @@ define([ this._positions = value; this._boundingVolume = BoundingSphere.fromPoints(this._positions, this._boundingVolume); makeDirty(this, POSITION_INDEX); - - this.update(); }; /** @@ -179,6 +177,7 @@ define([ } var length = this._segments.positions.length; + var segmentLengths = this._segments.lengths; this._modelMatrix = modelMatrix; var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; @@ -187,7 +186,17 @@ define([ } if (this._segments.positions.length !== length) { + // number of positions changed makeDirty(this, POSITION_SIZE_INDEX); + } else { + length = segmentLengths.length; + for (var i = 0; i < length; ++i) { + if (segmentLengths[i] !== this._segments.lengths[i]) { + // indices changed + makeDirty(this, POSITION_SIZE_INDEX); + break; + } + } } }; From ede696307c5b631dfb2da66daecacb55c49e9113 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Mar 2013 15:58:53 -0400 Subject: [PATCH 087/114] Remove extra polyline update. --- Source/Scene/PolylineCollection.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index a833509f00cf..1f01bf8335db 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1005,7 +1005,6 @@ define([ return polyline.getPositions().length; } - polyline.update(); return polyline._segments.positions.length; }; From 67d36c5c4557565a6845d76fe232f4ac6d30f80b Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 27 Mar 2013 20:10:18 -0400 Subject: [PATCH 088/114] Use a spheremap transform to encode normals instead of converting to spherical coordinates. --- Source/Scene/PolylineCollection.js | 12 +++++++---- Source/Shaders/BuiltinFunctions.glsl | 27 ----------------------- Source/Shaders/PolylineVS.glsl | 30 +++++++++++++++----------- Specs/Renderer/BuiltinFunctionsSpec.js | 25 --------------------- 4 files changed, 26 insertions(+), 68 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 1f01bf8335db..1558d5ddc6b2 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1027,8 +1027,10 @@ define([ Cartesian3.subtract(prev, position, prev); } Cartesian3.normalize(prev, prev); - result.x = Math.acos(prev.z); - result.y = Math.atan2(prev.y, prev.x); + + var p = Math.sqrt(prev.z * 8.0 + 8.0); + result.x = prev.x / p + 0.5; + result.y = prev.y / p + 0.5; var next = computeAdjacencyAnglesPosition; if (endSegment) { @@ -1038,8 +1040,10 @@ define([ Cartesian3.subtract(next, position, next); } Cartesian3.normalize(next, next); - result.z = Math.acos(next.z); - result.w = Math.atan2(next.y, next.x); + + p = Math.sqrt(next.z * 8.0 + 8.0); + result.z = next.x / p + 0.5; + result.w = next.y / p + 0.5; return result; } diff --git a/Source/Shaders/BuiltinFunctions.glsl b/Source/Shaders/BuiltinFunctions.glsl index 4e405ca67181..835095a8c7a0 100644 --- a/Source/Shaders/BuiltinFunctions.glsl +++ b/Source/Shaders/BuiltinFunctions.glsl @@ -1002,33 +1002,6 @@ vec3 czm_translateRelativeToEye(vec3 high, vec3 low) return highDifference + lowDifference; } -/** - * Converts from spherical coordinates to cartesian coordinates. - * - * @name czm_sphericalToCartesianCoordinates - * @glslFunction - * - * @param {vec2} spherical The spherical coordinates. The x property is the angle in - * the xy-plane from the positive x-axis. The y property is the angle from the positive z-axis. - * @returns {vec3} The cartesian coordinates - * - * @example - * // normal in spherical coordinates to cartesian coordinates - * vec3 normal = normalize(czm_sphericalToCartesianCoordinates(normalSpherical)); - * - * // position in spherical coordinates to cartesian coordinates - * vec3 position = normalize(czm_sphericalToCartesianCoordinates(positionSpherical)); - * position *= radius; - */ -vec3 czm_sphericalToCartesianCoordinates(vec2 spherical) -{ - float sinTheta = sin(spherical.x); - float x = sinTheta * cos(spherical.y); - float y = sinTheta * sin(spherical.y); - float z = cos(spherical.x); - return vec3(x, y, z); -} - /** * @private */ diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index a6a4e9f2fac1..90b30888fb3f 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -16,6 +16,18 @@ varying vec4 v_pickColor; uniform float u_morphTime; +vec3 decode(vec2 enc) +{ + vec2 fenc = enc * 4.0 - 2.0; + float f = dot(fenc, fenc); + float g = sqrt(1.0 - f / 4.0); + + vec3 n; + n.xy = fenc * g; + n.z = 1.0 - f / 2.0; + return n; +} + void main() { float texCoord = texCoordExpandWidthAndShow.x; @@ -30,14 +42,14 @@ void main() if (u_morphTime == 1.0) { p = vec4(czm_translateRelativeToEye(position3DHigh, position3DLow), 1.0); - prevDir = vec4(czm_sphericalToCartesianCoordinates(prev.xy), 0.0); - nextDir = vec4(czm_sphericalToCartesianCoordinates(next.xy), 0.0); + prevDir = vec4(decode(prev.xy), 0.0); + nextDir = vec4(decode(next.xy), 0.0); } else if (u_morphTime == 0.0) { p = vec4(czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), 1.0); - prevDir = vec4(czm_sphericalToCartesianCoordinates(prev.zw).zxy, 0.0); - nextDir = vec4(czm_sphericalToCartesianCoordinates(next.zw).zxy, 0.0); + prevDir = vec4(decode(prev.zw).zxy, 0.0); + nextDir = vec4(decode(next.zw).zxy, 0.0); } else { @@ -45,15 +57,9 @@ void main() czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), czm_translateRelativeToEye(position3DHigh, position3DLow), u_morphTime); - prevDir = czm_columbusViewMorph( - czm_sphericalToCartesianCoordinates(prev.xy), - czm_sphericalToCartesianCoordinates(prev.zw), - u_morphTime); - nextDir = czm_columbusViewMorph( - czm_sphericalToCartesianCoordinates(next.xy), - czm_sphericalToCartesianCoordinates(next.zw), - u_morphTime); + prevDir = czm_columbusViewMorph(decode(prev.xy), decode(prev.zw), u_morphTime); + nextDir = czm_columbusViewMorph(decode(next.xy), decode(next.zw), u_morphTime); prevDir.w = 0.0; nextDir.w = 0.0; } diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index 1a1e176ccc5c..6152ba6ea0a1 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -177,29 +177,4 @@ defineSuite([ verifyDraw(fs, uniformMap); }); - - it('has czm_sphericalToCartesianCoordinates', function() { - var normal = new Cartesian3(1.0, 1.0, 1.0).normalize(); - var latLon = new Cartesian2(Math.acos(normal.z), Math.atan2(normal.y, normal.x)); - - var uniformMap = { - u_latLon : function() { - return latLon; - }, - u_normal : function() { - return normal; - } - }; - - var fs = - 'uniform vec2 u_latLon;' + - 'uniform vec3 u_normal;' + - 'void main() {' + - ' vec3 cartesian = czm_sphericalToCartesianCoordinates(u_latLon);' + - ' vec3 diff = abs(u_normal - cartesian);' + - ' gl_FragColor = vec4(all(lessThan(diff, vec3(czm_epsilon6))));' + - '}'; - - verifyDraw(fs, uniformMap); - }); }, 'WebGL'); \ No newline at end of file From e3af8223a48fa9bf6267e4adb6dca345787860a4 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Mar 2013 15:23:17 -0400 Subject: [PATCH 089/114] Improve polyline vertex shader performance by removing the inverse cosine and sine function calls. --- Source/Shaders/PolylineVS.glsl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 90b30888fb3f..f87688947eec 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -104,8 +104,14 @@ void main() direction = -direction; } - float angle = acos(dot(direction, nextWC)); - float sinAngle = sin(angle); + // The sine of the angle between the two vectors is given by the formula + // |a x b| = |a||b|sin(theta) + // which is + // float sinAngle = length(cross(vec3(direction, 0.0), vec3(nextWC, 0.0))); + // Because the z components of both vectors are zero, the x and y coordinate will be zero. + // Therefore, the sine of the angle is just the z component of the cross product. + float sinAngle = direction.y * nextWC.x - direction.x * nextWC.y; + expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0); } From 79424d873432d25f2f5f4a717dfb10f7dfc98d66 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Mar 2013 15:38:44 -0400 Subject: [PATCH 090/114] Add comments with links. --- Source/Scene/PolylineCollection.js | 4 ++++ Source/Shaders/PolylineVS.glsl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 1558d5ddc6b2..1f0d26484a9c 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1010,6 +1010,10 @@ define([ var computeAdjacencyAnglesPosition = new Cartesian3(); + // Two normals are packed into a Cartesian4 using a spheremap transform + // see + // http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap + // for details. function computeAdjacencyAngles(position, index, positions, startSegment, endSegment, result, modelMatrix) { if (typeof result === 'undefined') { result = new Cartesian4(); diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index f87688947eec..4794891505fa 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -16,6 +16,10 @@ varying vec4 v_pickColor; uniform float u_morphTime; +// Unpacks a normal from a vec2 using a spheremap transform +// see +// http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap +// for details. vec3 decode(vec2 enc) { vec2 fenc = enc * 4.0 - 2.0; From 19a0ed282eca012a27eb48c066b673fccc8791b7 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 28 Mar 2013 17:24:06 -0400 Subject: [PATCH 091/114] Update simple.czml to reflect lastest converter changes. --- Apps/CesiumViewer/Gallery/simple.czml | 104 +++++++++++++------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/Apps/CesiumViewer/Gallery/simple.czml b/Apps/CesiumViewer/Gallery/simple.czml index 3c37d952cd48..238cd386628c 100644 --- a/Apps/CesiumViewer/Gallery/simple.czml +++ b/Apps/CesiumViewer/Gallery/simple.czml @@ -143,7 +143,7 @@ "number":1.0 } ], - "resolution":10.0, + "resolution":60.0, "show":[ { "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", @@ -157,8 +157,8 @@ "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ - 0.0,2370.575224321001, - 2370.575224321001,0.0 + 0.0,5903.376977238004, + 5903.376977238004,0.0 ] }, { @@ -292,7 +292,7 @@ ] }, { - "interval":"2012-03-16T07:58:35.1683124770061Z/2012-03-16T09:36:58.6038607679948Z", + "interval":"2012-03-16T07:58:35.1683124770061Z/2012-03-16T08:21:36.5644517090113Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-16T07:58:35.1683124770061Z", @@ -302,13 +302,13 @@ ] }, { - "interval":"2012-03-16T09:36:58.6038607679948Z/2012-03-16T10:00:00Z", + "interval":"2012-03-16T08:21:36.5644517090113Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T09:36:58.6038607679948Z", + "epoch":"2012-03-16T08:21:36.5644517090113Z", "number":[ - 0.0,1381.3961392320052, - 1381.3961392320052,0.0 + 0.0,5903.435548290989, + 5903.435548290989,0.0 ] } ], @@ -320,7 +320,7 @@ "epoch":"2012-03-15T10:00:00Z", "number":[ 0.0,0.0, - 2370.575224321001,2370.575224321001 + 5903.376977238004,5903.376977238004 ] }, { @@ -454,7 +454,7 @@ ] }, { - "interval":"2012-03-16T07:58:35.1683124770061Z/2012-03-16T09:36:58.6038607679948Z", + "interval":"2012-03-16T07:58:35.1683124770061Z/2012-03-16T08:21:36.5644517090113Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-16T07:58:35.1683124770061Z", @@ -464,13 +464,13 @@ ] }, { - "interval":"2012-03-16T09:36:58.6038607679948Z/2012-03-16T10:00:00Z", + "interval":"2012-03-16T08:21:36.5644517090113Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T09:36:58.6038607679948Z", + "epoch":"2012-03-16T08:21:36.5644517090113Z", "number":[ 0.0,0.0, - 1381.3961392320052,1381.3961392320052 + 5903.435548290989,5903.435548290989 ] } ] @@ -852,7 +852,7 @@ "number":1.0 } ], - "resolution":10.0, + "resolution":60.0, "show":[ { "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", @@ -866,8 +866,8 @@ "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ - 0.0,2696.103115773003, - 2696.103115773003,0.0 + 0.0,5537.546684141998, + 5537.546684141998,0.0 ] }, { @@ -1011,7 +1011,7 @@ ] }, { - "interval":"2012-03-16T08:17:01.17765616998076Z/2012-03-16T09:49:18.6175852820161Z", + "interval":"2012-03-16T08:17:01.17765616998076Z/2012-03-16T08:27:42.5600708879647Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-16T08:17:01.17765616998076Z", @@ -1021,13 +1021,13 @@ ] }, { - "interval":"2012-03-16T09:49:18.6175852820161Z/2012-03-16T10:00:00Z", + "interval":"2012-03-16T08:27:42.5600708879647Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T09:49:18.6175852820161Z", + "epoch":"2012-03-16T08:27:42.5600708879647Z", "number":[ - 0.0,641.3824147179839, - 641.3824147179839,0.0 + 0.0,5537.439929112035, + 5537.439929112035,0.0 ] } ], @@ -1039,7 +1039,7 @@ "epoch":"2012-03-15T10:00:00Z", "number":[ 0.0,0.0, - 2696.103115773003,2696.103115773003 + 5537.546684141998,5537.546684141998 ] }, { @@ -1183,7 +1183,7 @@ ] }, { - "interval":"2012-03-16T08:17:01.17765616998076Z/2012-03-16T09:49:18.6175852820161Z", + "interval":"2012-03-16T08:17:01.17765616998076Z/2012-03-16T08:27:42.5600708879647Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-16T08:17:01.17765616998076Z", @@ -1193,13 +1193,13 @@ ] }, { - "interval":"2012-03-16T09:49:18.6175852820161Z/2012-03-16T10:00:00Z", + "interval":"2012-03-16T08:27:42.5600708879647Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T09:49:18.6175852820161Z", + "epoch":"2012-03-16T08:27:42.5600708879647Z", "number":[ 0.0,0.0, - 641.3824147179839,641.3824147179839 + 5537.439929112035,5537.439929112035 ] } ] @@ -1587,7 +1587,7 @@ "number":1.0 } ], - "resolution":10.0, + "resolution":60.0, "show":[ { "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", @@ -1601,8 +1601,8 @@ "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ - 0.0,4025.3874546559964, - 4025.3874546559964,0.0 + 0.0,5933.062741324, + 5933.062741324,0.0 ] }, { @@ -1726,7 +1726,7 @@ ] }, { - "interval":"2012-03-16T06:53:42.1819449639879Z/2012-03-16T08:32:35.2452977779903Z", + "interval":"2012-03-16T06:53:42.1819449639879Z/2012-03-16T08:21:06.93664718599757Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-16T06:53:42.1819449639879Z", @@ -1736,13 +1736,13 @@ ] }, { - "interval":"2012-03-16T08:32:35.2452977779903Z/2012-03-16T10:00:00Z", + "interval":"2012-03-16T08:21:06.93664718599757Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T08:32:35.2452977779903Z", + "epoch":"2012-03-16T08:21:06.93664718599757Z", "number":[ - 0.0,5244.75470222201, - 5244.75470222201,0.0 + 0.0,5933.063352814002, + 5933.063352814002,0.0 ] } ], @@ -1754,7 +1754,7 @@ "epoch":"2012-03-15T10:00:00Z", "number":[ 0.0,0.0, - 4025.3874546559964,4025.3874546559964 + 5933.062741324,5933.062741324 ] }, { @@ -1878,7 +1878,7 @@ ] }, { - "interval":"2012-03-16T06:53:42.1819449639879Z/2012-03-16T08:32:35.2452977779903Z", + "interval":"2012-03-16T06:53:42.1819449639879Z/2012-03-16T08:21:06.93664718599757Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-16T06:53:42.1819449639879Z", @@ -1888,13 +1888,13 @@ ] }, { - "interval":"2012-03-16T08:32:35.2452977779903Z/2012-03-16T10:00:00Z", + "interval":"2012-03-16T08:21:06.93664718599757Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T08:32:35.2452977779903Z", + "epoch":"2012-03-16T08:21:06.93664718599757Z", "number":[ 0.0,0.0, - 5244.75470222201,5244.75470222201 + 5933.063352814002,5933.063352814002 ] } ] @@ -2276,7 +2276,7 @@ "number":1.0 } ], - "resolution":10.0, + "resolution":60.0, "show":[ { "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", @@ -2290,12 +2290,12 @@ "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ - 0.0,11502.060721728994, - 11502.060721728994,0.0 + 0.0,43058.246637085, + 43058.246637085,0.0 ] }, { - "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-16T01:09:20.307358813996Z", + "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-15T22:02:21.7533629149984Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-15T13:11:42.0607217289944Z", @@ -2305,13 +2305,13 @@ ] }, { - "interval":"2012-03-16T01:09:20.307358813996Z/2012-03-16T10:00:00Z", + "interval":"2012-03-15T22:02:21.7533629149984Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T01:09:20.307358813996Z", + "epoch":"2012-03-15T22:02:21.7533629149984Z", "number":[ - 0.0,31839.692641186004, - 31839.692641186004,0.0 + 0.0,43058.246637085, + 43058.246637085,0.0 ] } ], @@ -2323,11 +2323,11 @@ "epoch":"2012-03-15T10:00:00Z", "number":[ 0.0,0.0, - 11502.060721728994,11502.060721728994 + 43058.246637085,43058.246637085 ] }, { - "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-16T01:09:20.307358813996Z", + "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-15T22:02:21.7533629149984Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-15T13:11:42.0607217289944Z", @@ -2337,13 +2337,13 @@ ] }, { - "interval":"2012-03-16T01:09:20.307358813996Z/2012-03-16T10:00:00Z", + "interval":"2012-03-15T22:02:21.7533629149984Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, - "epoch":"2012-03-16T01:09:20.307358813996Z", + "epoch":"2012-03-15T22:02:21.7533629149984Z", "number":[ 0.0,0.0, - 31839.692641186004,31839.692641186004 + 43058.246637085,43058.246637085 ] } ] From f17c399c48b602efa8fecd599f21c3d9d31deb59 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Mar 2013 17:38:58 -0400 Subject: [PATCH 092/114] Modify command creation and caching. --- Source/Scene/PolylineCollection.js | 39 ++++++++++++------------------ 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 1f0d26484a9c..91e95d92e7bf 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -145,8 +145,6 @@ define([ this._boundingVolume2D = undefined; this._commandLists = new CommandLists(); - this._cachedColorCommands = []; - this._cachedPickCommands = []; this._colorCommands = []; this._pickCommands = []; @@ -465,11 +463,10 @@ define([ this._rs.depthMask = !useDepthTest; this._rs.depthTest.enabled = useDepthTest; - var cachedColorList = this._cachedColorCommands; var colorList = this._colorCommands; commandLists.colorList = colorList; - createCommandLists(colorList, cachedColorList, boundingVolume, modelMatrix, this._vertexArrays, this._rs, this._uniforms, true); + createCommandLists(colorList, boundingVolume, modelMatrix, this._vertexArrays, this._rs, this._uniforms, true); } if (pass.pick) { @@ -485,11 +482,10 @@ define([ this._rsPick.depthMask = !useDepthTest; this._rsPick.depthTest.enabled = useDepthTest; - var cachedPickList = this._cachedPickCommands; var pickList = this._pickCommands; commandLists.pickList = pickList; - createCommandLists(pickList, cachedPickList, boundingVolume, modelMatrix, this._vertexArrays, this._rsPick, this._uniforms, false, this._spPick); + createCommandLists(pickList, boundingVolume, modelMatrix, this._vertexArrays, this._rsPick, this._uniforms, false, this._spPick); } if (!this._commandLists.empty()) { @@ -497,12 +493,11 @@ define([ } }; - function createCommandLists(commands, cachedCommands, boundingVolume, modelMatrix, vertexArrays, renderState, uniforms, combineUniforms, shaderProgram) { + function createCommandLists(commands, boundingVolume, modelMatrix, vertexArrays, renderState, uniforms, combineUniforms, shaderProgram) { var length = vertexArrays.length; - var cachedCommandsLength = cachedCommands.length; - commands.length = 0; - var cacheIndex = 0; + var commandsLength = commands.length; + var commandIndex = 0; for ( var m = 0; m < length; ++m) { var va = vertexArrays[m]; @@ -527,13 +522,15 @@ define([ var mId = createMaterialId(polyline._material); if (mId !== currentId) { if (typeof currentId !== 'undefined') { - if (cacheIndex >= cachedCommandsLength) { + if (commandIndex >= commandsLength) { command = new DrawCommand(); - cachedCommands.push(command); + commands.push(command); } else { - command = cachedCommands[cacheIndex++]; + command = commands[commandIndex]; } + ++commandIndex; + command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; command.primitiveType = PrimitiveType.TRIANGLES; @@ -545,8 +542,6 @@ define([ command.count = count; command.offset = offset; - commands.push(command); - offset += count; count = 0; } @@ -566,13 +561,15 @@ define([ } if (typeof currentId !== 'undefined' && count > 0) { - if (cacheIndex >= cachedCommandsLength) { + if (commandIndex >= commandsLength) { command = new DrawCommand(); - cachedCommands.push(command); + commands.push(command); } else { - command = cachedCommands[cacheIndex++]; + command = commands[commandIndex]; } + ++commandIndex; + command.boundingVolume = boundingVolume; command.modelMatrix = modelMatrix; command.primitiveType = PrimitiveType.TRIANGLES; @@ -583,17 +580,13 @@ define([ command.uniformMap = combineUniforms ? combine([uniforms, currentMaterial._uniforms], false, false) : uniforms; command.count = count; command.offset = offset; - - commands.push(command); } currentId = undefined; } } - if (commands.length < cachedCommands.length / 2.0) { - cachedCommands.length = commands.length; - } + commands.length = commandIndex; } /** From dfc293fbba6285838bac034849be7478652d0b6f Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Mar 2013 17:57:56 -0400 Subject: [PATCH 093/114] Fix error found in test czml file. --- Source/Scene/PolylineCollection.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 91e95d92e7bf..33ae65515446 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1272,7 +1272,6 @@ define([ positions : undefined, lengths : undefined }; - var scratchLengths = new Array(1); PolylineBucket.prototype.getSegments = function(polyline) { var positions = polyline.getPositions(); @@ -1286,9 +1285,8 @@ define([ } if (this.mode === SceneMode.SCENE3D) { - scratchLengths[0] = positions.length; - scratchSegments.positions = positions; - scratchSegments.lengths = scratchLengths; + scratchSegments.positions = polyline._segments.positions; + scratchSegments.lengths = polyline._segments.lengths; return scratchSegments; } From ac15fda3c90646d1008af1b6f6bdd14f72fe98fd Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 28 Mar 2013 18:05:19 -0400 Subject: [PATCH 094/114] Final tweak to simple.czml --- Apps/CesiumViewer/Gallery/simple.czml | 52 ++++----------------------- 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/Apps/CesiumViewer/Gallery/simple.czml b/Apps/CesiumViewer/Gallery/simple.czml index 238cd386628c..453665420d2f 100644 --- a/Apps/CesiumViewer/Gallery/simple.czml +++ b/Apps/CesiumViewer/Gallery/simple.czml @@ -6,7 +6,7 @@ "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", "currentTime":"2012-03-15T10:00:00Z", "multiplier":60.0, - "range":"LOOP_STOP", + "range":"UNBOUNDED", "step":"SYSTEM_CLOCK_MULTIPLIER" } }, @@ -2285,65 +2285,25 @@ ], "leadTime":[ { - "interval":"2012-03-15T10:00:00Z/2012-03-15T13:11:42.0607217289944Z", + "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ - 0.0,43058.246637085, - 43058.246637085,0.0 - ] - }, - { - "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-15T22:02:21.7533629149984Z", - "interpolationAlgorithm":"LINEAR", - "interpolationDegree":1, - "epoch":"2012-03-15T13:11:42.0607217289944Z", - "number":[ - 0.0,43058.246637085, - 43058.246637085,0.0 - ] - }, - { - "interval":"2012-03-15T22:02:21.7533629149984Z/2012-03-16T10:00:00Z", - "interpolationAlgorithm":"LINEAR", - "interpolationDegree":1, - "epoch":"2012-03-15T22:02:21.7533629149984Z", - "number":[ - 0.0,43058.246637085, - 43058.246637085,0.0 + 0.0,8.64e4, + 8.64e4,0.0 ] } ], "trailTime":[ { - "interval":"2012-03-15T10:00:00Z/2012-03-15T13:11:42.0607217289944Z", + "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ 0.0,0.0, - 43058.246637085,43058.246637085 - ] - }, - { - "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-15T22:02:21.7533629149984Z", - "interpolationAlgorithm":"LINEAR", - "interpolationDegree":1, - "epoch":"2012-03-15T13:11:42.0607217289944Z", - "number":[ - 0.0,0.0, - 43058.246637085,43058.246637085 - ] - }, - { - "interval":"2012-03-15T22:02:21.7533629149984Z/2012-03-16T10:00:00Z", - "interpolationAlgorithm":"LINEAR", - "interpolationDegree":1, - "epoch":"2012-03-15T22:02:21.7533629149984Z", - "number":[ - 0.0,0.0, - 43058.246637085,43058.246637085 + 8.64e4,8.64e4 ] } ] From 8953a3992f42151607e729da898e1f0c90027110 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 28 Mar 2013 19:53:20 -0400 Subject: [PATCH 095/114] Revert last change and update polyline segments when positions are changed. --- Source/Scene/Polyline.js | 2 ++ Source/Scene/PolylineCollection.js | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index ce09a307c386..82a76a4eb470 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -165,6 +165,8 @@ define([ this._positions = value; this._boundingVolume = BoundingSphere.fromPoints(this._positions, this._boundingVolume); makeDirty(this, POSITION_INDEX); + + this.update(); }; /** diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 33ae65515446..91e95d92e7bf 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1272,6 +1272,7 @@ define([ positions : undefined, lengths : undefined }; + var scratchLengths = new Array(1); PolylineBucket.prototype.getSegments = function(polyline) { var positions = polyline.getPositions(); @@ -1285,8 +1286,9 @@ define([ } if (this.mode === SceneMode.SCENE3D) { - scratchSegments.positions = polyline._segments.positions; - scratchSegments.lengths = polyline._segments.lengths; + scratchLengths[0] = positions.length; + scratchSegments.positions = positions; + scratchSegments.lengths = scratchLengths; return scratchSegments; } From ef749667f655878f3b15feda0cfa492032e208a6 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 29 Mar 2013 15:31:33 -0400 Subject: [PATCH 096/114] Fix line width issue. --- Source/Shaders/PolylineVS.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 4794891505fa..eab27b12ba82 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -114,7 +114,7 @@ void main() // float sinAngle = length(cross(vec3(direction, 0.0), vec3(nextWC, 0.0))); // Because the z components of both vectors are zero, the x and y coordinate will be zero. // Therefore, the sine of the angle is just the z component of the cross product. - float sinAngle = direction.y * nextWC.x - direction.x * nextWC.y; + float sinAngle = abs(direction.x * nextWC.y - direction.y * nextWC.x); expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0); } From 2452897acf87391df595d10edfcf48d74513ea6a Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Fri, 29 Mar 2013 16:08:28 -0400 Subject: [PATCH 097/114] Update simple.czml --- Apps/CesiumViewer/Gallery/simple.czml | 52 +++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/Apps/CesiumViewer/Gallery/simple.czml b/Apps/CesiumViewer/Gallery/simple.czml index 453665420d2f..238cd386628c 100644 --- a/Apps/CesiumViewer/Gallery/simple.czml +++ b/Apps/CesiumViewer/Gallery/simple.czml @@ -6,7 +6,7 @@ "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", "currentTime":"2012-03-15T10:00:00Z", "multiplier":60.0, - "range":"UNBOUNDED", + "range":"LOOP_STOP", "step":"SYSTEM_CLOCK_MULTIPLIER" } }, @@ -2285,25 +2285,65 @@ ], "leadTime":[ { - "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", + "interval":"2012-03-15T10:00:00Z/2012-03-15T13:11:42.0607217289944Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ - 0.0,8.64e4, - 8.64e4,0.0 + 0.0,43058.246637085, + 43058.246637085,0.0 + ] + }, + { + "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-15T22:02:21.7533629149984Z", + "interpolationAlgorithm":"LINEAR", + "interpolationDegree":1, + "epoch":"2012-03-15T13:11:42.0607217289944Z", + "number":[ + 0.0,43058.246637085, + 43058.246637085,0.0 + ] + }, + { + "interval":"2012-03-15T22:02:21.7533629149984Z/2012-03-16T10:00:00Z", + "interpolationAlgorithm":"LINEAR", + "interpolationDegree":1, + "epoch":"2012-03-15T22:02:21.7533629149984Z", + "number":[ + 0.0,43058.246637085, + 43058.246637085,0.0 ] } ], "trailTime":[ { - "interval":"2012-03-15T10:00:00Z/2012-03-16T10:00:00Z", + "interval":"2012-03-15T10:00:00Z/2012-03-15T13:11:42.0607217289944Z", "interpolationAlgorithm":"LINEAR", "interpolationDegree":1, "epoch":"2012-03-15T10:00:00Z", "number":[ 0.0,0.0, - 8.64e4,8.64e4 + 43058.246637085,43058.246637085 + ] + }, + { + "interval":"2012-03-15T13:11:42.0607217289944Z/2012-03-15T22:02:21.7533629149984Z", + "interpolationAlgorithm":"LINEAR", + "interpolationDegree":1, + "epoch":"2012-03-15T13:11:42.0607217289944Z", + "number":[ + 0.0,0.0, + 43058.246637085,43058.246637085 + ] + }, + { + "interval":"2012-03-15T22:02:21.7533629149984Z/2012-03-16T10:00:00Z", + "interpolationAlgorithm":"LINEAR", + "interpolationDegree":1, + "epoch":"2012-03-15T22:02:21.7533629149984Z", + "number":[ + 0.0,0.0, + 43058.246637085,43058.246637085 ] } ] From d9fcfbfe251556a6f4dc0c329b2a916d4728dd6a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 2 Apr 2013 17:42:12 -0400 Subject: [PATCH 098/114] Update CHANGES.md after merge. --- CHANGES.md | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 73e9b2561046..46a59604e803 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,15 +5,6 @@ Beta Releases ------------- ### b16 - 2013-05-01 * Breaking changes: - * -* Added `AnimationViewModel.snapToTicks`, which when set to true, causes the shuttle ring on the Animation widget to snap to the defined tick values, rather than interpolate between them. - -### b15 - 2013-04-01 - -* Breaking changes: - * `Billboard.computeScreenSpacePosition` now takes `Context` and `FrameState` arguments instead of a `UniformState` argument. - * Removed `clampToPixel` property from `BillboardCollection` and `LabelCollection`. This options is no longer be needed due to overall LabelCollection visualization improvements. - * Removed `Widgets/Dojo/CesiumWidget` and replaced it with `Widgets/CesiumWidget`, which has no Dojo dependancies. * Removed the color, outline color, and outline width properties of polylines. Instead, use materials for polyline color and outline properties. Code that looked like: var polyline = polylineCollection.add({ @@ -36,7 +27,18 @@ Beta Releases width : 3.0, material : outlineMaterial }); - +* Added wide polylines that work with and without ANGLE. +* Polylines now use materials to describe their surface appearance. See the [Fabric](https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric) wiki page for more details on how to create materials. +* Added new `PolylineOutline`, `PolylineArrow`, and `Fade` materials. +* Added `czm_pixelSizeInMeters` automatic GLSL uniform. +* Added `AnimationViewModel.snapToTicks`, which when set to true, causes the shuttle ring on the Animation widget to snap to the defined tick values, rather than interpolate between them. + +### b15 - 2013-04-01 + +* Breaking changes: + * `Billboard.computeScreenSpacePosition` now takes `Context` and `FrameState` arguments instead of a `UniformState` argument. + * Removed `clampToPixel` property from `BillboardCollection` and `LabelCollection`. This options is no longer be needed due to overall LabelCollection visualization improvements. + * Removed `Widgets/Dojo/CesiumWidget` and replaced it with `Widgets/CesiumWidget`, which has no Dojo dependancies. * `destroyObject` no longer deletes properties from the object being destroyed. * `darker.css` files have been deleted and the `darker` theme is now the default style for widgets. The original theme is now known as `lighter` and is in corresponding `lighter.css` files. * CSS class names have been standardized to avoid potential collisions. All widgets now follow the same pattern, `cesium--`. @@ -46,10 +48,6 @@ Beta Releases * Added `DynamicPath.resolution` property for setting the maximum step size, in seconds, to take when sampling a position for path visualization. * Added `TileCoordinatesImageryProvider` that renders imagery with tile X, Y, Level coordinates on the surface of the globe. This is mostly useful for debugging. * Added `DynamicEllipse` and `DynamicObject.ellipse` property to render CZML ellipses on the globe. -* Added wide polylines that work with and without ANGLE. -* Polylines now use materials to describe their surface appearance. See the [Fabric](https://github.com/AnalyticalGraphicsInc/cesium/wiki/Fabric) wiki page for more details on how to create materials. -* Added new `PolylineOutline`, `PolylineArrow`, and `Fade` materials. -* Added `czm_pixelSizeInMeters` automatic GLSL uniform. * Added `sampleTerrain` function to sample the terrain height of a list of `Cartographic` positions. * Added `DynamicObjectCollection.removeObject` and handling of the new CZML `delete` property. * Imagery layers with an `alpha` of exactly 0.0 are no longer rendered. Previously these invisible layers were rendered normally, which was a waste of resources. Unlike the `show` property, imagery tiles in a layer with an `alpha` of 0.0 are still downloaded, so the layer will become visible more quickly when its `alpha` is increased. From e6009979657a0e78b79538ad97eb1c27ab92107c Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 2 Apr 2013 20:44:02 -0400 Subject: [PATCH 099/114] Add polyline segment length and which direction to use for clipping. --- Source/Scene/PolylineCollection.js | 246 ++++++++++++++++++----------- Source/Shaders/PolylineVS.glsl | 12 +- 2 files changed, 162 insertions(+), 96 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 91e95d92e7bf..cb3a1e19e5c0 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -694,7 +694,7 @@ define([ if (totalLength > 0) { var mode = collection._mode; - var positionArray = new Float32Array(2 * totalLength * 3 * 2); + var positionArray = new Float32Array(2 * totalLength * 4 * 2); var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); var pickColorArray = new Uint8Array(totalLength * 4 * 2); var texCoordExpandWidthAndShowArray = new Float32Array(totalLength * 4 * 2); @@ -711,13 +711,13 @@ define([ if (mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { - position3DArray = new Float32Array(2 * totalLength * 3 * 2); + position3DArray = new Float32Array(2 * totalLength * 4 * 2); } bucket.writeForMorph(position3DArray, adjacencyArray, positionIndex, adjacencyIndex); } var bucketLength = bucket.lengthOfPositions; - positionIndex += 2 * bucketLength * 3 * 2; + positionIndex += 2 * bucketLength * 4 * 2; adjacencyIndex += 2 * bucketLength * 4 * 2; colorIndex += bucketLength * 4 * 2; texCoordExpandWidthAndShowIndex += bucketLength * 4 * 2; @@ -740,7 +740,7 @@ define([ collection._texCoordExpandWidthAndShowBuffer = context.createVertexBuffer(texCoordExpandWidthAndShowArray, texCoordExpandWidthAndShowBufferUsage); var pickColorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; - var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; + var positionSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var texCoordExpandWidthAndShowSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; @@ -764,25 +764,25 @@ define([ var attributes = [{ index : attributeIndices.position3DHigh, - componentsPerAttribute : 3, + componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionHighOffset, strideInBytes : 2 * positionSizeInBytes }, { index : attributeIndices.position3DLow, - componentsPerAttribute : 3, + componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionLowOffset, strideInBytes : 2 * positionSizeInBytes }, { index : attributeIndices.position2DHigh, - componentsPerAttribute : 3, + componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionHighOffset, strideInBytes : 2 * positionSizeInBytes }, { index : attributeIndices.position2DLow, - componentsPerAttribute : 3, + componentsPerAttribute : 4, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionLowOffset, strideInBytes : 2 * positionSizeInBytes @@ -818,11 +818,11 @@ define([ if (mode === SceneMode.SCENE3D) { attributes[0].vertexBuffer = collection._positionBuffer; attributes[1].vertexBuffer = collection._positionBuffer; - attributes[2].value = [0.0, 0.0, 0.0]; - attributes[3].value = [0.0, 0.0, 0.0]; + attributes[2].value = [0.0, 0.0, 0.0, 0.0]; + attributes[3].value = [0.0, 0.0, 0.0, 0.0]; } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { - attributes[0].value = [0.0, 0.0, 0.0]; - attributes[1].value = [0.0, 0.0, 0.0]; + attributes[0].value = [0.0, 0.0, 0.0, 0.0]; + attributes[1].value = [0.0, 0.0, 0.0, 0.0]; attributes[2].vertexBuffer = collection._positionBuffer; attributes[3].vertexBuffer = collection._positionBuffer; } else { @@ -994,11 +994,14 @@ define([ } PolylineBucket.prototype.getPolylinePositionsLength = function(polyline) { + var length; if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { - return polyline.getPositions().length; + length = polyline.getPositions().length; + } else { + length = polyline._segments.positions.length; } - return polyline._segments.positions.length; + return (length > 1.0) ? length * 2.0 - 2.0 : 0.0; }; var computeAdjacencyAnglesPosition = new Cartesian3(); @@ -1007,11 +1010,17 @@ define([ // see // http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap // for details. - function computeAdjacencyAngles(position, index, positions, startSegment, endSegment, result, modelMatrix) { + function computeAdjacencyInfo(position, index, positions, startSegment, endSegment, result, modelMatrix) { if (typeof result === 'undefined') { - result = new Cartesian4(); + result = { + normals : new Cartesian4(), + prevLength : 0.0, + nextLength : 0.0 + }; } + var normals = result.normals; + if (typeof modelMatrix === 'undefined') { modelMatrix = Matrix4.IDENTITY; } @@ -1023,11 +1032,12 @@ define([ prev = Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); Cartesian3.subtract(prev, position, prev); } + result.prevLength = prev.magnitude(); Cartesian3.normalize(prev, prev); var p = Math.sqrt(prev.z * 8.0 + 8.0); - result.x = prev.x / p + 0.5; - result.y = prev.y / p + 0.5; + normals.x = prev.x / p + 0.5; + normals.y = prev.y / p + 0.5; var next = computeAdjacencyAnglesPosition; if (endSegment) { @@ -1036,17 +1046,23 @@ define([ next = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); Cartesian3.subtract(next, position, next); } + result.nextLength = next.magnitude(); Cartesian3.normalize(next, next); p = Math.sqrt(next.z * 8.0 + 8.0); - result.z = next.x / p + 0.5; - result.w = next.y / p + 0.5; + normals.z = next.x / p + 0.5; + normals.w = next.y / p + 0.5; return result; } var scratchWritePosition = new Cartesian3(); - var scratchWriteAdjacency = new Cartesian4(); + var scratchWriteAdjacencyInfo = { + normals : new Cartesian4(), + prevLength : 0.0, + nextLength : 0.0 + }; + var encodedP = new EncodedCartesian3(); PolylineBucket.prototype.write = function(positionArray, adjacencyArray, pickColorArray, texCoordExpandWidthAndShowArray, positionIndex, adjacencyIndex, colorIndex, texCoordExpandWidthAndShowIndex, context) { var mode = this.mode; @@ -1080,21 +1096,41 @@ define([ var segmentStart = j - count === 0; var segmentEnd = j === count + lengths[segmentIndex] - 1; - var adjacencyAngles = computeAdjacencyAngles(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacency); - for (var k = 0; k < 2; ++k) { - EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); + var adjacencyInfo = computeAdjacencyInfo(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacencyInfo); + var adjacencyNormals = adjacencyInfo.normals; + var prevLength = adjacencyInfo.prevLength; + var nextLength = adjacencyInfo.nextLength; + + var startK = (segmentStart) ? 2 : 0; + var endK = (segmentEnd) ? 2 : 4; + + for (var k = startK; k < endK; ++k) { + var lineLength = (k - 2 < 0) ? -prevLength : nextLength; + EncodedCartesian3.fromCartesian(scratchWritePosition, encodedP); + var high = encodedP.high; + var low = encodedP.low; + + positionArray[positionIndex] = high.x; + positionArray[positionIndex + 1] = high.y; + positionArray[positionIndex + 2] = high.z; + positionArray[positionIndex + 3] = 0.0; + + positionArray[positionIndex + 4] = low.x; + positionArray[positionIndex + 5] = low.y; + positionArray[positionIndex + 6] = low.z; + positionArray[positionIndex + 7] = lineLength; if (mode === SceneMode.SCENE3D) { - adjacencyArray[adjacencyIndex] = adjacencyAngles.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + adjacencyArray[adjacencyIndex] = adjacencyNormals.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyNormals.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyNormals.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyNormals.w; } else { - adjacencyArray[adjacencyIndex + 2] = adjacencyAngles.x; - adjacencyArray[adjacencyIndex + 3] = adjacencyAngles.y; - adjacencyArray[adjacencyIndex + 6] = adjacencyAngles.z; - adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; + adjacencyArray[adjacencyIndex + 2] = adjacencyNormals.x; + adjacencyArray[adjacencyIndex + 3] = adjacencyNormals.y; + adjacencyArray[adjacencyIndex + 6] = adjacencyNormals.z; + adjacencyArray[adjacencyIndex + 7] = adjacencyNormals.w; } pickColorArray[colorIndex] = pickColor.red; @@ -1103,11 +1139,11 @@ define([ pickColorArray[colorIndex + 3] = 255; texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex] = j / (positionsLength - 1); // s tex coord - texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * k - 1; // expand direction + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * (k % 2) - 1; // expand direction texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 2] = width; texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 3] = show; - positionIndex += 6; + positionIndex += 8; adjacencyIndex += 8; colorIndex += 4; texCoordExpandWidthAndShowIndex += 4; @@ -1142,17 +1178,37 @@ define([ var segmentStart = j - count === 0; var segmentEnd = j === count + lengths[segmentIndex] - 1; - var adjacencyAngles = computeAdjacencyAngles(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacency); - for (var k = 0; k < 2; ++k) { - EncodedCartesian3.writeElements(position, positionArray, positionIndex); + var adjacencyInfo = computeAdjacencyInfo(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacencyInfo); + var adjacencyNormals = adjacencyInfo.normals; + var prevLength = adjacencyInfo.prevLength; + var nextLength = adjacencyInfo.nextLength; + + var startK = (segmentStart) ? 2 : 0; + var endK = (segmentEnd) ? 2 : 4; + + for (var k = startK; k < endK; ++k) { + var lineLength = (k - 2 < 0) ? -prevLength : nextLength; + EncodedCartesian3.fromCartesian(scratchWritePosition, encodedP); + var high = encodedP.high; + var low = encodedP.low; - adjacencyArray[adjacencyIndex] = adjacencyAngles.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + positionArray[positionIndex] = high.x; + positionArray[positionIndex + 1] = high.y; + positionArray[positionIndex + 2] = high.z; + positionArray[positionIndex + 3] = 0.0; - positionIndex += 6; + positionArray[positionIndex + 4] = low.x; + positionArray[positionIndex + 5] = low.y; + positionArray[positionIndex + 6] = low.z; + positionArray[positionIndex + 7] = lineLength; + + adjacencyArray[adjacencyIndex] = adjacencyNormals.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyNormals.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyNormals.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyNormals.w; + + positionIndex += 8; adjacencyIndex += 8; } } @@ -1195,37 +1251,32 @@ define([ if (numberOfSegments > 0) { var segmentIndexCount = 0; for ( var j = 0; j < numberOfSegments; ++j) { - var segmentLength = segments[j]; + var segmentLength = segments[j] - 1.0; for ( var k = 0; k < segmentLength; ++k) { - if (k !== segmentLength - 1) { - if (indicesCount + 3 >= SIXTYFOURK - 1) { - polyline._locatorBuckets.push({ - locator : bucketLocator, - count : segmentIndexCount - }); - segmentIndexCount = 0; - vertexBufferOffset.push(4); - indices = []; - totalIndices.push(indices); - indicesCount = 0; - bucketLocator.count = count; - count = 0; - offset = 0; - bucketLocator = new VertexArrayBucketLocator(0, 0, this); - vertexArrayBuckets[++vaCount] = [bucketLocator]; - } + if (indicesCount + 4 >= SIXTYFOURK - 1) { + polyline._locatorBuckets.push({ + locator : bucketLocator, + count : segmentIndexCount + }); + segmentIndexCount = 0; + vertexBufferOffset.push(4); + indices = []; + totalIndices.push(indices); + indicesCount = 0; + bucketLocator.count = count; + count = 0; + offset = 0; + bucketLocator = new VertexArrayBucketLocator(0, 0, this); + vertexArrayBuckets[++vaCount] = [bucketLocator]; + } - indices.push(indicesCount, indicesCount + 2, indicesCount + 1); - indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); + indices.push(indicesCount, indicesCount + 2, indicesCount + 1); + indices.push(indicesCount + 1, indicesCount + 2, indicesCount + 3); - segmentIndexCount += 6; - count += 6; - offset += 6; - indicesCount += 2; - } - } - if (j !== numberOfSegments - 1) { - indicesCount += 2; + segmentIndexCount += 6; + count += 6; + offset += 6; + indicesCount += 4; } } @@ -1234,9 +1285,7 @@ define([ count : segmentIndexCount }); - if (indicesCount + 3 < SIXTYFOURK - 1) { - indicesCount += 2; - } else { + if (indicesCount + 4 >= SIXTYFOURK - 1) { vertexBufferOffset.push(0); indices = []; totalIndices.push(indices); @@ -1326,15 +1375,12 @@ define([ return scratchSegments; }; - - var scratchAdjacency = new Cartesian4(); - PolylineBucket.prototype.writePositionsUpdate = function(positionIndex, polyline, positionBuffer, adjacencyBuffer) { var mode = this.mode; var positionsLength = polyline._actualLength; if (positionsLength) { positionIndex += this.getPolylineStartIndex(polyline); - var positionArray = new Float32Array(2 * positionsLength * 3 * 2); + var positionArray = new Float32Array(2 * positionsLength * 4 * 2); var adjacencyArray = new Float32Array(2 * positionsLength * 4 * 2); var index = 0; @@ -1361,29 +1407,49 @@ define([ var segmentStart = i - count === 0; var segmentEnd = i === count + lengths[segmentIndex] - 1; - var adjacencyAngles = computeAdjacencyAngles(position, i, positions, segmentStart, segmentEnd, scratchAdjacency); - for (var j = 0; j < 2; ++j) { - EncodedCartesian3.writeElements(scratchWritePosition, positionArray, index); + var adjacencyInfo = computeAdjacencyInfo(position, i, positions, segmentStart, segmentEnd, scratchWriteAdjacencyInfo); + var adjacencyNormals = adjacencyInfo.normals; + var prevLength = adjacencyInfo.prevLength; + var nextLength = adjacencyInfo.nextLength; + + var startJ = (segmentStart) ? 2 : 0; + var endJ = (segmentEnd) ? 2 : 4; + + for (var j = startJ; j < endJ; ++j) { + var lineLength = (j - 2 < 0) ? -prevLength : nextLength; + EncodedCartesian3.fromCartesian(scratchWritePosition, encodedP); + var high = encodedP.high; + var low = encodedP.low; + + positionArray[index] = high.x; + positionArray[index + 1] = high.y; + positionArray[index + 2] = high.z; + positionArray[index + 3] = 0.0; + + positionArray[index + 4] = low.x; + positionArray[index + 5] = low.y; + positionArray[index + 6] = low.z; + positionArray[index + 7] = lineLength; if (mode === SceneMode.SCENE3D) { - adjacencyArray[adjacencyIndex] = adjacencyAngles.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyAngles.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyAngles.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyAngles.w; + adjacencyArray[adjacencyIndex] = adjacencyNormals.x; + adjacencyArray[adjacencyIndex + 1] = adjacencyNormals.y; + adjacencyArray[adjacencyIndex + 4] = adjacencyNormals.z; + adjacencyArray[adjacencyIndex + 5] = adjacencyNormals.w; } else { - adjacencyArray[adjacencyIndex + 2] = adjacencyAngles.x; - adjacencyArray[adjacencyIndex + 3] = adjacencyAngles.y; - adjacencyArray[adjacencyIndex + 6] = adjacencyAngles.z; - adjacencyArray[adjacencyIndex + 7] = adjacencyAngles.w; + adjacencyArray[adjacencyIndex + 2] = adjacencyNormals.x; + adjacencyArray[adjacencyIndex + 3] = adjacencyNormals.y; + adjacencyArray[adjacencyIndex + 6] = adjacencyNormals.z; + adjacencyArray[adjacencyIndex + 7] = adjacencyNormals.w; } - index += 6; + index += 8; adjacencyIndex += 8; } } - positionBuffer.copyFromArrayView(positionArray, 2 * 3 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); + positionBuffer.copyFromArrayView(positionArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); adjacencyBuffer.copyFromArrayView(adjacencyArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); } }; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index eab27b12ba82..fbb94a31231b 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -1,7 +1,7 @@ -attribute vec3 position3DHigh; -attribute vec3 position3DLow; -attribute vec3 position2DHigh; -attribute vec3 position2DLow; +attribute vec4 position3DHigh; +attribute vec4 position3DLow; +attribute vec4 position2DHigh; +attribute vec4 position2DLow; attribute vec4 prev; attribute vec4 next; attribute vec4 texCoordExpandWidthAndShow; @@ -45,7 +45,7 @@ void main() if (u_morphTime == 1.0) { - p = vec4(czm_translateRelativeToEye(position3DHigh, position3DLow), 1.0); + p = vec4(czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz), 1.0); prevDir = vec4(decode(prev.xy), 0.0); nextDir = vec4(decode(next.xy), 0.0); } @@ -59,7 +59,7 @@ void main() { p = czm_columbusViewMorph( czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), - czm_translateRelativeToEye(position3DHigh, position3DLow), + czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz), u_morphTime); prevDir = czm_columbusViewMorph(decode(prev.xy), decode(prev.zw), u_morphTime); From f95b2608b16cd8f08761516881c3e21d71bba3cb Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 4 Apr 2013 15:40:14 -0400 Subject: [PATCH 100/114] Modify polyline vertex shader to clip line segments to the near plane. --- Source/Renderer/ShaderProgram.js | 39 ++++++++++- Source/Renderer/UniformState.js | 20 ++++++ Source/Scene/PolylineCollection.js | 1 + Source/Scene/Scene.js | 1 - Source/Shaders/PolylineVS.glsl | 100 +++++++++++++++++++++++------ 5 files changed, 141 insertions(+), 20 deletions(-) diff --git a/Source/Renderer/ShaderProgram.js b/Source/Renderer/ShaderProgram.js index 69564549b082..14be9559dfb2 100644 --- a/Source/Renderer/ShaderProgram.js +++ b/Source/Renderer/ShaderProgram.js @@ -1191,7 +1191,7 @@ define([ /** * An automatic GLSL uniform containing the near distance (x) and the far distance (y) * of the frustum defined by the camera. This is the largest possible frustum, not an individual - * frustum used for mult-frustum rendering. + * frustum used for multi-frustum rendering. *

      * Like all automatic uniforms, czm_entireFrustum does not need to be explicitly declared. * However, it can be explicitly declared when a shader is also used by other applications such @@ -1201,6 +1201,7 @@ define([ * @glslUniform * * @see UniformState#getEntireFrustum + * @see czm_currentFrustum * * @example * // GLSL declaration @@ -1223,6 +1224,42 @@ define([ } }, + /** + * An automatic GLSL uniform containing the near distance (x) and the far distance (y) + * of the frustum defined by the camera. This is the individual + * frustum used for multi-frustum rendering. + *

      + * Like all automatic uniforms, czm_currentFrustum does not need to be explicitly declared. + * However, it can be explicitly declared when a shader is also used by other applications such + * as a third-party authoring tool. + * + * @alias czm_currentFrustum + * @glslUniform + * + * @see UniformState#getCurrentFrustum + * @see czm_entireFrustum + * + * @example + * // GLSL declaration + * uniform vec2 czm_currentFrustum; + * + * // Example + * float frustumLength = czm_currentFrustum.y - czm_currentFrustum.x; + */ + czm_currentFrustum : { + getSize : function() { + return 1; + }, + + getDatatype : function() { + return UniformDatatype.FLOAT_VECTOR2; + }, + + getValue : function(uniformState) { + return uniformState.getCurrentFrustum(); + } + }, + /** * An automatic GLSL uniform representing the size of a pixel in meters at a distance of one meter * from the camera. The pixel size is linearly proportional to the distance from the camera. diff --git a/Source/Renderer/UniformState.js b/Source/Renderer/UniformState.js index 6b1b63d0ee23..7f87635968bd 100644 --- a/Source/Renderer/UniformState.js +++ b/Source/Renderer/UniformState.js @@ -52,6 +52,7 @@ define([ this._projection = Matrix4.IDENTITY.clone(); this._infiniteProjection = Matrix4.IDENTITY.clone(); this._entireFrustum = new Cartesian2(); + this._currentFrustum = new Cartesian2(); this._pixelSize = 0.0; this._frameNumber = 1.0; @@ -209,6 +210,8 @@ define([ if (typeof frustum.getInfiniteProjectionMatrix !== 'undefined') { setInfiniteProjection(this, frustum.getInfiniteProjectionMatrix()); } + this._currentFrustum.x = frustum.near; + this._currentFrustum.y = frustum.far; }; /** @@ -877,17 +880,34 @@ define([ /** * Returns the near distance (x) and the far distance (y) of the frustum defined by the camera. + * This is the largest possible frustum, not an individual frustum used for multi-frustum rendering. * * @memberof UniformState * * @return {Cartesian2} Returns the near distance and the far distance of the frustum defined by the camera. * * @see czm_entireFrustum + * @see UniformState#getCurrentFrustum */ UniformState.prototype.getEntireFrustum = function() { return this._entireFrustum; }; + /** + * Returns the near distance (x) and the far distance (y) of the frustum defined by the camera. + * This is the individual frustum used for multi-frustum rendering. + * + * @memberof UniformState + * + * @return {Cartesian2} Returns the near distance and the far distance of the frustum defined by the camera. + * + * @see czm_currentFrustum + * @see UniformState#getEntireFrustum + */ + UniformState.prototype.getCurrentFrustum = function() { + return this._currentFrustum; + }; + /** * Returns the size of a pixel in meters at a distance of one meter from the camera. * diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index cb3a1e19e5c0..e067d2c5fc15 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1393,6 +1393,7 @@ define([ var segmentIndex = 0; var count = 0; + positionsLength = positions.length; for ( var i = 0; i < positionsLength; ++i) { var position = positions[i]; scratchWritePosition.x = position.x; diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index b92ee7ad91c5..869a38221b3d 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -273,7 +273,6 @@ define([ for (var m = 0; m < numFrustums; ++m) { var curNear = Math.max(near, Math.pow(farToNearRatio, m) * near); var curFar = Math.min(far, farToNearRatio * curNear); - curNear *= 0.99; var frustumCommands = frustumCommandsList[m]; if (typeof frustumCommands === 'undefined') { diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index fbb94a31231b..68edcb652e2b 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -32,28 +32,76 @@ vec3 decode(vec2 enc) return n; } +void clipLineSegmentToNearPlane( + vec3 positionEC, + vec3 directionEC, + float magnitude, + out vec4 positionWC, + out bool clipped, + out bool culledByNearPlane) +{ + culledByNearPlane = false; + clipped = false; + + vec3 normal = vec3(0.0, 0.0, -1.0); + vec3 point = normal * czm_currentFrustum.x; + vec4 plane = vec4(normal, -dot(normal, point)); + + float endPoint0Distance = dot(plane.xyz, positionEC) + plane.w; + float denominator = dot(plane.xyz, directionEC); + + if (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7) + { + culledByNearPlane = true; + } + else if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7) + { + float t = (-plane.w - dot(plane.xyz, positionEC)) / denominator; + if (t >= 0.0 && t <= magnitude) + { + clipped = true; + positionEC = positionEC + t * directionEC; + } + else + { + culledByNearPlane = true; + } + } + + positionWC = czm_eyeToWindowCoordinates(vec4(positionEC, 1.0)); +} + void main() { float texCoord = texCoordExpandWidthAndShow.x; float expandDir = texCoordExpandWidthAndShow.y; - float width = texCoordExpandWidthAndShow.z; + float width = texCoordExpandWidthAndShow.z + 0.5; float show = texCoordExpandWidthAndShow.w; vec4 p; vec4 prevDir; vec4 nextDir; + + float segmentMagnitude; + bool usePrevDirection; if (u_morphTime == 1.0) { p = vec4(czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz), 1.0); prevDir = vec4(decode(prev.xy), 0.0); nextDir = vec4(decode(next.xy), 0.0); + + segmentMagnitude = abs(position3DLow.w); + usePrevDirection = position3DLow.w < 0.0; } else if (u_morphTime == 0.0) { p = vec4(czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), 1.0); prevDir = vec4(decode(prev.zw).zxy, 0.0); nextDir = vec4(decode(next.zw).zxy, 0.0); + + segmentMagnitude = abs(position2DLow.w); + usePrevDirection = position2DLow.w < 0.0; } else { @@ -66,35 +114,59 @@ void main() nextDir = czm_columbusViewMorph(decode(next.xy), decode(next.zw), u_morphTime); prevDir.w = 0.0; nextDir.w = 0.0; + + segmentMagnitude = abs(position2DLow.w); + usePrevDirection = position2DLow.w < 0.0; } + vec4 endPointWC; + bool clipped; + bool culledByNearPlane; + vec4 positionEC = czm_modelViewRelativeToEye * p; - vec4 endPointWC = czm_eyeToWindowCoordinates(positionEC); + vec4 nextEC = czm_modelView * nextDir; + vec4 prevEC = czm_modelView * prevDir; + vec3 segmentDirection = (usePrevDirection) ? prevEC.xyz : nextEC.xyz; + + clipLineSegmentToNearPlane(positionEC.xyz, segmentDirection, segmentMagnitude, endPointWC, clipped, culledByNearPlane); + + if (culledByNearPlane) + { + gl_Position = czm_projection * vec4(0.0, 0.0, 0.0, 1.0); + return; + } + + if (clipped) + { + if (usePrevDirection) + { + nextDir = vec4(0.0); + } + else + { + prevDir = vec4(0.0); + } + } float pixelSize = czm_pixelSizeInMeters * abs(positionEC.z); float expandWidth = width * 0.5; - vec4 prevEC, nextEC, p0, p1; + vec4 p0, p1; vec2 direction, nextWC, prevWC; if (czm_equalsEpsilon(prevDir, vec4(0.0), czm_epsilon7)) { - nextEC = czm_modelView * nextDir; p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); nextWC = normalize(p1.xy - endPointWC.xy); direction = normalize(vec2(-nextWC.y, nextWC.x)); } else if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7) || czm_equalsEpsilon(nextDir, -prevDir, czm_epsilon1)) { - prevEC = czm_modelView * prevDir; p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); prevWC = normalize(p0.xy - endPointWC.xy); direction = normalize(vec2(prevWC.y, -prevWC.x)); } else { - prevEC = czm_modelView * prevDir; - nextEC = czm_modelView * nextDir; - p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); @@ -119,16 +191,8 @@ void main() expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0); } - vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, endPointWC.zw); - - vec4 position; - position.x = 2.0 * (positionWC.x - czm_viewport.x) / czm_viewport.z - 1.0; - position.y = 2.0 * (positionWC.y - czm_viewport.y) / czm_viewport.w - 1.0; - position.z = (positionWC.z - czm_viewportTransformation[3][2]) / czm_viewportTransformation[2][2]; - position.w = 1.0; - position /= positionWC.w; - - gl_Position = position * show; + vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, -endPointWC.z, 1.0); + gl_Position = czm_viewportOrthographic * positionWC * show; #ifndef RENDER_FOR_PICK v_textureCoordinates = vec2(texCoord, clamp(expandDir, 0.0, 1.0)); From 1601a317e70c4364de1a2d38bcd219ccb139c23a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 5 Apr 2013 13:41:31 -0400 Subject: [PATCH 101/114] Fix multi-frustum polyline issue. --- Source/Shaders/PolylineVS.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 68edcb652e2b..4bc85716cdd2 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -140,11 +140,11 @@ void main() { if (usePrevDirection) { - nextDir = vec4(0.0); + prevDir = vec4(0.0); } else { - prevDir = vec4(0.0); + nextDir = vec4(0.0); } } From 76dfac091a4dc8005575924748f70d78000c83a0 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 5 Apr 2013 15:33:36 -0400 Subject: [PATCH 102/114] Fix clipping at last end point. --- Source/Scene/PolylineCollection.js | 12 ++++++++---- Source/Shaders/PolylineVS.glsl | 14 +++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index e067d2c5fc15..f81e12d06502 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1028,12 +1028,14 @@ define([ var prev = computeAdjacencyAnglesPosition; if (startSegment) { Cartesian3.ZERO.clone(prev); + result.prevLength = 0.0; } else { prev = Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); Cartesian3.subtract(prev, position, prev); + + result.prevLength = prev.magnitude(); + Cartesian3.normalize(prev, prev); } - result.prevLength = prev.magnitude(); - Cartesian3.normalize(prev, prev); var p = Math.sqrt(prev.z * 8.0 + 8.0); normals.x = prev.x / p + 0.5; @@ -1042,12 +1044,14 @@ define([ var next = computeAdjacencyAnglesPosition; if (endSegment) { Cartesian3.ZERO.clone(next); + result.nextLength = 0.0; } else { next = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); Cartesian3.subtract(next, position, next); + + result.nextLength = next.magnitude(); + Cartesian3.normalize(next, next); } - result.nextLength = next.magnitude(); - Cartesian3.normalize(next, next); p = Math.sqrt(next.z * 8.0 + 8.0); normals.z = next.x / p + 0.5; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 4bc85716cdd2..522374f8d6f8 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -57,14 +57,14 @@ void clipLineSegmentToNearPlane( else if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7) { float t = (-plane.w - dot(plane.xyz, positionEC)) / denominator; - if (t >= 0.0 && t <= magnitude) + if (t < 0.0 || t > magnitude) { - clipped = true; - positionEC = positionEC + t * directionEC; + culledByNearPlane = true; } else { - culledByNearPlane = true; + clipped = true; + positionEC = positionEC + t * directionEC; } } @@ -124,8 +124,8 @@ void main() bool culledByNearPlane; vec4 positionEC = czm_modelViewRelativeToEye * p; - vec4 nextEC = czm_modelView * nextDir; - vec4 prevEC = czm_modelView * prevDir; + vec4 nextEC = vec4(normalize((czm_modelView * nextDir).xyz), 0.0); + vec4 prevEC = vec4(normalize((czm_modelView * prevDir).xyz), 0.0); vec3 segmentDirection = (usePrevDirection) ? prevEC.xyz : nextEC.xyz; clipLineSegmentToNearPlane(positionEC.xyz, segmentDirection, segmentMagnitude, endPointWC, clipped, culledByNearPlane); @@ -136,7 +136,7 @@ void main() return; } - if (clipped) + if (clipped) { if (usePrevDirection) { From b8f9da675d177d0fc9019ea8e572ed6faaa5dde5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 5 Apr 2013 16:20:00 -0400 Subject: [PATCH 103/114] Fix expand direction when clipping. --- Source/Scene/PolylineCollection.js | 7 +++++-- Source/Shaders/PolylineVS.glsl | 27 +++++++++++++++------------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index f81e12d06502..8b3dfdaf6dbe 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1027,7 +1027,10 @@ define([ var prev = computeAdjacencyAnglesPosition; if (startSegment) { - Cartesian3.ZERO.clone(prev); + prev = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], prev); + Cartesian3.subtract(prev, position, prev); + Cartesian3.normalize(prev, prev); + Cartesian3.negate(prev, prev); result.prevLength = 0.0; } else { prev = Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); @@ -1043,7 +1046,7 @@ define([ var next = computeAdjacencyAnglesPosition; if (endSegment) { - Cartesian3.ZERO.clone(next); + Cartesian3.negate(prev, next); result.nextLength = 0.0; } else { next = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 522374f8d6f8..0d7038ffff65 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -140,11 +140,11 @@ void main() { if (usePrevDirection) { - prevDir = vec4(0.0); + nextDir = -prevDir; } else { - nextDir = vec4(0.0); + prevDir = -nextDir; } } @@ -153,17 +153,20 @@ void main() vec4 p0, p1; vec2 direction, nextWC, prevWC; - if (czm_equalsEpsilon(prevDir, vec4(0.0), czm_epsilon7)) + if (czm_equalsEpsilon(prevDir, -nextDir, czm_epsilon7)) { - p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); - nextWC = normalize(p1.xy - endPointWC.xy); - direction = normalize(vec2(-nextWC.y, nextWC.x)); - } - else if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7) || czm_equalsEpsilon(nextDir, -prevDir, czm_epsilon1)) - { - p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); - prevWC = normalize(p0.xy - endPointWC.xy); - direction = normalize(vec2(prevWC.y, -prevWC.x)); + if (usePrevDirection || !clipped) + { + p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); + nextWC = normalize(p1.xy - endPointWC.xy); + direction = normalize(vec2(-nextWC.y, nextWC.x)); + } + else + { + p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); + prevWC = normalize(p0.xy - endPointWC.xy); + direction = normalize(vec2(prevWC.y, -prevWC.x)); + } } else { From 87e01efb4b59df54897afaac448fdbf7d5909842 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 5 Apr 2013 19:48:07 -0400 Subject: [PATCH 104/114] Simplify the polyline vertex shader. --- Source/Shaders/PolylineVS.glsl | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 0d7038ffff65..d8c8f06ea6ed 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -43,12 +43,8 @@ void clipLineSegmentToNearPlane( culledByNearPlane = false; clipped = false; - vec3 normal = vec3(0.0, 0.0, -1.0); - vec3 point = normal * czm_currentFrustum.x; - vec4 plane = vec4(normal, -dot(normal, point)); - - float endPoint0Distance = dot(plane.xyz, positionEC) + plane.w; - float denominator = dot(plane.xyz, directionEC); + float endPoint0Distance = -(czm_currentFrustum.x + positionEC.z); + float denominator = -directionEC.z; if (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7) { @@ -56,7 +52,8 @@ void clipLineSegmentToNearPlane( } else if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7) { - float t = (-plane.w - dot(plane.xyz, positionEC)) / denominator; + // t = (-plane distance - dot(plane normal, ray origin)) / dot(plane normal, ray direction) + float t = (czm_currentFrustum.x + positionEC.z) / denominator; if (t < 0.0 || t > magnitude) { culledByNearPlane = true; @@ -138,14 +135,7 @@ void main() if (clipped) { - if (usePrevDirection) - { - nextDir = -prevDir; - } - else - { - prevDir = -nextDir; - } + prevDir = -nextDir; } float pixelSize = czm_pixelSizeInMeters * abs(positionEC.z); @@ -153,7 +143,7 @@ void main() vec4 p0, p1; vec2 direction, nextWC, prevWC; - if (czm_equalsEpsilon(prevDir, -nextDir, czm_epsilon7)) + if (czm_equalsEpsilon(prevDir, -nextDir, czm_epsilon3)) { if (usePrevDirection || !clipped) { From 5bce46d7d9c531741b94fda42785c910de9b7615 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 8 Apr 2013 14:49:34 -0400 Subject: [PATCH 105/114] Fix segment lengths in 2D/Columbus view that where off by two at the segment end points. --- Source/Scene/Polyline.js | 3 ++- Source/Scene/PolylineCollection.js | 42 +++++++++++++++++------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 82a76a4eb470..91a79c1b1784 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -180,13 +180,14 @@ define([ var length = this._segments.positions.length; var segmentLengths = this._segments.lengths; - this._modelMatrix = modelMatrix; var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; if (!modelMatrix.equals(this._modelMatrix) || positionsChanged) { this._segments = PolylinePipeline.wrapLongitude(this._positions, modelMatrix); } + this._modelMatrix = modelMatrix; + if (this._segments.positions.length !== length) { // number of positions changed makeDirty(this, POSITION_SIZE_INDEX); diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 8b3dfdaf6dbe..af61362becf9 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -694,10 +694,10 @@ define([ if (totalLength > 0) { var mode = collection._mode; - var positionArray = new Float32Array(2 * totalLength * 4 * 2); - var adjacencyArray = new Float32Array(2 * totalLength * 4 * 2); - var pickColorArray = new Uint8Array(totalLength * 4 * 2); - var texCoordExpandWidthAndShowArray = new Float32Array(totalLength * 4 * 2); + var positionArray = new Float32Array(2 * totalLength * 4); + var adjacencyArray = new Float32Array(2 * totalLength * 4); + var pickColorArray = new Uint8Array(totalLength * 4); + var texCoordExpandWidthAndShowArray = new Float32Array(totalLength * 4); var position3DArray; var positionIndex = 0; @@ -711,16 +711,16 @@ define([ if (mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { - position3DArray = new Float32Array(2 * totalLength * 4 * 2); + position3DArray = new Float32Array(2 * totalLength * 4); } bucket.writeForMorph(position3DArray, adjacencyArray, positionIndex, adjacencyIndex); } var bucketLength = bucket.lengthOfPositions; - positionIndex += 2 * bucketLength * 4 * 2; - adjacencyIndex += 2 * bucketLength * 4 * 2; - colorIndex += bucketLength * 4 * 2; - texCoordExpandWidthAndShowIndex += bucketLength * 4 * 2; + positionIndex += 2 * bucketLength * 4; + adjacencyIndex += 2 * bucketLength * 4; + colorIndex += bucketLength * 4; + texCoordExpandWidthAndShowIndex += bucketLength * 4; offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); } } @@ -997,11 +997,17 @@ define([ var length; if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { length = polyline.getPositions().length; - } else { - length = polyline._segments.positions.length; + return (length > 1.0) ? length * 4.0 - 4.0 : 0.0; + } + + var count = 0; + var segmentLengths = polyline._segments.lengths; + length = segmentLengths.length; + for (var i = 0; i < length; ++i) { + count += segmentLengths[i] * 4.0 - 4.0; } - return (length > 1.0) ? length * 2.0 - 2.0 : 0.0; + return count; }; var computeAdjacencyAnglesPosition = new Cartesian3(); @@ -1387,8 +1393,8 @@ define([ var positionsLength = polyline._actualLength; if (positionsLength) { positionIndex += this.getPolylineStartIndex(polyline); - var positionArray = new Float32Array(2 * positionsLength * 4 * 2); - var adjacencyArray = new Float32Array(2 * positionsLength * 4 * 2); + var positionArray = new Float32Array(2 * positionsLength * 4); + var adjacencyArray = new Float32Array(2 * positionsLength * 4); var index = 0; var adjacencyIndex = 0; @@ -1457,8 +1463,8 @@ define([ } } - positionBuffer.copyFromArrayView(positionArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); - adjacencyBuffer.copyFromArrayView(adjacencyArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); + positionBuffer.copyFromArrayView(positionArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex); + adjacencyBuffer.copyFromArrayView(adjacencyArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex); } }; @@ -1468,7 +1474,7 @@ define([ positionIndex += this.getPolylineStartIndex(polyline); var show = polyline.getShow(); var width = polyline.getWidth(); - var texCoordExpandWidthAndShowArray = new Float32Array(4 * positionsLength * 2); + var texCoordExpandWidthAndShowArray = new Float32Array(4 * positionsLength); var texCoordExpandWidthAndShowIndex = 0; for ( var j = 0; j < positionsLength; ++j) { for (var k = 0; k < 2; ++k) { @@ -1480,7 +1486,7 @@ define([ texCoordExpandWidthAndShowIndex += 4; } } - buffer.copyFromArrayView(texCoordExpandWidthAndShowArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex * 2); + buffer.copyFromArrayView(texCoordExpandWidthAndShowArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex); } }; From 90add054efbffb9997c67bd900a984cecf639731 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Apr 2013 15:52:14 -0400 Subject: [PATCH 106/114] Subdivide polylines. --- Source/Scene/Polyline.js | 40 +++++++++++++++++++++++++++--- Source/Scene/PolylineCollection.js | 6 ++--- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 91a79c1b1784..a13198a95871 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -47,6 +47,7 @@ define([ } this._positions = positions; + this._computedPositions = computePositions(positions); var modelMatrix; if (typeof this._polylineCollection !== 'undefined') { @@ -169,6 +170,35 @@ define([ this.update(); }; + var granularity = (Math.PI / 360.0) * 6378137.0; + + function computePositions(positions) { + if (typeof positions === 'undefined' || positions.length === 0) { + return []; + } + + var computedPositions = [Cartesian3.clone(positions[0])]; + + var length = positions.length; + for (var i = 1; i < length; ++i) { + var p0 = positions[i - 1]; + var p1 = positions[i]; + + var segmentLength = Cartesian3.subtract(p0, p1).magnitude(); + if (segmentLength > granularity) { + var numPoints = Math.floor(segmentLength / granularity); + for (var j = 1.0; j < numPoints; ++j) { + var t = j / numPoints; + computedPositions.push(Cartesian3.lerp(p0, p1, t)); + } + } + + computedPositions.push(Cartesian3.clone(p1)); + } + + return computedPositions; + } + /** * @private */ @@ -178,21 +208,23 @@ define([ modelMatrix = this._polylineCollection.modelMatrix; } - var length = this._segments.positions.length; + var segmentPositionsLength = this._segments.positions.length; + var computedPositionsLength = this._computedPositions.length; var segmentLengths = this._segments.lengths; var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; if (!modelMatrix.equals(this._modelMatrix) || positionsChanged) { - this._segments = PolylinePipeline.wrapLongitude(this._positions, modelMatrix); + this._computedPositions = computePositions(this._positions); + this._segments = PolylinePipeline.wrapLongitude(this._computedPositions, modelMatrix); } this._modelMatrix = modelMatrix; - if (this._segments.positions.length !== length) { + if (this._segments.positions.length !== segmentPositionsLength || this._computedPositions.length !== computedPositionsLength) { // number of positions changed makeDirty(this, POSITION_SIZE_INDEX); } else { - length = segmentLengths.length; + var length = segmentLengths.length; for (var i = 0; i < length; ++i) { if (segmentLengths[i] !== this._segments.lengths[i]) { // indices changed diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index af61362becf9..1dd416ee3fba 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -996,7 +996,7 @@ define([ PolylineBucket.prototype.getPolylinePositionsLength = function(polyline) { var length; if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { - length = polyline.getPositions().length; + length = polyline._computedPositions.length; return (length > 1.0) ? length * 4.0 - 4.0 : 0.0; } @@ -1250,7 +1250,7 @@ define([ var segments; if (this.mode === SceneMode.SCENE3D) { segments = scratchSegmentLengths; - var positionsLength = polyline.getPositions().length; + var positionsLength = polyline._computedPositions.length; if (positionsLength > 0) { segments[0] = positionsLength; } else { @@ -1337,7 +1337,7 @@ define([ var scratchLengths = new Array(1); PolylineBucket.prototype.getSegments = function(polyline) { - var positions = polyline.getPositions(); + var positions = polyline._computedPositions; if (positions.length > 0) { if (typeof polyline._polylineCollection._boundingVolume === 'undefined') { From b6f91e4b6c9f16c785aa4ba27710d49ecbc993d4 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Apr 2013 17:57:14 -0400 Subject: [PATCH 107/114] Add adjacent polyline positions as vertex attributes. --- Source/DynamicScene/DynamicPathVisualizer.js | 2 - .../DynamicScene/DynamicPolylineVisualizer.js | 2 - Source/Scene/Polyline.js | 36 +- Source/Scene/PolylineCollection.js | 436 ++++++++---------- Source/Shaders/PolylineVS.glsl | 95 ++-- 5 files changed, 238 insertions(+), 333 deletions(-) diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 98339f49d491..a2a023281af5 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -47,8 +47,6 @@ define([ } }; - var cachedColor = new Color(); - var cachedOutlineColor = new Color(); PolylineUpdater.prototype.updateObject = function(time, dynamicObject) { var dynamicPath = dynamicObject.path; if (typeof dynamicPath === 'undefined') { diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index da1f8ba0c4ab..43762692633e 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -170,8 +170,6 @@ define([ }; var cachedPosition = new Cartesian3(); - var cachedColor = new Color(); - var cachedOutlineColor = new Color(); DynamicPolylineVisualizer.prototype._updateObject = function(time, dynamicObject) { var dynamicPolyline = dynamicObject.polyline; if (typeof dynamicPolyline === 'undefined') { diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 344dd166a327..40346f109c80 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -49,7 +49,6 @@ define([ } this._positions = positions; - this._computedPositions = computePositions(positions); var modelMatrix; if (typeof this._polylineCollection !== 'undefined') { @@ -172,35 +171,6 @@ define([ this.update(); }; - var granularity = (Math.PI / 360.0) * 6378137.0; - - function computePositions(positions) { - if (typeof positions === 'undefined' || positions.length === 0) { - return []; - } - - var computedPositions = [Cartesian3.clone(positions[0])]; - - var length = positions.length; - for (var i = 1; i < length; ++i) { - var p0 = positions[i - 1]; - var p1 = positions[i]; - - var segmentLength = Cartesian3.subtract(p0, p1).magnitude(); - if (segmentLength > granularity) { - var numPoints = Math.floor(segmentLength / granularity); - for (var j = 1.0; j < numPoints; ++j) { - var t = j / numPoints; - computedPositions.push(Cartesian3.lerp(p0, p1, t)); - } - } - - computedPositions.push(Cartesian3.clone(p1)); - } - - return computedPositions; - } - /** * @private */ @@ -211,18 +181,16 @@ define([ } var segmentPositionsLength = this._segments.positions.length; - var computedPositionsLength = this._computedPositions.length; var segmentLengths = this._segments.lengths; var positionsChanged = this._propertiesChanged[POSITION_INDEX] > 0 || this._propertiesChanged[POSITION_SIZE_INDEX] > 0; if (!modelMatrix.equals(this._modelMatrix) || positionsChanged) { - this._computedPositions = computePositions(this._positions); - this._segments = PolylinePipeline.wrapLongitude(this._computedPositions, modelMatrix); + this._segments = PolylinePipeline.wrapLongitude(this._positions, modelMatrix); } this._modelMatrix = modelMatrix; - if (this._segments.positions.length !== segmentPositionsLength || this._computedPositions.length !== computedPositionsLength) { + if (this._segments.positions.length !== segmentPositionsLength) { // number of positions changed makeDirty(this, POSITION_SIZE_INDEX); } else { diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 0066dd95736b..0c4564c8e490 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -64,10 +64,16 @@ define([ position3DLow : 1, position2DHigh : 2, position2DLow : 3, - prev : 4, - next : 5, - texCoordExpandWidthAndShow : 6, - pickColor : 7 + prevPosition3DHigh : 4, + prevPosition3DLow : 5, + prevPosition2DHigh : 6, + prevPosition2DLow : 7, + nextPosition3DHigh : 8, + nextPosition3DLow : 9, + nextPosition2DHigh : 10, + nextPosition2DLow : 11, + texCoordExpandWidthAndShow : 12, + pickColor : 13 }; /** @@ -176,7 +182,6 @@ define([ this._polylinesToUpdate = []; this._vertexArrays = []; this._positionBuffer = undefined; - this._adjacencyBuffer = undefined; this._pickColorBuffer = undefined; this._texCoordExpandWidthAndShowBuffer = undefined; }; @@ -382,6 +387,11 @@ define([ */ PolylineCollection.prototype.update = function(context, frameState, commandList) { removePolylines(this); + + if (this._polylines.length === 0) { + return; + } + updateMode(this, frameState); var polyline; @@ -415,11 +425,8 @@ define([ for ( var x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { if (polylineBuckets[x] === bucket) { - if (properties[POSITION_INDEX]) { - bucket.writePositionsUpdate(index, polyline, this._positionBuffer, this._adjacencyBuffer); - } - if (properties[SHOW_INDEX] || properties[WIDTH_INDEX]) { - bucket.writeTexCoordExpandWidthAndShowUpdate(index, polyline, this._texCoordExpandWidthAndShowBuffer); + if (properties[POSITION_INDEX] || properties[SHOW_INDEX] || properties[WIDTH_INDEX]) { + bucket.writePositionsUpdate(index, polyline, this._positionBuffer, this._texCoordExpandWidthAndShowBuffer); } break; } @@ -664,6 +671,8 @@ define([ return usageChanged; } + var emptyVertexBuffer = [0.0, 0.0, 0.0]; + function createVertexArrays(collection, context) { collection._createVertexArray = false; releaseShaders(collection); @@ -696,31 +705,28 @@ define([ if (totalLength > 0) { var mode = collection._mode; - var positionArray = new Float32Array(2 * totalLength * 4); - var adjacencyArray = new Float32Array(2 * totalLength * 4); + var positionArray = new Float32Array(6 * totalLength * 3); var pickColorArray = new Uint8Array(totalLength * 4); var texCoordExpandWidthAndShowArray = new Float32Array(totalLength * 4); var position3DArray; var positionIndex = 0; - var adjacencyIndex = 0; var colorIndex = 0; var texCoordExpandWidthAndShowIndex = 0; for (x in polylineBuckets) { if (polylineBuckets.hasOwnProperty(x)) { bucket = polylineBuckets[x]; - bucket.write(positionArray, adjacencyArray, pickColorArray, texCoordExpandWidthAndShowArray, positionIndex, adjacencyIndex, colorIndex, texCoordExpandWidthAndShowIndex, context); + bucket.write(positionArray, pickColorArray, texCoordExpandWidthAndShowArray, positionIndex, colorIndex, texCoordExpandWidthAndShowIndex, context); if (mode === SceneMode.MORPHING) { if (typeof position3DArray === 'undefined') { - position3DArray = new Float32Array(2 * totalLength * 4); + position3DArray = new Float32Array(6 * totalLength * 3); } - bucket.writeForMorph(position3DArray, adjacencyArray, positionIndex, adjacencyIndex); + bucket.writeForMorph(position3DArray, positionIndex); } var bucketLength = bucket.lengthOfPositions; - positionIndex += 2 * bucketLength * 4; - adjacencyIndex += 2 * bucketLength * 4; + positionIndex += 6 * bucketLength * 3; colorIndex += bucketLength * 4; texCoordExpandWidthAndShowIndex += bucketLength * 4; offset = bucket.updateIndices(totalIndices, vertexBufferOffset, vertexArrayBuckets, offset); @@ -737,13 +743,11 @@ define([ if (typeof position3DArray !== 'undefined') { position3DBuffer = context.createVertexBuffer(position3DArray, positionBufferUsage); } - collection._adjacencyBuffer = context.createVertexBuffer(adjacencyArray, positionBufferUsage); collection._pickColorBuffer = context.createVertexBuffer(pickColorArray, BufferUsage.STATIC_DRAW); collection._texCoordExpandWidthAndShowBuffer = context.createVertexBuffer(texCoordExpandWidthAndShowArray, texCoordExpandWidthAndShowBufferUsage); var pickColorSizeInBytes = 4 * Uint8Array.BYTES_PER_ELEMENT; - var positionSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; - var adjacencySizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; + var positionSizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var texCoordExpandWidthAndShowSizeInBytes = 4 * Float32Array.BYTES_PER_ELEMENT; var vbo = 0; @@ -757,51 +761,87 @@ define([ vbo += vertexBufferOffset[k]; - var positionHighOffset = 2 * (k * (positionSizeInBytes * SIXTYFOURK) - vbo * positionSizeInBytes);//componentsPerAttribute(3) * componentDatatype(4) + var positionHighOffset = 6 * (k * (positionSizeInBytes * SIXTYFOURK) - vbo * positionSizeInBytes);//componentsPerAttribute(3) * componentDatatype(4) var positionLowOffset = positionSizeInBytes + positionHighOffset; - var prevOffset = 2 * (k * (adjacencySizeInBytes * SIXTYFOURK) - vbo * adjacencySizeInBytes); - var nextOffset = adjacencySizeInBytes + prevOffset; + var prevPositionHighOffset = positionSizeInBytes + positionLowOffset; + var prevPositionLowOffset = positionSizeInBytes + prevPositionHighOffset; + var nextPositionHighOffset = positionSizeInBytes + prevPositionLowOffset; + var nextPositionLowOffset = positionSizeInBytes + nextPositionHighOffset; var vertexPickColorBufferOffset = k * (pickColorSizeInBytes * SIXTYFOURK) - vbo * pickColorSizeInBytes; var vertexTexCoordExpandWidthAndShowBufferOffset = k * (texCoordExpandWidthAndShowSizeInBytes * SIXTYFOURK) - vbo * texCoordExpandWidthAndShowSizeInBytes; var attributes = [{ index : attributeIndices.position3DHigh, - componentsPerAttribute : 4, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes + strideInBytes : 6 * positionSizeInBytes }, { index : attributeIndices.position3DLow, - componentsPerAttribute : 4, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes + strideInBytes : 6 * positionSizeInBytes }, { index : attributeIndices.position2DHigh, - componentsPerAttribute : 4, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionHighOffset, - strideInBytes : 2 * positionSizeInBytes + strideInBytes : 6 * positionSizeInBytes }, { index : attributeIndices.position2DLow, - componentsPerAttribute : 4, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, offsetInBytes : positionLowOffset, - strideInBytes : 2 * positionSizeInBytes + strideInBytes : 6 * positionSizeInBytes }, { - index : attributeIndices.prev, - componentsPerAttribute : 4, + index : attributeIndices.prevPosition3DHigh, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : collection._adjacencyBuffer, - offsetInBytes : prevOffset, - strideInBytes : 2 * adjacencySizeInBytes + offsetInBytes : prevPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes }, { - index : attributeIndices.next, - componentsPerAttribute : 4, + index : attributeIndices.prevPosition3DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : prevPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeIndices.prevPosition2DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : prevPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeIndices.prevPosition2DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : prevPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeIndices.nextPosition3DHigh, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : nextPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeIndices.nextPosition3DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : nextPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeIndices.nextPosition2DHigh, + componentsPerAttribute : 3, componentDatatype : ComponentDatatype.FLOAT, - vertexBuffer : collection._adjacencyBuffer, - offsetInBytes : nextOffset, - strideInBytes : 2 * adjacencySizeInBytes + offsetInBytes : nextPositionHighOffset, + strideInBytes : 6 * positionSizeInBytes + }, { + index : attributeIndices.nextPosition2DLow, + componentsPerAttribute : 3, + componentDatatype : ComponentDatatype.FLOAT, + offsetInBytes : nextPositionLowOffset, + strideInBytes : 6 * positionSizeInBytes }, { index : attributeIndices.texCoordExpandWidthAndShow, componentsPerAttribute : 4, @@ -817,23 +857,41 @@ define([ normalize : true }]; + var buffer3D; + var bufferProperty3D; + var buffer2D; + var bufferProperty2D; + if (mode === SceneMode.SCENE3D) { - attributes[0].vertexBuffer = collection._positionBuffer; - attributes[1].vertexBuffer = collection._positionBuffer; - attributes[2].value = [0.0, 0.0, 0.0, 0.0]; - attributes[3].value = [0.0, 0.0, 0.0, 0.0]; + buffer3D = collection._positionBuffer; + bufferProperty3D = 'vertexBuffer'; + buffer2D = emptyVertexBuffer; + bufferProperty2D = 'value'; } else if (mode === SceneMode.SCENE2D || mode === SceneMode.COLUMBUS_VIEW) { - attributes[0].value = [0.0, 0.0, 0.0, 0.0]; - attributes[1].value = [0.0, 0.0, 0.0, 0.0]; - attributes[2].vertexBuffer = collection._positionBuffer; - attributes[3].vertexBuffer = collection._positionBuffer; + buffer3D = emptyVertexBuffer; + bufferProperty3D = 'value'; + buffer2D = collection._positionBuffer; + bufferProperty2D = 'vertexBuffer'; } else { - attributes[0].vertexBuffer = position3DBuffer; - attributes[1].vertexBuffer = position3DBuffer; - attributes[2].vertexBuffer = collection._positionBuffer; - attributes[3].vertexBuffer = collection._positionBuffer; + buffer3D = position3DBuffer; + bufferProperty3D = 'vertexBuffer'; + buffer2D = collection._positionBuffer; + bufferProperty2D = 'vertexBuffer'; } + attributes[0][bufferProperty3D] = buffer3D; + attributes[1][bufferProperty3D] = buffer3D; + attributes[2][bufferProperty2D] = buffer2D; + attributes[3][bufferProperty2D] = buffer2D; + attributes[4][bufferProperty3D] = buffer3D; + attributes[5][bufferProperty3D] = buffer3D; + attributes[6][bufferProperty2D] = buffer2D; + attributes[7][bufferProperty2D] = buffer2D; + attributes[8][bufferProperty3D] = buffer3D; + attributes[9][bufferProperty3D] = buffer3D; + attributes[10][bufferProperty2D] = buffer2D; + attributes[11][bufferProperty2D] = buffer2D; + var va = context.createVertexArray(attributes, indexBuffer); collection._vertexArrays.push({ va : va, @@ -998,7 +1056,7 @@ define([ PolylineBucket.prototype.getPolylinePositionsLength = function(polyline) { var length; if (this.mode === SceneMode.SCENE3D || !intersectsIDL(polyline)) { - length = polyline._computedPositions.length; + length = polyline.getPositions().length; return (length > 1.0) ? length * 4.0 - 4.0 : 0.0; } @@ -1012,74 +1070,11 @@ define([ return count; }; - var computeAdjacencyAnglesPosition = new Cartesian3(); - - // Two normals are packed into a Cartesian4 using a spheremap transform - // see - // http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap - // for details. - function computeAdjacencyInfo(position, index, positions, startSegment, endSegment, result, modelMatrix) { - if (typeof result === 'undefined') { - result = { - normals : new Cartesian4(), - prevLength : 0.0, - nextLength : 0.0 - }; - } - - var normals = result.normals; - - if (typeof modelMatrix === 'undefined') { - modelMatrix = Matrix4.IDENTITY; - } - - var prev = computeAdjacencyAnglesPosition; - if (startSegment) { - prev = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], prev); - Cartesian3.subtract(prev, position, prev); - Cartesian3.normalize(prev, prev); - Cartesian3.negate(prev, prev); - result.prevLength = 0.0; - } else { - prev = Matrix4.multiplyByPoint(modelMatrix, positions[index - 1], prev); - Cartesian3.subtract(prev, position, prev); - - result.prevLength = prev.magnitude(); - Cartesian3.normalize(prev, prev); - } - - var p = Math.sqrt(prev.z * 8.0 + 8.0); - normals.x = prev.x / p + 0.5; - normals.y = prev.y / p + 0.5; - - var next = computeAdjacencyAnglesPosition; - if (endSegment) { - Cartesian3.negate(prev, next); - result.nextLength = 0.0; - } else { - next = Matrix4.multiplyByPoint(modelMatrix, positions[index + 1], next); - Cartesian3.subtract(next, position, next); - - result.nextLength = next.magnitude(); - Cartesian3.normalize(next, next); - } - - p = Math.sqrt(next.z * 8.0 + 8.0); - normals.z = next.x / p + 0.5; - normals.w = next.y / p + 0.5; - - return result; - } - var scratchWritePosition = new Cartesian3(); - var scratchWriteAdjacencyInfo = { - normals : new Cartesian4(), - prevLength : 0.0, - nextLength : 0.0 - }; - var encodedP = new EncodedCartesian3(); + var scratchWritePrevPosition = new Cartesian3(); + var scratchWriteNextPosition = new Cartesian3(); - PolylineBucket.prototype.write = function(positionArray, adjacencyArray, pickColorArray, texCoordExpandWidthAndShowArray, positionIndex, adjacencyIndex, colorIndex, texCoordExpandWidthAndShowIndex, context) { + PolylineBucket.prototype.write = function(positionArray, pickColorArray, texCoordExpandWidthAndShowArray, positionIndex, colorIndex, texCoordExpandWidthAndShowIndex, context) { var mode = this.mode; var polylines = this.polylines; var length = polylines.length; @@ -1098,10 +1093,20 @@ define([ var count = 0; for ( var j = 0; j < positionsLength; ++j) { - var position = positions[j]; + var position = (j !== 0) ? positions[j - 1] : positions[j]; + scratchWritePrevPosition.x = position.x; + scratchWritePrevPosition.y = position.y; + scratchWritePrevPosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; + + position = positions[j]; scratchWritePosition.x = position.x; scratchWritePosition.y = position.y; - scratchWritePosition.z = (this.mode !== SceneMode.SCENE2D) ? position.z : 0.0; + scratchWritePosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; + + position = (j !== positionsLength - 1) ? positions[j + 1] : positions[j]; + scratchWriteNextPosition.x = position.x; + scratchWriteNextPosition.y = position.y; + scratchWriteNextPosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; var segmentLength = lengths[segmentIndex]; if (j === count + segmentLength) { @@ -1112,54 +1117,26 @@ define([ var segmentStart = j - count === 0; var segmentEnd = j === count + lengths[segmentIndex] - 1; - var adjacencyInfo = computeAdjacencyInfo(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacencyInfo); - var adjacencyNormals = adjacencyInfo.normals; - var prevLength = adjacencyInfo.prevLength; - var nextLength = adjacencyInfo.nextLength; - var startK = (segmentStart) ? 2 : 0; var endK = (segmentEnd) ? 2 : 4; for (var k = startK; k < endK; ++k) { - var lineLength = (k - 2 < 0) ? -prevLength : nextLength; - EncodedCartesian3.fromCartesian(scratchWritePosition, encodedP); - var high = encodedP.high; - var low = encodedP.low; - - positionArray[positionIndex] = high.x; - positionArray[positionIndex + 1] = high.y; - positionArray[positionIndex + 2] = high.z; - positionArray[positionIndex + 3] = 0.0; - - positionArray[positionIndex + 4] = low.x; - positionArray[positionIndex + 5] = low.y; - positionArray[positionIndex + 6] = low.z; - positionArray[positionIndex + 7] = lineLength; - - if (mode === SceneMode.SCENE3D) { - adjacencyArray[adjacencyIndex] = adjacencyNormals.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyNormals.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyNormals.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyNormals.w; - } else { - adjacencyArray[adjacencyIndex + 2] = adjacencyNormals.x; - adjacencyArray[adjacencyIndex + 3] = adjacencyNormals.y; - adjacencyArray[adjacencyIndex + 6] = adjacencyNormals.z; - adjacencyArray[adjacencyIndex + 7] = adjacencyNormals.w; - } + EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); + EncodedCartesian3.writeElements(scratchWritePrevPosition, positionArray, positionIndex + 6); + EncodedCartesian3.writeElements(scratchWriteNextPosition, positionArray, positionIndex + 12); pickColorArray[colorIndex] = pickColor.red; pickColorArray[colorIndex + 1] = pickColor.green; pickColorArray[colorIndex + 2] = pickColor.blue; pickColorArray[colorIndex + 3] = 255; + var direction = (k - 2 < 0) ? -1.0 : 1.0; texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex] = j / (positionsLength - 1); // s tex coord - texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * (k % 2) - 1; // expand direction - texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 2] = width; + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * (k % 2) - 1; // expand direction + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 2] = direction * width; texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 3] = show; - positionIndex += 8; - adjacencyIndex += 8; + positionIndex += 6 * 3; colorIndex += 4; texCoordExpandWidthAndShowIndex += 4; } @@ -1168,8 +1145,10 @@ define([ }; var morphPositionScratch = new Cartesian3(); + var morphPrevPositionScratch = new Cartesian3(); + var morphNextPositionScratch = new Cartesian3(); - PolylineBucket.prototype.writeForMorph = function(positionArray, adjacencyArray, positionIndex, adjacencyIndex) { + PolylineBucket.prototype.writeForMorph = function(positionArray, positionIndex) { var modelMatrix = this.modelMatrix; var polylines = this.polylines; var length = polylines.length; @@ -1183,8 +1162,14 @@ define([ var count = 0; for ( var j = 0; j < positionsLength; ++j) { + var prevPosition = (j !== 0) ? positions[j - 1] : Cartesian3.ZERO; + prevPosition = Matrix4.multiplyByPoint(modelMatrix, prevPosition, morphPrevPositionScratch); + var position = Matrix4.multiplyByPoint(modelMatrix, positions[j], morphPositionScratch); + var nextPosition = (j !== positionsLength - 1) ? positions[j + 1] : Cartesian3.ZERO; + nextPosition = Matrix4.multiplyByPoint(modelMatrix, nextPosition, morphNextPositionScratch); + var segmentLength = lengths[segmentIndex]; if (j === count + segmentLength) { count += segmentLength; @@ -1194,37 +1179,15 @@ define([ var segmentStart = j - count === 0; var segmentEnd = j === count + lengths[segmentIndex] - 1; - var adjacencyInfo = computeAdjacencyInfo(position, j, positions, segmentStart, segmentEnd, scratchWriteAdjacencyInfo); - var adjacencyNormals = adjacencyInfo.normals; - var prevLength = adjacencyInfo.prevLength; - var nextLength = adjacencyInfo.nextLength; - var startK = (segmentStart) ? 2 : 0; var endK = (segmentEnd) ? 2 : 4; for (var k = startK; k < endK; ++k) { - var lineLength = (k - 2 < 0) ? -prevLength : nextLength; - EncodedCartesian3.fromCartesian(scratchWritePosition, encodedP); - var high = encodedP.high; - var low = encodedP.low; - - positionArray[positionIndex] = high.x; - positionArray[positionIndex + 1] = high.y; - positionArray[positionIndex + 2] = high.z; - positionArray[positionIndex + 3] = 0.0; - - positionArray[positionIndex + 4] = low.x; - positionArray[positionIndex + 5] = low.y; - positionArray[positionIndex + 6] = low.z; - positionArray[positionIndex + 7] = lineLength; - - adjacencyArray[adjacencyIndex] = adjacencyNormals.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyNormals.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyNormals.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyNormals.w; - - positionIndex += 8; - adjacencyIndex += 8; + EncodedCartesian3.writeElements(position, positionArray, positionIndex); + EncodedCartesian3.writeElements(prevPosition, positionArray, positionIndex + 6); + EncodedCartesian3.writeElements(nextPosition, positionArray, positionIndex + 12); + + positionIndex += 6 * 3; } } } @@ -1252,7 +1215,7 @@ define([ var segments; if (this.mode === SceneMode.SCENE3D) { segments = scratchSegmentLengths; - var positionsLength = polyline._computedPositions.length; + var positionsLength = polyline.getPositions().length; if (positionsLength > 0) { segments[0] = positionsLength; } else { @@ -1339,7 +1302,7 @@ define([ var scratchLengths = new Array(1); PolylineBucket.prototype.getSegments = function(polyline) { - var positions = polyline._computedPositions; + var positions = polyline.getPositions(); if (positions.length > 0) { if (typeof polyline._polylineCollection._boundingVolume === 'undefined') { @@ -1390,16 +1353,16 @@ define([ return scratchSegments; }; - PolylineBucket.prototype.writePositionsUpdate = function(positionIndex, polyline, positionBuffer, adjacencyBuffer) { + PolylineBucket.prototype.writeUpdate = function(index, polyline, positionBuffer, texCoordExpandWidthAndShowBuffer) { var mode = this.mode; var positionsLength = polyline._actualLength; if (positionsLength) { - positionIndex += this.getPolylineStartIndex(polyline); - var positionArray = new Float32Array(2 * positionsLength * 4); - var adjacencyArray = new Float32Array(2 * positionsLength * 4); + index += this.getPolylineStartIndex(polyline); + var positionArray = new Float32Array(6 * positionsLength * 3); + var texCoordExpandWidthAndShowArray = new Float32Array(positionsLength * 4); - var index = 0; - var adjacencyIndex = 0; + var positionIndex = 0; + var texCoordExpandWidthAndShowIndex = 0; var segments = this.getSegments(polyline); var positions = segments.positions; @@ -1408,12 +1371,25 @@ define([ var segmentIndex = 0; var count = 0; + var width = polyline.getWidth(); + var show = polyline.getShow(); + positionsLength = positions.length; for ( var i = 0; i < positionsLength; ++i) { - var position = positions[i]; + var position = (i !== 0) ? positions[i - 1] : Cartesian3.ZERO; + scratchWritePrevPosition.x = position.x; + scratchWritePrevPosition.y = position.y; + scratchWritePrevPosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; + + position = positions[i]; scratchWritePosition.x = position.x; scratchWritePosition.y = position.y; - scratchWritePosition.z = (this.mode !== SceneMode.SCENE2D) ? position.z : 0.0; + scratchWritePosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; + + position = (i !== positionsLength - 1) ? positions[i + 1] : Cartesian3.ZERO; + scratchWriteNextPosition.x = position.x; + scratchWriteNextPosition.y = position.y; + scratchWriteNextPosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; var segmentLength = lengths[segmentIndex]; if (i === count + segmentLength) { @@ -1424,71 +1400,27 @@ define([ var segmentStart = i - count === 0; var segmentEnd = i === count + lengths[segmentIndex] - 1; - var adjacencyInfo = computeAdjacencyInfo(position, i, positions, segmentStart, segmentEnd, scratchWriteAdjacencyInfo); - var adjacencyNormals = adjacencyInfo.normals; - var prevLength = adjacencyInfo.prevLength; - var nextLength = adjacencyInfo.nextLength; - var startJ = (segmentStart) ? 2 : 0; var endJ = (segmentEnd) ? 2 : 4; for (var j = startJ; j < endJ; ++j) { - var lineLength = (j - 2 < 0) ? -prevLength : nextLength; - EncodedCartesian3.fromCartesian(scratchWritePosition, encodedP); - var high = encodedP.high; - var low = encodedP.low; - - positionArray[index] = high.x; - positionArray[index + 1] = high.y; - positionArray[index + 2] = high.z; - positionArray[index + 3] = 0.0; - - positionArray[index + 4] = low.x; - positionArray[index + 5] = low.y; - positionArray[index + 6] = low.z; - positionArray[index + 7] = lineLength; - - if (mode === SceneMode.SCENE3D) { - adjacencyArray[adjacencyIndex] = adjacencyNormals.x; - adjacencyArray[adjacencyIndex + 1] = adjacencyNormals.y; - adjacencyArray[adjacencyIndex + 4] = adjacencyNormals.z; - adjacencyArray[adjacencyIndex + 5] = adjacencyNormals.w; - } else { - adjacencyArray[adjacencyIndex + 2] = adjacencyNormals.x; - adjacencyArray[adjacencyIndex + 3] = adjacencyNormals.y; - adjacencyArray[adjacencyIndex + 6] = adjacencyNormals.z; - adjacencyArray[adjacencyIndex + 7] = adjacencyNormals.w; - } - - index += 8; - adjacencyIndex += 8; - } - } - - positionBuffer.copyFromArrayView(positionArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex); - adjacencyBuffer.copyFromArrayView(adjacencyArray, 2 * 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex); - } - }; - - PolylineBucket.prototype.writeTexCoordExpandWidthAndShowUpdate = function(positionIndex, polyline, buffer) { - var positionsLength = polyline._actualLength; - if (positionsLength) { - positionIndex += this.getPolylineStartIndex(polyline); - var show = polyline.getShow(); - var width = polyline.getWidth(); - var texCoordExpandWidthAndShowArray = new Float32Array(4 * positionsLength); - var texCoordExpandWidthAndShowIndex = 0; - for ( var j = 0; j < positionsLength; ++j) { - for (var k = 0; k < 2; ++k) { - texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex] = j / (positionsLength - 1); // s tex coord - texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * k - 1; // expand direction - texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 2] = width; + EncodedCartesian3.writeElements(scratchWritePosition, positionArray, positionIndex); + EncodedCartesian3.writeElements(scratchWritePrevPosition, positionArray, positionIndex + 6); + EncodedCartesian3.writeElements(scratchWriteNextPosition, positionArray, positionIndex + 12); + + var direction = (j - 2 < 0) ? -1.0 : 1.0; + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex] = i / (positionsLength - 1); // s tex coord + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 1] = 2 * (j % 2) - 1; // expand direction + texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 2] = direction * width; texCoordExpandWidthAndShowArray[texCoordExpandWidthAndShowIndex + 3] = show; + positionIndex += 6 * 3; texCoordExpandWidthAndShowIndex += 4; } } - buffer.copyFromArrayView(texCoordExpandWidthAndShowArray, 4 * Float32Array.BYTES_PER_ELEMENT * positionIndex); + + positionBuffer.copyFromArrayView(positionArray, 6 * 3 * Float32Array.BYTES_PER_ELEMENT * index); + texCoordExpandWidthAndShowBuffer.copyFromArrayView(texCoordExpandWidthAndShowArray, 4 * Float32Array.BYTES_PER_ELEMENT * index); } }; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index d8c8f06ea6ed..5d4ed02762cc 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -1,9 +1,15 @@ -attribute vec4 position3DHigh; -attribute vec4 position3DLow; -attribute vec4 position2DHigh; -attribute vec4 position2DLow; -attribute vec4 prev; -attribute vec4 next; +attribute vec3 position3DHigh; +attribute vec3 position3DLow; +attribute vec3 position2DHigh; +attribute vec3 position2DLow; +attribute vec3 prevPosition3DHigh; +attribute vec3 prevPosition3DLow; +attribute vec3 prevPosition2DHigh; +attribute vec3 prevPosition2DLow; +attribute vec3 nextPosition3DHigh; +attribute vec3 nextPosition3DLow; +attribute vec3 nextPosition2DHigh; +attribute vec3 nextPosition2DLow; attribute vec4 texCoordExpandWidthAndShow; attribute vec4 pickColor; @@ -16,22 +22,6 @@ varying vec4 v_pickColor; uniform float u_morphTime; -// Unpacks a normal from a vec2 using a spheremap transform -// see -// http://aras-p.info/texts/CompactNormalStorage.html#method04spheremap -// for details. -vec3 decode(vec2 enc) -{ - vec2 fenc = enc * 4.0 - 2.0; - float f = dot(fenc, fenc); - float g = sqrt(1.0 - f / 4.0); - - vec3 n; - n.xy = fenc * g; - n.z = 1.0 - f / 2.0; - return n; -} - void clipLineSegmentToNearPlane( vec3 positionEC, vec3 directionEC, @@ -72,48 +62,67 @@ void main() { float texCoord = texCoordExpandWidthAndShow.x; float expandDir = texCoordExpandWidthAndShow.y; - float width = texCoordExpandWidthAndShow.z + 0.5; + float width = abs(texCoordExpandWidthAndShow.z) + 0.5; + bool usePrevDirection = texCoordExpandWidthAndShow.z < 0.0; float show = texCoordExpandWidthAndShow.w; - vec4 p; + vec4 p, prev, next; vec4 prevDir; vec4 nextDir; float segmentMagnitude; - bool usePrevDirection; if (u_morphTime == 1.0) { p = vec4(czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz), 1.0); - prevDir = vec4(decode(prev.xy), 0.0); - nextDir = vec4(decode(next.xy), 0.0); + prev = vec4(czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz), 1.0); + next = vec4(czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz), 1.0); - segmentMagnitude = abs(position3DLow.w); - usePrevDirection = position3DLow.w < 0.0; + segmentMagnitude = usePrevDirection ? length(prev - p) : length(next - p); + + prevDir = vec4(normalize(prev.xyz - p.xyz), 0.0); + nextDir = vec4(normalize(next.xyz - p.xyz), 0.0); } else if (u_morphTime == 0.0) { p = vec4(czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), 1.0); - prevDir = vec4(decode(prev.zw).zxy, 0.0); - nextDir = vec4(decode(next.zw).zxy, 0.0); + prev = vec4(czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy), 1.0); + next = vec4(czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy), 1.0); + + segmentMagnitude = usePrevDirection ? length(prev - p) : length(next - p); - segmentMagnitude = abs(position2DLow.w); - usePrevDirection = position2DLow.w < 0.0; + prevDir = vec4(normalize(prev.xyz - p.xyz), 0.0); + nextDir = vec4(normalize(next.xyz - p.xyz), 0.0); } else { p = czm_columbusViewMorph( czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), - czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz), + czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz), u_morphTime); + prev = czm_columbusViewMorph( + czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy), + czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz), + u_morphTime); + next = czm_columbusViewMorph( + czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy), + czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz), + u_morphTime); + + segmentMagnitude = usePrevDirection ? length(prev - p) : length(next - p); - prevDir = czm_columbusViewMorph(decode(prev.xy), decode(prev.zw), u_morphTime); - nextDir = czm_columbusViewMorph(decode(next.xy), decode(next.zw), u_morphTime); - prevDir.w = 0.0; - nextDir.w = 0.0; - - segmentMagnitude = abs(position2DLow.w); - usePrevDirection = position2DLow.w < 0.0; + prevDir = vec4(normalize(prev.xyz - p.xyz), 0.0); + nextDir = vec4(normalize(next.xyz - p.xyz), 0.0); + } + + if (czm_equalsEpsilon(prevDir, vec4(0.0), czm_epsilon7)) + { + prevDir = -nextDir; + } + + if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7)) + { + nextDir = -prevDir; } vec4 endPointWC; @@ -121,8 +130,8 @@ void main() bool culledByNearPlane; vec4 positionEC = czm_modelViewRelativeToEye * p; - vec4 nextEC = vec4(normalize((czm_modelView * nextDir).xyz), 0.0); - vec4 prevEC = vec4(normalize((czm_modelView * prevDir).xyz), 0.0); + vec4 nextEC = vec4(normalize((czm_modelViewRelativeToEye * nextDir).xyz), 0.0); + vec4 prevEC = vec4(normalize((czm_modelViewRelativeToEye * prevDir).xyz), 0.0); vec3 segmentDirection = (usePrevDirection) ? prevEC.xyz : nextEC.xyz; clipLineSegmentToNearPlane(positionEC.xyz, segmentDirection, segmentMagnitude, endPointWC, clipped, culledByNearPlane); From ab8872042fe861308e56f2349ace7a9bec3d9e51 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Apr 2013 17:58:19 -0400 Subject: [PATCH 108/114] Update after merge. --- Source/DynamicScene/DynamicPathVisualizer.js | 2 -- Source/DynamicScene/DynamicPolylineVisualizer.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/Source/DynamicScene/DynamicPathVisualizer.js b/Source/DynamicScene/DynamicPathVisualizer.js index 98339f49d491..a2a023281af5 100644 --- a/Source/DynamicScene/DynamicPathVisualizer.js +++ b/Source/DynamicScene/DynamicPathVisualizer.js @@ -47,8 +47,6 @@ define([ } }; - var cachedColor = new Color(); - var cachedOutlineColor = new Color(); PolylineUpdater.prototype.updateObject = function(time, dynamicObject) { var dynamicPath = dynamicObject.path; if (typeof dynamicPath === 'undefined') { diff --git a/Source/DynamicScene/DynamicPolylineVisualizer.js b/Source/DynamicScene/DynamicPolylineVisualizer.js index da1f8ba0c4ab..43762692633e 100644 --- a/Source/DynamicScene/DynamicPolylineVisualizer.js +++ b/Source/DynamicScene/DynamicPolylineVisualizer.js @@ -170,8 +170,6 @@ define([ }; var cachedPosition = new Cartesian3(); - var cachedColor = new Color(); - var cachedOutlineColor = new Color(); DynamicPolylineVisualizer.prototype._updateObject = function(time, dynamicObject) { var dynamicPolyline = dynamicObject.polyline; if (typeof dynamicPolyline === 'undefined') { From 09cff09d7479efd501ba738d9a20a251525bb5b9 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 9 Apr 2013 19:22:53 -0400 Subject: [PATCH 109/114] Update polyline VS to use the new attributes. --- Source/Shaders/PolylineVS.glsl | 94 ++++++++++------------------------ 1 file changed, 26 insertions(+), 68 deletions(-) diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 5d4ed02762cc..5668cc485eed 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -23,18 +23,18 @@ varying vec4 v_pickColor; uniform float u_morphTime; void clipLineSegmentToNearPlane( - vec3 positionEC, - vec3 directionEC, - float magnitude, + vec3 p0, + vec3 p1, out vec4 positionWC, - out bool clipped, out bool culledByNearPlane) { culledByNearPlane = false; - clipped = false; - float endPoint0Distance = -(czm_currentFrustum.x + positionEC.z); - float denominator = -directionEC.z; + vec3 p1ToP0 = p1 - p0; + float magnitude = length(p1ToP0); + vec3 direction = normalize(p1ToP0); + float endPoint0Distance = -(czm_currentFrustum.x + p0.z); + float denominator = -direction.z; if (endPoint0Distance < 0.0 && abs(denominator) < czm_epsilon7) { @@ -43,19 +43,18 @@ void clipLineSegmentToNearPlane( else if (endPoint0Distance < 0.0 && abs(denominator) > czm_epsilon7) { // t = (-plane distance - dot(plane normal, ray origin)) / dot(plane normal, ray direction) - float t = (czm_currentFrustum.x + positionEC.z) / denominator; + float t = (czm_currentFrustum.x + p0.z) / denominator; if (t < 0.0 || t > magnitude) { culledByNearPlane = true; } else { - clipped = true; - positionEC = positionEC + t * directionEC; + p0 = p0 + t * direction; } } - positionWC = czm_eyeToWindowCoordinates(vec4(positionEC, 1.0)); + positionWC = czm_eyeToWindowCoordinates(vec4(p0, 1.0)); } void main() @@ -63,36 +62,21 @@ void main() float texCoord = texCoordExpandWidthAndShow.x; float expandDir = texCoordExpandWidthAndShow.y; float width = abs(texCoordExpandWidthAndShow.z) + 0.5; - bool usePrevDirection = texCoordExpandWidthAndShow.z < 0.0; + bool usePrev = texCoordExpandWidthAndShow.z < 0.0; float show = texCoordExpandWidthAndShow.w; vec4 p, prev, next; - vec4 prevDir; - vec4 nextDir; - - float segmentMagnitude; - if (u_morphTime == 1.0) { p = vec4(czm_translateRelativeToEye(position3DHigh.xyz, position3DLow.xyz), 1.0); prev = vec4(czm_translateRelativeToEye(prevPosition3DHigh.xyz, prevPosition3DLow.xyz), 1.0); next = vec4(czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz), 1.0); - - segmentMagnitude = usePrevDirection ? length(prev - p) : length(next - p); - - prevDir = vec4(normalize(prev.xyz - p.xyz), 0.0); - nextDir = vec4(normalize(next.xyz - p.xyz), 0.0); } else if (u_morphTime == 0.0) { p = vec4(czm_translateRelativeToEye(position2DHigh.zxy, position2DLow.zxy), 1.0); prev = vec4(czm_translateRelativeToEye(prevPosition2DHigh.zxy, prevPosition2DLow.zxy), 1.0); next = vec4(czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy), 1.0); - - segmentMagnitude = usePrevDirection ? length(prev - p) : length(next - p); - - prevDir = vec4(normalize(prev.xyz - p.xyz), 0.0); - nextDir = vec4(normalize(next.xyz - p.xyz), 0.0); } else { @@ -108,33 +92,16 @@ void main() czm_translateRelativeToEye(nextPosition2DHigh.zxy, nextPosition2DLow.zxy), czm_translateRelativeToEye(nextPosition3DHigh.xyz, nextPosition3DLow.xyz), u_morphTime); - - segmentMagnitude = usePrevDirection ? length(prev - p) : length(next - p); - - prevDir = vec4(normalize(prev.xyz - p.xyz), 0.0); - nextDir = vec4(normalize(next.xyz - p.xyz), 0.0); - } - - if (czm_equalsEpsilon(prevDir, vec4(0.0), czm_epsilon7)) - { - prevDir = -nextDir; - } - - if (czm_equalsEpsilon(nextDir, vec4(0.0), czm_epsilon7)) - { - nextDir = -prevDir; } vec4 endPointWC; - bool clipped; bool culledByNearPlane; vec4 positionEC = czm_modelViewRelativeToEye * p; - vec4 nextEC = vec4(normalize((czm_modelViewRelativeToEye * nextDir).xyz), 0.0); - vec4 prevEC = vec4(normalize((czm_modelViewRelativeToEye * prevDir).xyz), 0.0); - vec3 segmentDirection = (usePrevDirection) ? prevEC.xyz : nextEC.xyz; + vec4 prevEC = czm_modelViewRelativeToEye * prev; + vec4 nextEC = czm_modelViewRelativeToEye * next; - clipLineSegmentToNearPlane(positionEC.xyz, segmentDirection, segmentMagnitude, endPointWC, clipped, culledByNearPlane); + clipLineSegmentToNearPlane(positionEC.xyz, usePrev ? prevEC.xyz : nextEC.xyz, endPointWC, culledByNearPlane); if (culledByNearPlane) { @@ -142,35 +109,26 @@ void main() return; } - if (clipped) - { - prevDir = -nextDir; - } - - float pixelSize = czm_pixelSizeInMeters * abs(positionEC.z); float expandWidth = width * 0.5; vec4 p0, p1; vec2 direction, nextWC, prevWC; - if (czm_equalsEpsilon(prevDir, -nextDir, czm_epsilon3)) + if (czm_equalsEpsilon(normalize(prev.xyz - p.xyz), vec3(0.0), czm_epsilon3)) { - if (usePrevDirection || !clipped) - { - p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); - nextWC = normalize(p1.xy - endPointWC.xy); - direction = normalize(vec2(-nextWC.y, nextWC.x)); - } - else - { - p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); - prevWC = normalize(p0.xy - endPointWC.xy); - direction = normalize(vec2(prevWC.y, -prevWC.x)); - } + p1 = czm_eyeToWindowCoordinates(vec4(nextEC.xyz, 1.0)); + nextWC = normalize(p1.xy - endPointWC.xy); + direction = normalize(vec2(-nextWC.y, nextWC.x)); + } + else if (czm_equalsEpsilon(normalize(next.xyz - p.xyz), vec3(0.0), czm_epsilon3)) + { + p0 = czm_eyeToWindowCoordinates(vec4(prevEC.xyz, 1.0)); + prevWC = normalize(p0.xy - endPointWC.xy); + direction = normalize(vec2(prevWC.y, -prevWC.x)); } else { - p0 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + prevEC.xyz * pixelSize, 1.0)); - p1 = czm_eyeToWindowCoordinates(vec4(positionEC.xyz + nextEC.xyz * pixelSize, 1.0)); + p0 = czm_eyeToWindowCoordinates(vec4(prevEC.xyz, 1.0)); + p1 = czm_eyeToWindowCoordinates(vec4(nextEC.xyz, 1.0)); prevWC = normalize(p0.xy - endPointWC.xy); nextWC = normalize(p1.xy - endPointWC.xy); From 996152591300af9ffba712c19d8760e8246e72c3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 10 Apr 2013 14:24:59 -0400 Subject: [PATCH 110/114] Tweak the polyline subdivision distance. --- Source/Scene/Polyline.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Polyline.js b/Source/Scene/Polyline.js index 344dd166a327..03525d1c4978 100644 --- a/Source/Scene/Polyline.js +++ b/Source/Scene/Polyline.js @@ -172,7 +172,7 @@ define([ this.update(); }; - var granularity = (Math.PI / 360.0) * 6378137.0; + var granularity = 0.8 * (Math.PI / 180.0) * 6378137.0; function computePositions(positions) { if (typeof positions === 'undefined' || positions.length === 0) { From 101fd067fb8394b3d52e9f7b11cf157dbd855fdd Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 10 Apr 2013 15:14:01 -0400 Subject: [PATCH 111/114] Fix tests. --- Source/Scene/PolylineCollection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index 0c4564c8e490..eadb7e9b67d4 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -426,7 +426,7 @@ define([ if (polylineBuckets.hasOwnProperty(x)) { if (polylineBuckets[x] === bucket) { if (properties[POSITION_INDEX] || properties[SHOW_INDEX] || properties[WIDTH_INDEX]) { - bucket.writePositionsUpdate(index, polyline, this._positionBuffer, this._texCoordExpandWidthAndShowBuffer); + bucket.writeUpdate(index, polyline, this._positionBuffer, this._texCoordExpandWidthAndShowBuffer); } break; } From 45bb0d8cbe435690ace7a1b6dc5fda4224a59b65 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 10 Apr 2013 19:40:56 -0400 Subject: [PATCH 112/114] Update polyline segment end points. Update vertex shader. Updates based on review. --- Source/Scene/PolylineCollection.js | 8 +++--- Source/Shaders/PolylineVS.glsl | 41 ++++++++++++++---------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/Source/Scene/PolylineCollection.js b/Source/Scene/PolylineCollection.js index eadb7e9b67d4..d30dd875da2a 100644 --- a/Source/Scene/PolylineCollection.js +++ b/Source/Scene/PolylineCollection.js @@ -1162,12 +1162,12 @@ define([ var count = 0; for ( var j = 0; j < positionsLength; ++j) { - var prevPosition = (j !== 0) ? positions[j - 1] : Cartesian3.ZERO; + var prevPosition = (j !== 0) ? positions[j - 1] : positions[j]; prevPosition = Matrix4.multiplyByPoint(modelMatrix, prevPosition, morphPrevPositionScratch); var position = Matrix4.multiplyByPoint(modelMatrix, positions[j], morphPositionScratch); - var nextPosition = (j !== positionsLength - 1) ? positions[j + 1] : Cartesian3.ZERO; + var nextPosition = (j !== positionsLength - 1) ? positions[j + 1] : positions[j]; nextPosition = Matrix4.multiplyByPoint(modelMatrix, nextPosition, morphNextPositionScratch); var segmentLength = lengths[segmentIndex]; @@ -1376,7 +1376,7 @@ define([ positionsLength = positions.length; for ( var i = 0; i < positionsLength; ++i) { - var position = (i !== 0) ? positions[i - 1] : Cartesian3.ZERO; + var position = (i !== 0) ? positions[i - 1] : positions[i]; scratchWritePrevPosition.x = position.x; scratchWritePrevPosition.y = position.y; scratchWritePrevPosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; @@ -1386,7 +1386,7 @@ define([ scratchWritePosition.y = position.y; scratchWritePosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; - position = (i !== positionsLength - 1) ? positions[i + 1] : Cartesian3.ZERO; + position = (i !== positionsLength - 1) ? positions[i + 1] : positions[i]; scratchWriteNextPosition.x = position.x; scratchWriteNextPosition.y = position.y; scratchWriteNextPosition.z = (mode !== SceneMode.SCENE2D) ? position.z : 0.0; diff --git a/Source/Shaders/PolylineVS.glsl b/Source/Shaders/PolylineVS.glsl index 5668cc485eed..21ea5147b029 100644 --- a/Source/Shaders/PolylineVS.glsl +++ b/Source/Shaders/PolylineVS.glsl @@ -22,6 +22,8 @@ varying vec4 v_pickColor; uniform float u_morphTime; +const vec2 czm_highResolutionSnapScale = vec2(1.0, 1.0); // TODO + void clipLineSegmentToNearPlane( vec3 p0, vec3 p1, @@ -94,13 +96,15 @@ void main() u_morphTime); } - vec4 endPointWC; + vec4 endPointWC, p0, p1; bool culledByNearPlane; vec4 positionEC = czm_modelViewRelativeToEye * p; vec4 prevEC = czm_modelViewRelativeToEye * prev; vec4 nextEC = czm_modelViewRelativeToEye * next; + clipLineSegmentToNearPlane(prevEC.xyz, positionEC.xyz, p0, culledByNearPlane); + clipLineSegmentToNearPlane(nextEC.xyz, positionEC.xyz, p1, culledByNearPlane); clipLineSegmentToNearPlane(positionEC.xyz, usePrev ? prevEC.xyz : nextEC.xyz, endPointWC, culledByNearPlane); if (culledByNearPlane) @@ -109,31 +113,23 @@ void main() return; } - float expandWidth = width * 0.5; - vec4 p0, p1; - vec2 direction, nextWC, prevWC; + vec2 prevWC = normalize(p0.xy - endPointWC.xy); + vec2 nextWC = normalize(p1.xy - endPointWC.xy); - if (czm_equalsEpsilon(normalize(prev.xyz - p.xyz), vec3(0.0), czm_epsilon3)) - { - p1 = czm_eyeToWindowCoordinates(vec4(nextEC.xyz, 1.0)); - nextWC = normalize(p1.xy - endPointWC.xy); - direction = normalize(vec2(-nextWC.y, nextWC.x)); + float expandWidth = width * 0.5; + vec2 direction; + + if (czm_equalsEpsilon(normalize(prev.xyz - p.xyz), vec3(0.0), czm_epsilon1)) + { + direction = vec2(-nextWC.y, nextWC.x); } - else if (czm_equalsEpsilon(normalize(next.xyz - p.xyz), vec3(0.0), czm_epsilon3)) - { - p0 = czm_eyeToWindowCoordinates(vec4(prevEC.xyz, 1.0)); - prevWC = normalize(p0.xy - endPointWC.xy); - direction = normalize(vec2(prevWC.y, -prevWC.x)); + else if (czm_equalsEpsilon(normalize(next.xyz - p.xyz), vec3(0.0), czm_epsilon1)) + { + direction = vec2(prevWC.y, -prevWC.x); } else { - p0 = czm_eyeToWindowCoordinates(vec4(prevEC.xyz, 1.0)); - p1 = czm_eyeToWindowCoordinates(vec4(nextEC.xyz, 1.0)); - - prevWC = normalize(p0.xy - endPointWC.xy); - nextWC = normalize(p1.xy - endPointWC.xy); - vec2 normal = normalize(vec2(-nextWC.y, nextWC.x)); - + vec2 normal = vec2(-nextWC.y, nextWC.x); direction = normalize((nextWC + prevWC) * 0.5); if (dot(direction, normal) < 0.0) { @@ -151,7 +147,8 @@ void main() expandWidth = clamp(expandWidth / sinAngle, 0.0, width * 2.0); } - vec4 positionWC = vec4(endPointWC.xy + direction * expandWidth * expandDir, -endPointWC.z, 1.0); + vec2 offset = direction * expandDir * expandWidth * czm_highResolutionSnapScale; + vec4 positionWC = vec4(endPointWC.xy + offset, -endPointWC.z, 1.0); gl_Position = czm_viewportOrthographic * positionWC * show; #ifndef RENDER_FOR_PICK From f156a226b5129fc72f67e9e096a111a60807a372 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 10 Apr 2013 20:55:07 -0400 Subject: [PATCH 113/114] Update Sancastle polyline example image. --- Apps/Sandcastle/gallery/Polylines.jpg | Bin 10621 -> 19741 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Apps/Sandcastle/gallery/Polylines.jpg b/Apps/Sandcastle/gallery/Polylines.jpg index c2951698e6b6311eac3f4deee241d37aba2b9778..60ea242ef26bbdc8119fc59b6bdcee3fd090593a 100644 GIT binary patch literal 19741 zcmbTdbyOTp^foxSLxA8OCLwrmhXBC?1b25GT!KSzhu{{1d(gq%HMq;*&I|+?{Nw%Y zcfLJm|JvQ#eY@*)SM|A1S5@Dt=T^Tgy=(#A$VV7Y_#;_rLUi5Bab7f2Ce`Y;-jA|8o3)lb3D)J~|*306{`{2SCI} zK*C3O=?BofT95MjUjBPE|633ck&sbPUroZqdd<-I=GA;8B*a%^QIL^ebNjvC2O#64 z5YTamqY|o^puKZ`%NdlIk4`U9+e4%}4Fz(Ux&&ij5|faUk-z`I@R5;;n}?T=UqDdu zix`w8fwvMiuxrL>bwT-Q-o4bdnm-qLOAE9C45s^_z$v;z4)6z3Ce-{)M z6_=EjmDklbG&X^oTUvYj`UeJwhDSzcX6NP?7MGS+Alo~;d;156N5`I=zfrPv_x9 zeg@E*p45w-qT0~dj%<6HZ=Egd?l)4_DO%1fE}u1f7_4o+V?qKfX+my|aG!Bwomir4 z;N|9ZGpvCW=XEk-yu77o&SsY>7JIS+_k2>&uskSXPv2Jq+bONqj#iz0uL9J4Im%LX zEZP-MA`1dy8fMBeB%Zr80!yV%CiShS;iKc*fcRZMHsxUF!ty!8fZZ;mj5OHo*7V=4 z*7hVfJJK!Lg)szru*8V(05CoaEizj|l+s|c0l&}LjK!lo@hd$i7usDg zu1A@~=W}UJ*>`QqM80xuFq+=O!79@_0|m}C?PyhPJ@#}_OG}2FO7Th3+TD*haaMg$ zIUgSoRY%c4zbA&XGl6;entTN1FH#f@gwIpi{?O!Rw%Mz4rdye+k1Y!h_KW*I$~_9s zVu8kK`rtb2{g^d5ie8VA_Am>RTt~30&cijfnV#D5}^!HPLH49!-y>4N_|VNxt763DCj+S%RKuYwWYvD zl#+ymc*?nKpqxF!#iE6)ok;*`EE2IC)+Zd2Iwb%8LWrtiR(`$x1%O1wR#{zH7);6z zqA+RkNk79@`5+3ha=|($gQ!Epi`6wm7}Wafyra%2I4so!Vrz%gdJF|Uw>+y?PPRM4 z%dAmFcze!t{o*M-wS;s!m2me=muLw{Xnnx%nv=a&iiVrx9p*s634K=_NJy!Uf>*c7 zN_X4l1thLaBi7ZtehSKZkq)em^P$ zCxCiC<>gJhaPzaQdv}U4h7cVzVBy&`PB<2O! z-+^L;G4j_RWuOmokPgAS-%&R6`I0ydssIV$AEWt~pD_OjjC3FH96rC9Gi&$p`ehA~ zD_|PX0H|6Y6Q2B&jVO1Bi5?G6ra)PZI-z5eD~ul8>QxM zJEcM(rS@kGnUfO^1G|P_Q)_wQ{o(P61wy?CXehEs!ll(9O?cXGU(wlZBLZ8^R_QG4 z8Nz*qz1{)WPz`?eAptV}E!@6Jqc=|l5*bzxQaMEpVPpwCH@tHfcLw^g$=3)zp|VqT|_ZHEE*$m4pv zE2_p7zQclD5eZ4g@PPzx5m%l1gQ8$3@$e6)--*_DSGxLf_++QwCgb#gna1<~bXuhk zmpcc4X5qS9tXFC>_$cV0yDDV+0^piTs`4o~WY#e_(MPO!2R?76&4x`0;4F&8d2Rlf^!#=G@HWA#>+qV^{f{2|bt zUf9eA-&QcED$ab>j-FED;M36HHiCWf6|NjVLyhpiJX~S+l9SaB^__O>qOvIcYQW(U z`dx$uM!FzF1#IkKW@GKf@x&3#yAj7q(gs8QW)XkK!td0}J2k>}mD`UmfU3zFv-6|; zsln6$6E9l3nh%R(-rt6&D zxi+9xxY>YMxh;&^?2G)<>=Y>}b;?uvO6bnIp>AVQn<(~%;o%lqm_6(yXo`PGH*Y(( zL69NY?8eL7TUDUgI${-zTL&AR>J~o<)j9bhM_B#$U1E0Wp!_;6(+=b@fS}774*_nZ z-n#Jnudhac@b~m-d;e8$&$n;9i$Bt-yIcwGk>C&a6i=lw-ciK9Hpiq#BDfti?-`RB zEle2AtYjHZRa4NArW~c>K%6JchiBpkXzQT)q!+ETI+gRqR(r?Img=6JxbB#mv^idN z_6&69KfN!B{I_xp1I^k(wUGG@VlJmR*+b*dQ7b6i*KVg6dLC^?)jq99k)!wzewNCw zVIE_jD&R`71y(E;4+#Y%8p-{%%pJ^o7dNtABXs=4=4^V{v#j7#lUw%8sQoW*b+-4- zBO%=6m%fhIS6`92MplmtDFab4;^OAC72^n|7FC2htn?76%MYlYTp#$SRy?;#!W(Ns zbn_zVW*-@fbsAF!LW^=bvn=eVM-zuf$+f?Qr`hfjtVUvba%_3=oqfrq3B6{e@B5DB z9sgUe&Pd;zgJpJ9eoGGMg{%INmT2@K)sjUf#VdSAvljRF!fobYg*zo|+vPS%R*xR= zMp=xJ9+Gf%t#Ai&vxg9fA938H^50L^fVTWYbJF#7Q;xQPiCURySTVa@~R{8yv_~WO zici0OJw8=kiU~1fF4aX4KXFPPG6|dM-8#^uIPEaHV^xI0-8CC*6!!h7pmu#=Llzio z$IU|REO!o*fsjHHd)jH-@XmzBq`&8tHz3q<$bzWgx37RX?D$v^V$oFVUDSy9CDYyc z9eeto+}EHM%mj?S$*+# zzUuiy1MlUCNr4Qv=3#$|6Q=K_L+`=9<`6W-*w~C3Qsf2t2JH&0-ummXAS4u#yMQeB zgKOfdUbb{qftPQGp^R*J(vCz2_8eUbk1>#ZA3M6i)G#UV?YIZaoNfMF`(yLq0zVaV zBy6Z3Yl`5=$Q+!h(HJA?;26#+w_E&olF!@`fT*3b_u5)9$bf$Ad!>6-$e45}N zi4!)$N&3BY`l~D!Kaqv*gSrLm^He9MLUzCBSkCzj_t8s(6qKIPk%*XIq%gx8YgN3H~mwy zxB9-@!%~?`^qb;P_AdSl;N*bY^&iKclHt)pRYNY2lP`^ad9d=7US&$6atR4*7WfZM zfG1fr@At7_gKfPeh-!zJ;0F%%Q_E_S3&u{iYsj?-dr)<1pCl$9ic59XyHMlqU2|-t zn2@8PmTDihKXI%5IOGyw{Bg1Z*&Sr*?wmCmL)k) z)z;BT$0kV<9|kOL5FX*jvOh7dj>hDJV`?=c3eNTaiOA3khfJY%lEDt**xK#8pW(9=n*Dji#0TLksW3g{#TK zwR4H)8=4;#soLx1E!$&89jP+Lc%M5RF_T7RSQDe*v)jPbTmU?68;4JEWyPR<6sIeX zHcGZzOPdC}(j)2ZRf3HEl~J+HRt0HgO7Rsj#hbcn<*{JTciGp-F$4(0=4M^d{(l4N zo6=wu5GJ@)Ux;%3T%|kzenWfuIj15$jnG6wS>hO@Sv6%gN5!^e` zFw4f}cS-kD@G}RTMl|0NJTvu+C$a-Pi~L(rV#BX|A4QDC{Bo>C8*wa~&DAi+!_lNY zOz6yVN;&LUoT^TEz_Qg?d6M}hD zM|YDr3!UQxEJ$?PrQbI+%(K1#-p1ux(71@@4t3NFdbfLS9bSX*HYEc}B;DV)uC4MO zX3XIXL{ju1BevBJ1I&!k%mC_>`&Uyt#f+YQrffoK#qCag;dVNBrGxtdroFqbGmd8fU+(q zg;X@XMzn;T>&C~ebLTd)Zi zXR8ZI%sLc`7v(GES0lw+@YIFj4UCn^IzW_TK{9}9VPKSSZ-?BeJr{S!Y3%spDgd}w&k1@;i zWVXM0%yHFLru;bCwqD=ht9i!dZriyxMcM8(@V171u`#uCjv)iqDw+H|e0JwnHAP}u z>8=oJiPLaOq5N4$i^lcC9bTiKebe9Vp6NEnFL^eg3-Hsml*Xo%GE2PlG;cc(sh`BB zF5Z14ls}~ZYGwk^ymY4^o880ib`@T_FvX(KqTiQ)hHHUI9QwwgoG3UW@27;qjvqIm zAoA<<7eMjwcPq-MCvA99k%T|q(F?$e&>+CxR&zu0eN7s$^pamZB)R#NluXPE+lmMF zXueXS$lCZMwv{8G4-$;8N<03}_v5tM7i;U}B(y1BYrZ&YK}T}nxnwGsteXnKilCf$ zO@d3XlmO8#8Wxt@`p>CydfdF##yoe1t4Y9-lo^}L#06txXdj~B8s~>@H!b%dV(oEL zcU(J?KYaBRBt;vlFgUd4!Ce(nTEqVb`k;1 zK##G|nFVloEz6;BYBJ(($kE`b@+s8bsK%(yU9dligY`!Zsd zqO%e6aa`z-nEtUq2*Jj6O^$(U^%{}MRoN-j*xln634?iIpjnfzBWUU6muTG%9a;>3 zhKDHZ4&zC^Bu@IoP`FLGPNl(2#c)nb@CMN`8S{TMfZQS^JMai_L#v820XgK1Ocj6A-fm598*-|h1rn**l+BlUV-Y`}Mv8=oiR9yG#rACO7| z2a{1Zh#_@--yMP3A;CRf+s&Z2@a-wZw&o7#O|o+dc-bW0x7IIr<5D;`q8}%=A%b<0@eDR3u>Rv6&Wf>}Vrh$m?14v1_Q*~WaG6D(lp-}B7_5j=bMjB_ zgO_Y>u2>ccIlqLDedcrE7yZGml$|`~_Sb=KmTkX1R+m&ZrG3bFLx*;&meRssm12=T zw{gac3*u1^df=7WRxmofz_(6Vl_7$GGaP|`i>z`*(jvir)jJp*Z460}zrfHeYluUB zjKLVotalRcp2k;t!D>&(>u;ZFX~q|se21jD*lR+aQ{QF9bGCL_CU1@&pSUlKM_mlu zCQT729(=9DKy%!BdrkWSAQ2zhR+45mk_xIRh})*{rq}MKFz-z@GDIH~O#x<#bVbd` zRbFJuSa1xgDzmEJbWe&x(Q*aoi_BjDz4Y67rz4p+(qP%X!9aq1sGrA{i)fA@OnokC z>FRi*I7vpb{G?WAgD7gN-ggy`b&7@&Ehsw?t^u4qa}S~#-bgOSosVe}e*s*-0J7D% z{iuDgG%O#!)O{wB#nzdQZx(icyG{-Is6Zjts-1p8QJZ~#uRdfj>207$eglRb9kb4w zuafMquf<{9yt?|EqNJ6Lb4k|m5i57IGcFgId zZH(-I@^sm9*#rFl!z&AzzflT%xV@UsMDxjDtFNTfPeq}wAJGNNgacYz+HxDwKeLoLz)^NIX zEt%JDO?T%v)CF3cwCam3SM460sbK?X&TEYJiS#Z@5qWuAcU z*4E?D%4=zp>?RebfS*D$(IKd=(l5=`{%V+*=)UNH;^lG868v=@1U{t~8H(J8q4nF9 z`HEK>Dc*!d31n=0h;eY$elq|&eHQXJ^t3`cLT@OeH^b&wU0%{D3tRX&tf8dge@KfE zlz51?#nf5GjVLQR-@35AOj3)5X+2vCv=~t}RM5Q*yrU$$Lm?2XyPtCq- z>^Ec5@|`zaWsCm1ufCORU4&Ac?{2{}f3U10X+8jUPT-S3-+Chy(0E)K>Wb>_c|?Y>avyRe9+yNCfG?4Z@~ z*YH18KDrkl=Ap6?^Lj1z>)N!>cB3TiV<6J5z&95Fo|1HF zlnK zfc-Ziy0SN=10R2jH4I7VJecSGn|i+cU3@w-yaesz=5vyxKuPxM5#h?czE5-tXnIEQ zUd;T#WlQc?R5im?Yr!c)srsfOd#mE#pv&1BN6i>J-Z*L%sHLgAdE_L>s7MT>I!*m4 z*P-DgpR}{RHhS1^@^W%!wR}*;rH$M#6R8 zpf?oSrV<+F=9aYP`Lx7{Z8&Ob%`;VWnTmA=CoyTQIVW zm&#ov5jRPn3D3-Mh;D`P`kxs);bq$?Gj6PsstYWq4*3af6E|eQ=A1;&3JxI^o$j88 zwp;UBV?Q5Fc%&V4tmnI7NC3#9PJR5I!C%k)@x8768}FK;j(23*6nWoAen!c3MuwH(tEXae8H{Y*TaJwWg`JCiu1D)s3G} zwNH+I(0N1C8Y;IU-h(2GY}%@zC?P^3K3DjF&|23jyQR0u@Mg8`OSMkm-H(V!I?_Qj zeJIoI8Quf14^m~Mw%D+GvMQ^phTVp)gN;SohYzOtbUYT5oo$||e+G_(KtZQh&Ly^< zfA#G?9d|9ij*Xls#&akI*wA~%O?oU368MM9V~o_Me5bP`Wt;SPmf;WxhEnMcWD zc=e79?0vTE!lI!2vDmOYUs|?93WaG{>}^3%n5H3fK^yd-?_ve9hxiNh1<=P%tk12& zGtQCz$XeQ*5Tihj>c^>=^yO<}c!Q`yQtGc{eX1A0fP#n}Z<7k10(qJnU{ z3SXl67eMXx8HxI|yJehE`dLY)fbg(EgwF3o1>m1rX+-Vi#HOYN{ts0)&$P`mZZ-ue zCe1NSPr*`0&;zS~UHuisT=Iqtv45WQKkW8blW$i@amP5ZNV= z^oGZ)a=Q36opU>%?(a2>2shWI$`vWC>l{Bux8)SnUQa4tRSoEH%h~ULt4&X{;Uwr# zf84keAbs>AqjSjYuSxz&2bmsa=Sm#aeVhJbPm5TJTZh0=4luwGfs-S~s#>;MZCfnbk^5oH zPOnr~pf5F({}0h;1^};XeY{PawSa=k?lX@5%rm~Vk5Kw*~M93WX!3i;yN_kvhkRz7{?=*kR2VCK| z8E|Pplr&9trKY~pS!Qh>@x`Nxs*`9H`G@^Q&+u8?@_mTr=$dl5?&^qGLXmH22H;Kw zmMS8MxE|1^7%rc>KW~oR^x*wIY=K?`aPCd>>sZ$Dd{ON zd~vj>$M;)chs3o1o}jTn#*FQPP0Q;l+W`%;^A`~VL$*~(&E)Hl=%AlSdHH#<$J2S> z{ZM#g1f(I+lW-SZCk=PV)j1x+PT$dB?y!doK|D0`0kwv<9i1&rs<8GvuZ|Gc_^ zFuO52r7?3(R>QiX+^FllVWRz6iqL*gYkzq65+K&=d=9-}Sj;ES`FCwJANO@co?qwE zWAXk`ImZ3r1<-ixI;wQaJ0KdxPx_?1qrW~sc(imNno?EGx9kWsY|}5JpCim1Xr@#1 z`M!8!_r-UD^yfJm_dF^6M*5|klaeB{=qcM~+tfmR+tR-zz3_>rz2EU4l+PRAhS}Pj znfWUc%6@D^=yNpE z_mgs8(X0YCK`GDI5dW-B3S2yY*W_QL64qdlE}pt?={YNs{#}7H{UG-s>Z{TPfA}@> zR8%Ty<}EV1BEv{y4Q|Cl;x|rb#Ujr3+kbv1KFs9aF5~W-OSV8iqq}^CpVf zdOx->OhD;&O!mMY$#N$YS3XxBesEe+VRN&Iy{HauzNBhY&XhS5*=Bx4LU3}#-Mr?3viLP@hxdatRV;%PJ1zYv&?m`gc<=%yLuk`=vK@v+? zW*EI)dSb`p`)H6&(pM944-S0+*f?NXKZ@J&g*wuEotdO)P(3T>u1Gsk2&DY{G@2TN zi)!W&=t>7w{KH?h@2y%t@)p08%0ms|u4DCUrDZ|0R zaiMlazwv7I9Na?KZ73RKsn*NoyBZ{50s3Ya3Pl@?C-eQVa6Lhx(U|-#w7n6Wr5f-0 zL88+7HHI&H5Hd^~*d4Q$?Z(8ZAZM_C?(;S?_|XxH+Hs(FoQd-cw(!JG6B3(tvx`_y z6gT!aB}H8+jBR%OVb$X+{_2_Z=ly|?qO-tPB4t1MDUa&DGud9!cIA}|0kYA3(e(72 z9t=kYo4PO`UW6`AIG3J*<0cB?h<&o=pVm7nP`WYOCQn)D_gCpC&1=QSF{lUqEn-# zwM~m`*R>=~c6*b-R?DpyTS{><;m`f3k+p5uSh#X>A6ls^ow5JQK^@)$1I%Z+XHLz< zEWxToIvdg-v@BDVghzl(%#zzQy?O>#J!zdE;U+x&)I?w-F%9UyI*KaEUIsccECBg_ zpRkO3V2^xdk2%F2tV7f1NlPbeaz$3t<{jQX+unMEwD^=GpLsSy8(NX;v|QU*z{&kl z`La-+)Bx!*oaP1_`1Yd$#M$#EYPH4AXVZM8Uj8yFnuiBOBvX1qg7YCaVJM+i2H&_J zFU>W{Nsco4>0 zs2S>kVJi$R;&j)BUeBlPr;ey2kxI}M(yXw53U5t~9B$_VpQq9CpOp|Uc?k{zf@V6s zB*dhGxzv*ZwRV}>^-ekRWvt<<2GG~e^Ch5fk+^Ume|alje`5pY?DFa{!6)-Ln?>_c zB-AxXq#=n1`ay}3lrqnJ#>9A)jnLa&SVDWVO`dwvjtWIaZ=kW8eV96$<7V1iVy@Sb zo}f`U#rBm=g>y;opJi#oy+y{_Fn@!wo{i<5+=7{M-IJ=)6IPz{_>y&Y?3m+P;Ag_X zHW~Uwp*k7Il*0|e8P;pLGuDQ?hNlm+YG9k)7O}P_uxdMZIC3Cn6M)RJx75-?EqjmL z*)?n0R)hP@^4#q^O*q{jXd$}hpb!P|(^;fnwC}Opo4`U2@!O0(HpB!{A!&;K#tUlO zOwhnGPqbb>%EYb%h!GrV8upcgPU0iRAFKb?S((M5$-(l5(vl7PN}e(mNcUrD8^Rqi zl+$jL`6gObhxY9gADJ78Bw*zDA@VRvW%aqD2 zQi+%w($u;&*NI?bX$U9{gf30#5JT)J)1rz8If^>&xcOA(?`Zd(;KY!zeKB|1!6a-k zCmPvmKPJH&c+HOtb;3YC;F($8)R!#o1C^{~9hs)kQD}`PNjv;PS>e>KrNu3wbaB={ zg)YO%7q)rUxo;Um81++J^!8XUE@O6}M>$5waFaBn2-~X>w!Eu`#G29Sid2JszqQ(K zvWqWTE*A`CM}|01s+&CMsG^-}`(KBhOpoM|G@V+#9x}?j`pB=kmgM0$=iMpK8U7rIWL)z#Y;A8Mynwb(OQXxPVQv)x{MsKMV*k8`>- zmQTthx`W@QQ-D|ZQ7u%PKUESXIj`}ihkm^>SucS5M*Ax(;;C8CGSUv!e#QfE^CZ)r zS8c;ulrZyLd!4h`PT;1yn?Mx8F><+^J(47-)#c0dRK<?S9u&55cDJwtH zN~5U0B^U$t{5%*ox1QEUxT1FiY~_UoY~^*b%swhYO9le)zMPqC)8OkG>K$FR!^136 zi4aK5__1TN31kx}slr8M9tlDHT#q8~w(Sedlgxm}P`AFf3(23NWO6r-NK9+#`N#VM zUDJb}361i0I7fY(Gk9zUuGpa+{%6ltb6Zz}iK$c|GB&N}_u#3qvYW2{F7g$4eYYVE zxD)mkRH}4lMfgdXX^X{XuUSecQ4@nT(gxK~cK0q~g9rw9m4xRLS75G7X9kyob4@?J z8EL!~^_u!QO=QaN#ARp)<6a#Ezd35Fem9SQZAZ@-Oku*4mi|EcXOJFj7pfjPUzqs2 z8_1>y&D&PWDuy>f&a3z0CmW)$C}^&oH^zfVo6eTL%IwuBc^^dGkttLx-Rrs&`i7VK zazl5Guq!KlMM~vFi|ju9p=U)dr%F6emlah@?6;Sr4cWt=loiJ7jRze2)4;mo8nKoR z3>b9hipeP)JF~r;07#js*a@nEfxtP=uQf9Jk_j^De&d3n#km z&ZXRNr|>s;8^&&nC_osZ?Avwn?Z{KZw-tGJpOSpMZ@rx_Nrmmn$k0a{>@n;1w26Q; z5-^&+b+MhaFm_)Z=!I16tgtvr{lshQUtwIvLP+bJ5r3aMFsM_dbi}Gh>z&}>bpn4~ z;^-;Lo_aGVdoAmZY`RUj-%&a;hOl}b+ATurK4E@hNYDyJDbA_UJx7_B-b?k15LV>6*Sc6{2~#kcBzlhJQWCY;lGm?p?djZnresc`f3# zDptJdzTR~PC(eDUcma?L2fP5VWGU(NwARE`<*5#QBJNinK$S z^saB?I!%W#tki~WpbGAkE=!elo3aoCL)Ct;qjR>^?A>-XSF#+}z{IDyKi4^w+;=-O z3gtE;xfT1#=c$90#KbEog`Ol%-k&!4QcK5qaVpa1P=1i1WsZS|7zaGRI@dpSDLPK7h51_;BKo!UGt>7hmVeyc9xDbGyA!u|8l!B zQ=S|AMrw%fqpeYzP}1$d`(Qiva|EWDhtk<-XJ^-H(JVXH@a@zm+#DMKpcc0`b{Dv= zKIjpo=FadHd;yqs*3W{BlTN+`jb{}C&%rv*jlW`2hU0fVO;-z5u&~+5ZE2t}@OL6= z^5h1C4NbA28%t$DpN|EidImoPuo$~FSW{IxKbL>y#HbYZxuFT34RY3hdKR79g+EhNSg&j=XwUE~ zar_A$iu3OMDRTdy#Ze>kRN!FchyH1TswMbPx^fUT2EY~fNgADAU=3lwz4bNjG$RzS zi52jkuPh}xZGCYwJJ|bVsDtl8=ow$=@ceXNxzW4;Axorf}Xlxr`5)F6Z$B9kRykElynIZDfoU^c^o9Jkd6f-QKT$^LJo`6|4QqN8e zQjy|yi|FKqv?L^!c-v3L{huQ6vZ=o}h8QP!RDd7ZogTFee$np$^^xpsT`=cb?n^Pp z+h^%%0;eT8_2=|a|G?8dYuDR05R+eE1+kMG8}QY}JXR!zH29sy?0W2KjfsK9B8xlb z-Lkl^3c$@*YzCx{)!h)~mc6#`T1Ckav* zcE>JO7xI;Z*Q^PQ=G63quu=SC5qO_$Xt5o=zKY+ppNh47eXG5Raw}>%HmaKn zXPB|sW}KAuqbh)igv~DLCr4`gJ`HLrdx`j_ctm6;s$l$V^)Fi*hI>UO8)o096$jpu zKM0U#u(jN!)OSx^mVB9^Ci9@FdFAX<7}h^8t%n3Mejfez^j*UxoARFe?19Xh`~?uz zu4ml&Hb$}9%iqNJ_zL}}UIpT~%cu@way#Sj*W3)AYqT@Lw7fdyGiL~h{6v*XUZFB2 zSSX%#`?3&y=3@`FdIAR~rz>4b1Q|sq1soq1t_{b5X-UBhLxr7eb%mepEwxi+*JW3R zN7vqr%8H;*AyeYt;++w}=)XR-`{OlrlpJv^*`*d%^^v{p=va}aW-6| z&t$h>Z#_v`s!{g%A=~`Ei0xVHB*eF(Sxad{N(=arFAOwk+J>nSSkf{K>YLB)rn7XY5NKAgE{P!?nY zo^_{zr%S-}8AbJ@e~2ef0sJ<4YSYMi=W)P-qc3X)s+3LTJC}qv1}6&55$kG~iI* zUv6(NY*_!6iJr(B{qlM3aj1kgBsn*pZ3eHxO`b)idp| zbe9^8%l7^|$&F#tiX3`A4xPXC*IG18TRG8a*)!v4_;aLGapx`?0fvee!G!urNIdGI z1u`M$z-B3J)in zYLprOj>wQOUR;+Wqp*YDjZX!aN#S}@a#5SNlp63ciZphJi6WsAjX62^C)GZcnC@Vp)BsCT$Ut zwZGy_e>rwPlM#YMHscV6V*Cg1V;52$q`e$vc~ED!6vA@PZqFoGD_bWOqo+)1KMfey15xsE()=#*Am&&E;~z zdheWf9HvTX6>F#M1lQ#RYTvuuuE|67(Re4Z)~) zrUNpn_$!%Xf97?2V)*?`?|;YH8i*dS2W-qf#}GO?|!x^=I%oz$GdK3a`AmKs*Jw|@}DZ@kHc<4Wwu z2m^(F-PWXi#jZU!cWOD7MscIT6SnZ&GQwZk)LBz>aJFL_qnxhABP<(j%^fdEu*)Km zS^b;yu`812Hj(UsskV&0ZdOEZ=Pb7f8gdgi$M%6l(BWd$fAeiZ9?Jlo-)b`8jm9NE z5{e(H-D$+xEA8%!@*7^F{J;jbP8avgS(VQ>$!UaA{CQr9R)ViKyC2=ieH^yvibpGL`I3+K*#4FX_>);58shw*BB!l(ccoPtBZefg+d7i#gqT zKz~lee?WG7u=$9!)AAd7>d7&_Y1SM}!?|Z=;mX^sJzVP2f}&t1qJ9;l)uU26SNUwU z1UbGMoUtnM>eP!5cagDsKQS<;n{t?V_W0|89)}^1AW1JLj%>sNX-}9?pS`yWVADxj z+r{i+(mZ$ZKK?ZEYrPzXl_g;q@}IT3&)PwauGu*KS~}&n^`wImH!m8{+eLUm9ifWcc+%vMBo%17Kj_6BSgK1R7iy5g@kW!S+nMN;OKD?+fb?cirV z&{2{2R{qk;n!*#He$}&{iI(CvBs z@AX$GBl7`zBx`>A*JVjyW!uOI=awT#^fWm(#y6Zx8y$;dTU-~8%}5A#Y?mrrwSZ?0 z#XZor!^S^3?;+dL{8FA@uLLLdsGs`QvuSG{%88;!EQp>$vfDIg4d;-}J$KR7iWCVX z?8o-Sc_W(6H%pJAf1k%_VjCtT$C9Wdm8LDg$!FgjHRX8Q7(c%Wr3oM?4*|P;G{RdH zv$`O(-Vidv%n@GmN-U0>c6+eW+4s&yEX~Jqq{UAVq{hWVVoG$%ib;vD=rJqX{#YLQ zY*jLYth<+-~ zjI%rDpq!}`_+8aS#@uY4(EE8#Jr5djB6fA+{sQn{e6%hC(LKlqOm_bBPOB$4i|jNw1dbu8#! zbQ{^|BZjuT!S>))5_(>r2celfRWEhWbckhZgzB2F90i#>q_+izo?} zLON5!*bO5Bx*L>X1-fv~1b9U~(03cvhlgI{;o5wEZt;dp5qL#etLb-H!TL3!`h(bN za%QaHdETTtJWGt4+?ne^FyXN}j(PnUh z|NUw1I_pSNR+#1X3j%>5DGumL8E2474eIf=&D^C2$ni zy)%>Jv1PEgP+QZrhk;?VBEhsx@v-G&Q*6^de1WU?;s59Tej=R zy#4|(4+y0p5`E*V3uW(jpodK6Z!35gxA;-LZ<2dAXRh7?_6Vh5rtbr~ep1CeZxTQe zulX(d(boi4GT31@u-F=Y3gfNy+;RBOC;PY2#I8`mvt+f~aXUeR-5wNpRWe^0l!O-N z#(PtmT$5fd8oF&=4vwMtnY6gRS9iFYagm#?ln1Mmgk(RTUp6sZs(h_Nb9H)T28)PK;NS(=!b#$d|%X^DIKq$%WsS-Sd z#W0?$gXX!x(4wF18e||W2L1K|K-2SD0TCGZ_jIAViJj8N!u9aKB%Le$idtPG`Bd{rSoX-_<={{0B{-$M=)MbMw)I?@&rTy3J|aWxrK6Np z49}sI`fX_pZ5S4A0m?z(F}F-H6@I3fd#dZ8n$d?msT6g$q!Izc4Mm$PsdZ61A3u)G zalI<`Z}FqeO)euelj$2RIK!5-p+`yLXqoHKno#;_i#Sk&-pbOH^IJ8Z{y+A^SmZd} z*r`G?44z1F26}|uUE~dUnDAR&7;a+8p|h9kH=kxmgF@Da*#@!;)AmccyWbpVpRvl{ z-u2^vE%|E7;NTs%?d?=HIk0jxV(T0D&5;K5ev@4LSy%*lksE`x}AxSPb;XPo;fh z@zT>p@qfat79A(TI%bFBYprKaH=2Eoh`7AcWBVYEJ4U*DJ86}f=C%xyJ=HJ z)i*yd{?wnd{{V!^aRy= zYHOr;|L zvNpGP=4lU^6j&Qr^X5+iV1E?Rj;^5fULO68J}G#r?$+N)@HV}vTwhy@yJ+no^Pb`o zs=`zXNn|SMLk=+NdJ$6VL;089bIP4(@WK7e`R`fK7fyyr18wr~aDR*Z@ruhf((e7_ zY^k?*9dLSopKA4uXW>SxDsB;J@@0W4bsKJaf742<;V*+XI)=U^*BaK^#5i|V)F5Y& zXBZn;;{!drdeq9a66S2GH0xU2uKtYYd=+D@c#`frJrc(L>f`Q(wT;UW^dHW>qriW# zUyZy?s7EHL_I)nhw-=G7Nu6-mKO(k0dyWTujQW?u-w?xVrD}QwpM~V`<+p}ln&SL{ z8(umg5s@g0Rxpjs70VIJ0L*^r%J{=!@ee|l&qVNV!~XyqXkI0_2`kR#D><%2v-uIS zM0d*Dv_ESL}vtc`fZN?ro9=xM^fq znke@Y8JX65c2FB}6Gleu<37=UcdqXzC~nlk?KGZQ`3P2@aHxNTCB z5fhedEQMDliDp^e8Y;IuC%w{o`ES3Klk>7U>tuL3^;IWMNiCa6ue~d;JKOI*3HY(& zO+&{zyjq3kj@A<@`Do=^=8ajljz&6?4;+vO7&(VVlUlyi^nFXh@2_0=s7}(|T_gmU zrDks}VsORZaNf*F87Ca=$@edb-yi&C@d>Y?(0nstrAc_gCBMAXtmn88{NEx)<`~mE z++~Y^7~=<#d-h~qQ{e7{bq=u%Hx?kQ^4eQn+T1mZ85KU$D=I?$n_}Yu%|Uf9}TUxiFVcMdF;Qj$BevPCB~txc#B1~xVf2{=uLII z$Yx=^q;c}E%olMdrh1SCc}x)aXW@MMy2uyA+S^_%^fu0OPb*r|q!c%)b8s z_$Lpt#Qy-#r~d$epRH^E00yxB&{|fl;rT6mXYg*~Ju^g`M!J$+Pf>;DA8xpsCkiZB zf2nv-f_N(2umGP#@qhdqrSZeXKMS-y4$Zy;cxzM9Y-P8()b#ClS&~h5XOh*HdyhWR z*<36VaT^G;DcKZYwn{7JYE+VzkGJG~l{#^2Rov{fkN6<(#v4D6I=73Y(|!XthxG|z zbnu|o^%c{?rHt0aOUI{1Kr%=s%xaCe95S{Zyt~KW@NBooPaOPT@P57hz3^VgOVKq* zudeK%)%8|bp-Z_Z@*wkV9oa%SMKZ`+KVPqDb0;`fJR)~qz2?5Jde#aft-+7%Z@J7~$W+_vHV!hErS2ih<* z<gejzV>%fqXgWN-q-t)%j-YzY^Uv8;!OhANz}e7d^FTFn-d?|?5=!G ztV?ePmmilN$lAoJ?T_SK4i|yP6{X>i_%-9>ovrSl9;4$AgFIX)%6ya%iZ(r z-(!u~&Np$KcA|>ot0wJsbV8hWI?F%!HuvMlg7kZT_(lFA_%BSG07#x=sM@#cD8nmuMAN5lUI#mDo#2aDt~|jNwx8lnPCHpc+D{XCsBF31-)BRC%wA~gv{6MK z(p|;u<8y1`AN(72`#}$kJ}SQOFT|e(_;11YTF#?$p;;dkYXauZ%Hn;=9F6v8CPN%> z2?=*BVp3V~4OH;w{2QhFRQNkivb55^E%++N-%LqkvPgVeti-l!Aq^tLt7a7gum!e( zlgZ5#S3OFTy{>5*ao)!{;{O2nHDlvN#+za^Ul@EZTc!U1kH59*_u@1AsD9?#4F3SG z`$u2k^1JS?e#ia|RQ;s1%jj;cym|0`-s;{(mMNmv^+b{N56rrp>W&2cik~dw% zO(SMf81ovZ{2I~wL|J&M;_F5Dh48{VYkRXcoi)b2sjb{XuO~BZKv&h4c4hVe;B?W!#24rb80T0EY^eS5=L_y%->?njHi_?k`GK*O{{;x zw7;|mh`b4Xrs^LUw2SF3En^F5bK;FkYY8V3TFTyHHJ{BGkm?S+XLDPgzF{R4rBX?5 zUnEa9Z}>Gc_K73@M_+?~_&C)60Qmy7{0aX62DyIG{uICpcr9x*5| z0Q`SX`2Pm|uS7U_1SrIRVQ~xqG!!%t3JwMi_-{i50HFSbF#$k0ED8>IY)VlTV;rYI z1kU*U`oFkTVtv0N|3HYL08qgHbp`ByFhF>?e?fLk02C|~ z3^Xhp6fDgDD*_4t4TDJmi^Uq|t!r?T|ukQ6CeVZ zaJ&23OmtAf?*=hV9M(_X4zmd)p|IYy8pUjmd9YA3c4|3zAPA@oN@m&(e36>WiI6b8 z654mfXsd^scRPdFsd-SvL3Q(xoPIImUw6H8RwLFKzMbA`&{9 zNLrsL-d5&jB-D;jYF_uSx25X6Woa`i*srOgvTBr}(RwMBH_0PG1|hLC9MeQ*edq$j z`|^8)L*qy<#ZnYcse!7mX)eb*)3e@GZ}syieL`5Q@QhJu1a$;L{`4s(rHU<3g&caF z#n#&>t=Vx9qM;u%aNkJlepWp~^+IX2wknvH|E;lEmcJr?b=SNiok7joNKSfNTa;-V ztzwWfyWoB(&~IRciQ_Zo!+L&QM7mAkr3<05VpZ!(XFy}{HvNkhS;5+FCcc^t4zOrZ zCuQ^1xnc8tjqU@0V}q4BT)B|LHFUEwf$s3sM)%T^WIF!x8QA8l@gQ*znth6qQb}Xg zUnvsHAiMpgq(<$A!rO8F6~yI$8$vQyA zd7;YB$>WT%-wl;r{(aFjerH4KMJ6+<8#WmHr;Odz)k*PQKt&?aOh6bDJuZ3@hBbDeg@1>Vf z6gwS~nV7yAscBGE)qB2)P3FQCv2;4DO9m_l*cl!-ubf@|kvyyC)OBq3dB~gA>rvm& zZI=(U@BMvAd9tVO#QgCRy7_y4Sg3_{3HIle{msNW6WwE9k%BwuQK`H`6>;+gmxbFt z_QWo}<6V01i16k4nlT*CFgAjAw+B3I(+;qwO?&i<*H&I6&X3Q-6?Qtjh`z)M9Wm*W zqv6R;-RMiDf#=FHK~wwiZ(d1f@Uz_v0-?=#*2xoM9l_k?#YyMvO8Oj8k(2zmPJBNBp{8Q(Hd(?$lg0Gu%79l`>yi_8!8lSxj&20Oz(aRp@mRLX$rB&dGQ` zWKrid7Mj&I!+)(Yz9c%ioIgJ)NeSr#`NL9LT5>Q)BN)qZA-=(;HdS-lu&&`Ep=j^- z+<2^uUg=jn=6Zv!BKR~PfY?x0TtF^&Ujr24)=wLXdr<}+yrPRVSU7NA^#cK`Rf+$)mF%%}kl%v`pp z)ZCZ)mVrNzuV~L1#LPis8?swup5*ZDx9$D6zL{oN)L}Z%1r*K`+@VrJz*qyRdDJV8 z`&Xs_w9j%FIfa5aR|_l#=FDcE_WI;tk~^BVAydA^KgrC_=({(~qEt_=cdDbpRXS@> z$H$SE4jHC2<44!!&dWrU*Av*mOqrp`5JalU+q+@jzi}Uc!W+I@Z&D^V%pU?iOp4Qi zM7~mKi}G^{Y2ZnP0M6-)FQmY+BeoFQD$aVyvu>ix>+lDF&jSril9$~=rkBOaDXq}f zy6^$W@`gKFTWdw4ZaA0da-9TVPdO-F^-QCZBtrSUn|}aKc%KF*y%acMUORL3N04f? zL+oI-QjW7f z+uf%SAxGn6)%Xtp)BEnblXd7}?LN=_y^{OL`Qw)9dK-c8>_T@m3yDotenj+O8C_|1 zJrEqPx+po1D3XN zse`>`f5(lqC7T}4s5oqHf5(Ya7fhmox)^P1jXNC~#q#x4q#i_SV4c|5^jy<@n8x

      )%k<7cEAN-*|OThBNaoB$R>_>rn-R9)bXInzd0Gd~)5y(=medFNRjYw?J>HwpRJOTSjG)AGU%+~Z_RK{B`$t5AwQz6DRscSs3z?a9+) zAh2U7aRR!eJIm#-c&s3j&puUStST&H+8q5$pKhiseCBTK>`Aj=7`dzYrT5dp2Vj=( z#&GA$<@;Bkt3^FMD82cWnp%6MTwsiOLPU~XXwbC`j0=_*uSf|aJ4MD9csZ9)F7M{r z$%;}iLWAryrbJMXgAscdH6=CNTKu#CS{PgdPZJV=L7!X4F#`7sDWI=!B)A0b^P=?Q ztins0u@Cdvj`^b>S`36;(2(FxSddBQT&6?mQfmk8}6+VYudzMFIQwO ziYP=#srqM!an;@;!-lDa1ET&&=?=@Im+?~+qD&Nn=+N$U-*!>7bs-1l&vH&|XN70X z{r%_N2&^t!?aqps&n!C?(!qG-5ZW~t|CzUXd^uzV?0}-iSVZ{J8LW<$Y6bO(DCjak z0EBJkp5S{Vr!2CAN;5F!&0!YZVKaqNNg|Tzdxoe&g*8oaV6q&&i*2s><$gHgk>4lR z*j*$XKnwMAuG8$B6O(?fB*mA$BA>Sj?55R3h{Mcjm;;!_NBURzVtVX#YQdV5gKef? zn%J-`0YEmYtjg+G84jvQd5{4%#$jeQb^wbIV$rBnPcT|!FbS{nbTe`oUUd=!u23Ps zGVF5$y$Aok9?SukGBQxfWQ$K8+J9HyEuE>Iz#_MACKfCgB8uV5W9}OOsJl`A8=!hV z#?wk*R4c(PFTw@Sv}H7YygR&`hXI-EyTE=aqJVV|@6E(-JmV{fC9c``)8DNrzOh2# zoxWYE1ymvm^x+jB#vnzEmFS{YHfxcIJ>Q*<-u0ZGU5{}~_2lRTB+$zUTRhGpKSFR&FQ^5^H2Kt5E-VEt&YuwBhxl}EV6M)k$ z#I%>#^ECs|L7SLzAZe^J1eJZ&g+*$1!O@Za zKH!4O%PWTqv8T$tfs(2gP|}1zYjtjO6Ih3-4jY}Grq%JcjLl{2iNsdh-%@>q29bVM zc*8x?k8TF{>_*~D{BO|+d2<@e58)5MWi-5XxJlFS?s(~(dAN0-g&}DqTISFD*V@zL z;HB}TMAngxydDEZW`4iy3ebT445BNp#gq=EmZCrDACf*n zqrRHuzSTAseXSKegzIB>8tucW6o(_(YP(a!l0LC>boA=?Wamqek;_8y`i4S1anvYE zol3EcoB|+rR?_nVO(~@=^rmnXu(unv0v#L-*+#I++ZnR*(EI9)-Fk{IBZLbp6Mw3w z*`Yv=zSq_oe4FM=pVq93@8{7%D%7N&Qen zdA>#QmnW0MnEKN%Ck(&B?4L=MmXLo^B_b?NU_V0?6oYc{H-LDfZ%SzP_j-}4flfNA z8hZLGvjY44*HB(U!A z+L%zUjp|w>l&0Xf^Iq4{onHTx9i+s?xezS=LNpF9Cj9pf9_yeu!4Ia-yp#(iU)neEx{(|N=YRQv?9yM}G0-c{$}9bW=2vhth~ zTg15g)fgG^xAr&oU8W-aFq82Fmky4m%p73t-ElaKShAv%Gg5(Bfadc@6FQ|O zxEkNyR7-MtQoxqe{yY|!bv>z$0v{tQ-_C39!|(z#s`=elZleCSW4nz4br)_sutH1j z!q(GLeh{5+*-x#to9R#HDk`+fW0q|wXN&jm%Ttu;!0?5gZ>0P?2AaH zW8K!Wqdzmsbb}3HUucw5U>#idFK2I4`iZVyA$289CIulkR&lT#sk)lR{10$(N#T|3 z6*O`P^gCtVDxq-GZ|+@=Nrq#31)ki}cYExn{Us#7uQunl4#=(f)N5!m_zklsQNQI5 zaGx&pGtK`%ToTQiwHNs(;kJ$mF8<&crnt}!Jy3rDWLlX|Hs%^xER#p%G$?;iB^Ofy zzL-eix6{Sg-yFP}E?T?J*|bk`L6_HC=~9OlYemsMIfR!e&5UF$;#q8%1sRN{`16e9Rs#TG0*-sfIj#XnTc zNekG8Aq!=;1O9E3AttKX27Z_EWvn!n#hd@s-d>>6*OU9=GEX?{ zV9?wiGVoJFothA#`Khb@dMH+H(VsK_*Pk_=_2s%_+vlg;8H{vTCn?o~wq@j;BNvz6 zHxYR!Ra9+*SmpDLWJEFzvl6#-*1@<;A!dQKyPXffDhBR~AAQE#TBXRdsT+Pz+Tr-_ zW@$HTMi2kRsowry#(W5FT3DU30MrQY-TQLk!BbWOQ(IK^^pdep@CZSz5T1N~A(WW9 zc_9m&T$9f?{q>f*y+8-QpYLPVH@wB=L2j|7%DyZPfBLm+jD?g7qw3>%IDkJOrS`RF zIL6G~49KCF5O-qP#Dy2b<4Bt@f3DO8(?pYQUVm}G{PE)z;9F%uf zcdD@Vr9q4Gka)eF>drm-kOZ?Ne0Ex=gd$Gqs-3;s9~(sTVjEfDf3^LjXjiDNmB9iQh)5A*I#h<#2VRYK6rYJ%s$NSaxyhH!5YRf!=20vl=0 zv#;}t>DO}}sHZ|DzACd7qK*Wm{`car_VP5eF|4#S zC5>mRH`A~pcD>FvxY*L%L%!$}ABX7Q)gO_8#zV1jhm*Q9goiey)l(%_1%-t_%qB}z zb2LzN_{p3{~y$pEczkGYG_nN;%&Vx8=9Qk1xu^AeD2AHC(Lvg;m2zb`k!ZA-XB z6Z|e5MZc~)+H=tY)@%9Gs6&J+u7JVFNHCy&dx5}!S&B8mEW5&5+<@Me$ zX#9F@lP<4DA~2>k=?7*@ zkP5y{;1S0KsvSOlk^lh#0l);vCyvE$mh`JIJ>_zLnyQWi9~q~JJ+&-OhKuvI-?Rp) zjRylaWOVsovX6r8ksF*|!U@8X34+AN(jHm2VG8kKhsRE3MWyNAL0$-%UKC1I69-sB z`km4}mdQl2M_9DfhB#md;o)vlZ6wU8~isyp`v&s4*CPuA?$GGx6{)LXvP7AiN81AMwlPYROxRSxG3~NlCX*&RQo%2U=xk|-mEg6&5JPSMRN1AZH&aw z;~@AmcT%JLIfI26itMuX_cZ*TQsK?0`)pbd?+N;HB`AebyO3oFU5>Pn=LtH=mJBVd<8ZHi79}N8#yAuG!SdY%kyZjF9&6i*eJ_on zjXuriDqmlzPq8&jY*L|22RZy`W!+>)UG`&S)|ju6^o;X#$4>dKqs|4)*w#te3VP{}nEc4D4%% ze=A>|sGO7>AVV;&e+rg ze-Jio6k01K(H6f{zx6C&4giDxwILrP_DG8=24rbTc`kJ^{$2q|gOQHJ{4}KKg4qOj8_Ys+FX0u*N>ExL*oj&d6 zk#(P>(667aCp#vDPdJmPyKP~_A3iJDuv*?taAc>?T0}9F6(z}(1aA)2I9`(!Xzv0= znf*(#GpOWAo-LhbJRlsUGk;E~5vk3nfcV39iD5*VJe(3$vW;|Q1qyTddK|+e;1cAf zAXlN;Pd8*?+|D+lGGB(W`)Sw#F&_!xH6ciK*36B~h z+#`A;+0YmsvB}rWTzPOK<9D4zd~XSm*zn<{&+6$*3(bk(qm`<(2d^6y1J8b!z>eS} z_exle475M%JuF(c<_J}y&mOU7aox+dv~{$gnx0WAWZdEk`uphfPI2XJT(C0GQdz~L zxoU&VlXB;G>z-4qyTNVKqLQ4}*jh-Po=5wO-v^g--!hO{e;OPv*sh@J)Gh0D+r?4Z z=4{ec$X~HNutzTeUmZS9R#;U?4QTX{Gpl2EvCKWR-fq0QJ;0z+N3!R|Af7OMbxmxS zHlV}uh;7rdCyDfVaUBqto_8i{{*Y6sX)aFK?rX6JnpQM!s4I9+S-ek?Dkgk7kk zIT~9f*7^PB>-mIY(SRsJG09y4(1u-!oAgniaAw>%u&XKISI3Y}!Z;XQUPgA7s+E`h z$4UZ8+P^-nORA{?Qnm}gy7?r*Gls7>Q8$MBNjhrEl*l;W__|2GZlM(bA zvN@|pdsgRh8%zS8oj1>sf_YCfPL5hs+PB3?bAz29@GGK6{a@R^%1<74mwQ++m%LGJ z!5!A@-tGME5?rBG$lm_|;HJoGl#Q>JOPhJ7Mz`XV$9RVcdGU7hR|-sIWGGJ%N{16vfsOd!bG~n$PG!Uta!*x8OXxOadQutS zYF3BQzVIyG>A2Sw6?fxF5(i_O@xE-i_Q<`U+nG#kT|}^Kt;XHzo;YtvejUrGMIcWY z52JLibX^@2VfA&KD^(Kqui?J40Lza3y#{f0zdhiurI2Xh0(+jiwX*VZNL5mpZ=+ij z-?~ZAcoSgQK-UTvLIOGiM3;Xq8ONR9?zAgE03d9m(_Ud;rRrxR7Py0{ww-tsD{73o z*ygb8@Ge~W`0x|xLJngSh0v=wcQMYg=4KX%PXhRaB$X}9d%Oclm~e?tKdJuu%L_90 zzSCh$-;11eRj%$ZRp7{Ab;~upys@`bH+wYpSjJVNo51q&=-80TK5QzTf*LOYaI?dl)P zUC%?8l1;!F2)62P#7E> z9BVW1WNV-XM9Oh=8YV;hZ$P0XJoBohsIn+XKq=SB7bnM3^OBgTeKCvsjWV88oQ{Lg zM;=o;aU6EXFI`cJ&EV=Nx^BC+vPAOY`u>>yi!ho@Nf)%JCI#Ixt=+QmyXU}Z!qox& zHb?B1lP9`@WJR2}B$Go&g-M!qHSl4C*ZognGtl;%dc3SVX>I$r`n8ov_Ts$g(_?eZ z=;vheNaJcDyu{yLg5sb$(8bT_t$fGREF*JMDw6h7N#6NGS^2$GJ)rm^GR=YVY-N1OHGK$?x zcSEb3)r35X6k3HrH3j-5TDkqw_>P4O2JhLv{FCofD!_wDIVwlulr6KfMzsELpJsj6No%zDG@bxm6^3(1 zG0XMsH{nu!-bC|#$mI1}OMXswL}^!X9rK)Q>RQCN2L>LhAn9%z=Zm=;A=LOIdkXDb z)x)GkelxIZomlTHF_^<|`}y&*DOX{jL}(;f_Sm%+#9!#3GWMym&QYo%GmBu=1Bo(4 zeuUvOE|#2m)ZcDTLwQ>BoWuHQl@)gHoU}&EXASx17#WkSUsL^~p$p^?;k#!?hp|r} zeL=4IV<1|wLM$W(I&K1eYmOxvkw4y8flv)o~EaRGT=p1M;O2QIpu& z|8;bbSowb}KwrQ>NL+7U6+8Q}&NDWiFR6tJ+IU&~J`*Pu7U5LabNm5%3qy~!g0@1* z3u{GniF;Vb&jH})z_z%!GbK4d_{Ptb`~E*dEX+;Gb(*Ri{JzFHaDhK)ASGYAS>4wR zm&;C^B7CbW_sR8!}cpn>8TPn9aZT8$WS}W z&tu7lUc&nEXg5@8+RLKp6-7xk&qsC8rj!Vr=6CU>a^(wM0&VQA|1B>%TX z0FGGivvED%!1%Xm9jgdBvd1OfUvR<|izP2Yc9Y-Bk|c9H2;9{ExMcJu-9hcrjheKl zp4jz&wo34*CzHYhWg1K*+H-AK+`w*WdIc;qZZ}(HsMW8q?SV#1MBl!e_^Y{dB_901 zF;Av}USnnAH-vECF_8+WAryfi@c11p3b@?Xnws?HE`1KnmZSfKmq=r49NgOanZ|%| zv&RT?i%VcD8Xx7L;hG_SwC^8^Q3|_X$NizeA}~J7SdT%jqSrvpxS&z#IuOK|AUR0S zdmR0}>E}FS)tr3tTzCeU5zwkeJ?aKV| zr6x2c0$3jP&%1KHT8}%aj!)s2vt-%MkPpDh>F$CZQ8*Tq<%rW#ZWxW zA7k1!q6jB^dLBanQ1nmFyW;CS@U1z?<|<)of>@$T(7K=mF&tWSj^-Xas5M3M(e7+? z#;U4X!%cE8*`^cGs*s{YlFYVio4V^Vm20S0yEu-_WD@I=G%fJ!vsTpREkbv4&g_W;@4wE$-ho`PFf2`w!eIgRmrn#V z{8vJ!Uc?sK=?N8F)qX8}Ep%2yY7TGPdcEQ;m zijvKRbDUkQ3EJjHuIDR0`mv6xZY%yt^d z9)uB3eKr>Ni^+z1O)BkNkz_0l1H++c7%~KI~MH^y}kYJNJfz)(b(U`E#S7IWHfDlE)~QZ ze}<@le)RSZ%89olDLBC+P5t?8>*j4z18ar)C2I5C7@x26KJq?u#$|`W+S<5SaUD2#pJ+5@QwYVK-~<&c?uvj2sAfVZ#mb_)zZ-k*{sZu7lhANg zPHyg))V%a_G7AtPr5KCB8oFV4)f9*xP`*1XaEpL?24Uy0{2@8d%~q8O`+(c0=l?9F zLZ7Qrx_)%KTOtG3iG2%>8SUgPIA4|hEMyhSSR2&+HLt8tR|;>d20XjzjAy%y>A+fY zCa8Hv+u5j3CzE}UywD!pY^&PLEZEt7p4!{{N7_hS&-M7yDKK!2p%-nl`OIi>2Cr+y zqVv}Ql%W`>VAXJ|W)naA1cUV)!ZLE*iTyN18B@fF#T5f@eQ)nj<`)8k*+grbto;@I nP<#_!T@!BPEEE*2SwMePrj$x3;NRCTs8s)B%0trqKmPm=N3$>; From 79e3aabbe97284bb8f2bb2fbc53b0d3aca89ebf0 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 10 Apr 2013 21:05:23 -0400 Subject: [PATCH 114/114] Add czm_antialias test. --- Specs/Renderer/BuiltinFunctionsSpec.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index 6152ba6ea0a1..7413d9da71e2 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -177,4 +177,15 @@ defineSuite([ verifyDraw(fs, uniformMap); }); + + it('has czm_antialias', function() { + var fs = + 'void main() {' + + ' vec4 color0 = vec4(1.0, 0.0, 0.0, 1.0);' + + ' vec4 color1 = vec4(0.0, 1.0, 0.0, 1.0);' + + ' vec4 result = czm_antialias(color0, color1, color1, 0.5);' + + ' gl_FragColor = vec4(result == color1);' + + '}'; + verifyDraw(fs); + }); }, 'WebGL'); \ No newline at end of file