From 0ef885ed30d46667c29d40e185b99ac614f4eed8 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Sat, 10 May 2014 09:19:51 -0400 Subject: [PATCH 01/22] First draft implementation of pervertex normals for quantized-mesh. Will need to update other meshes that use the CentralBody shaders. --- Source/Core/CesiumTerrainProvider.js | 6 +++ Source/Core/QuantizedMeshTerrainData.js | 5 ++ Source/Scene/terrainAttributeLocations.js | 2 +- .../Shaders/Builtin/Functions/octDecode.glsl | 19 ++++++++ .../Builtin/Functions/signNotZero.glsl | 29 +++++++++++ Source/Shaders/GlobeFS.glsl | 18 ++++--- Source/Shaders/GlobeVS.glsl | 22 ++++++--- .../createVerticesFromQuantizedTerrainMesh.js | 23 ++++++++- .../Workers/upsampleQuantizedTerrainMesh.js | 48 +++++++++++++++---- 9 files changed, 145 insertions(+), 27 deletions(-) create mode 100644 Source/Shaders/Builtin/Functions/octDecode.glsl create mode 100644 Source/Shaders/Builtin/Functions/signNotZero.glsl diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index 858a399ecd1a..334beefb2f38 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -195,6 +195,7 @@ define([ function createQuantizedMeshTerrainData(provider, buffer, level, x, y, tmsY) { var pos = 0; + var uint8Length = 1; var uint16Length = 2; var uint32Length = 4; var float32Length = 4; @@ -297,6 +298,10 @@ define([ var northIndices = new Uint16Array(buffer, pos, northVertexCount); pos += northVertexCount * uint16Length; + var encodedNormalBuffer; + encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); + pos += vertexCount * 2 * uint8Length; + var skirtHeight = provider.getLevelMaximumGeometricError(level) * 5.0; return new QuantizedMeshTerrainData({ @@ -306,6 +311,7 @@ define([ boundingSphere : boundingSphere, horizonOcclusionPoint : horizonOcclusionPoint, quantizedVertices : encodedVertexBuffer, + encodedNormals : encodedNormalBuffer, indices : indices, westIndices : westIndices, southIndices : southIndices, diff --git a/Source/Core/QuantizedMeshTerrainData.js b/Source/Core/QuantizedMeshTerrainData.js index 662a0f1a5e82..6210b2e9e244 100644 --- a/Source/Core/QuantizedMeshTerrainData.js +++ b/Source/Core/QuantizedMeshTerrainData.js @@ -39,6 +39,7 @@ define([ * @param {Uint16Array} options.quantizedVertices The buffer containing the quantized mesh. * @param {Uint16Array} options.indices The indices specifying how the quantized vertices are linked * together into triangles. Each three indices specifies one triangle. + * @param {Uint8Array} description.encodedNormals The buffer containing per vertex normals, encoded using 'oct' encoding * @param {Number} options.minimumHeight The minimum terrain height within the tile, in meters above the ellipsoid. * @param {Number} options.maximumHeight The maximum terrain height within the tile, in meters above the ellipsoid. * @param {BoundingSphere} options.boundingSphere A sphere bounding all of the vertices in the mesh. @@ -145,6 +146,7 @@ define([ //>>includeEnd('debug'); this._quantizedVertices = options.quantizedVertices; + this._encodedNormals = options.encodedNormals; this._indices = options.indices; this._minimumHeight = options.minimumHeight; this._maximumHeight = options.maximumHeight; @@ -251,6 +253,7 @@ define([ minimumHeight : this._minimumHeight, maximumHeight : this._maximumHeight, quantizedVertices : this._quantizedVertices, + octEncodedNormals : this._encodedNormals, indices : this._indices, westIndices : this._westIndices, southIndices : this._southIndices, @@ -338,6 +341,7 @@ define([ var upsamplePromise = upsampleTaskProcessor.scheduleTask({ vertices : this._quantizedVertices, indices : this._indices, + encodedNormals : this._encodedNormals, minimumHeight : this._minimumHeight, maximumHeight : this._maximumHeight, isEastChild : isEastChild, @@ -364,6 +368,7 @@ define([ return new QuantizedMeshTerrainData({ quantizedVertices : new Uint16Array(result.vertices), indices : new Uint16Array(result.indices), + encodedNormals : new Uint8Array(result.encodedNormals), minimumHeight : result.minimumHeight, maximumHeight : result.maximumHeight, boundingSphere : BoundingSphere.clone(result.boundingSphere), diff --git a/Source/Scene/terrainAttributeLocations.js b/Source/Scene/terrainAttributeLocations.js index a8bc1e12ee88..68dfa98670ba 100644 --- a/Source/Scene/terrainAttributeLocations.js +++ b/Source/Scene/terrainAttributeLocations.js @@ -3,6 +3,6 @@ define(function() { "use strict"; return { position3DAndHeight : 0, - textureCoordinates : 1 + textureCoordAndEncodedNormals : 1 }; }); diff --git a/Source/Shaders/Builtin/Functions/octDecode.glsl b/Source/Shaders/Builtin/Functions/octDecode.glsl new file mode 100644 index 000000000000..ca032233fa45 --- /dev/null +++ b/Source/Shaders/Builtin/Functions/octDecode.glsl @@ -0,0 +1,19 @@ +/** + * Decodes a unit-length vector in 'oct' encoding to a normalized 3-component Cartesian vector. + * The 'oct' encoding is described in "A Survey of Efficient Representations of Independent Unit Vectors", + * Cigolle et al 2014: http://jcgt.org/published/0003/02/01/ + * + * @name czm_octDecode + * @param {vec2} encoded The oct-encoded, unit-length vector + * @returns {vec3} The decoded and normalized vector + */ + vec3 czm_octDecode(vec2 encoded) + { + vec3 v = vec3(encoded.x, encoded.y, 1.0 - abs(encoded.x) - abs(encoded.y)); + if (v.z < 0.0) + { + v.xy = (1.0 - abs(v.yx)) * czm_signNotZero(v.xy); + } + + return normalize(v); + } diff --git a/Source/Shaders/Builtin/Functions/signNotZero.glsl b/Source/Shaders/Builtin/Functions/signNotZero.glsl new file mode 100644 index 000000000000..4901ea5cbdac --- /dev/null +++ b/Source/Shaders/Builtin/Functions/signNotZero.glsl @@ -0,0 +1,29 @@ +/** + * Returns 1.0 if the given value is positive or zero, and -1.0 if it is negative. This is similar to the GLSL + * built-in function sign except that returns 1.0 instead of 0.0 when the input value is 0.0. + * + * @name czm_signNotZero + * @glslFunction + * + * @param {} value The value for which to determine the sign. + * @returns {} 1.0 if the value is positive or zero, -1.0 if the value is negative. + */ +float czm_signNotZero(float value) +{ + return value >= 0.0 ? 1.0 : -1.0; +} + +vec2 czm_signNotZero(vec2 value) +{ + return vec2(czm_signNotZero(value.x), czm_signNotZero(value.y)); +} + +vec3 czm_signNotZero(vec3 value) +{ + return vec3(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z)); +} + +vec4 czm_signNotZero(vec4 value) +{ + return vec4(czm_signNotZero(value.x), czm_signNotZero(value.y), czm_signNotZero(value.z), czm_signNotZero(value.w)); +} \ No newline at end of file diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index e313a8eed3b2..4545fb1f0d6b 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -48,6 +48,7 @@ uniform vec2 u_lightingFadeDistance; varying vec3 v_positionMC; varying vec3 v_positionEC; varying vec2 v_textureCoordinates; +varying vec3 v_normal; vec3 sampleAndBlend( vec3 previousColor, @@ -128,7 +129,8 @@ void main() vec4 color = vec4(startDayColor, 1.0); #if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_LIGHTING) - vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates + //vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates + vec3 normalMC = normalize(v_normal); // normalized surface normal in model coordinates vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes #endif @@ -153,13 +155,15 @@ void main() #endif #ifdef ENABLE_LIGHTING - float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); - float cameraDist = length(czm_view[3]); - float fadeOutDist = u_lightingFadeDistance.x; - float fadeInDist = u_lightingFadeDistance.y; - float t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); - diffuseIntensity = mix(1.0, diffuseIntensity, t); + //float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); + //float cameraDist = length(czm_view[3]); + //float fadeOutDist = u_lightingFadeDistance.x; + //float fadeInDist = u_lightingFadeDistance.y; + //float t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); + //diffuseIntensity = mix(1.0, diffuseIntensity, t); + float diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 0.8 + 0.2; gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); + //gl_FragColor = vec4(v_normal, 1.0); #else gl_FragColor = color; #endif diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl index 538fb01548f4..8801ff61a57a 100644 --- a/Source/Shaders/GlobeVS.glsl +++ b/Source/Shaders/GlobeVS.glsl @@ -1,5 +1,5 @@ attribute vec4 position3DAndHeight; -attribute vec2 textureCoordinates; +attribute vec4 textureCoordAndEncodedNormals; uniform vec3 u_center3D; uniform mat4 u_modifiedModelView; @@ -13,6 +13,7 @@ varying vec3 v_positionMC; varying vec3 v_positionEC; varying vec2 v_textureCoordinates; +varying vec3 v_normal; // These functions are generated at runtime. vec4 getPosition(vec3 position3DWC); @@ -31,7 +32,7 @@ float get2DMercatorYPositionFraction() // when we're at this level or higher. The constant below is the expression // above evaluated and then rounded up at the 4th significant digit. const float maxTileWidth = 0.003068; - float positionFraction = textureCoordinates.y; + float positionFraction = textureCoordAndEncodedNormals.y; float southLatitude = u_southAndNorthLatitude.x; float northLatitude = u_southAndNorthLatitude.y; if (northLatitude - southLatitude > maxTileWidth) @@ -40,7 +41,7 @@ float get2DMercatorYPositionFraction() float southMercatorYHigh = u_southMercatorYLowAndHighAndOneOverHeight.y; float oneOverMercatorHeight = u_southMercatorYLowAndHighAndOneOverHeight.z; - float currentLatitude = mix(southLatitude, northLatitude, textureCoordinates.y); + float currentLatitude = mix(southLatitude, northLatitude, textureCoordAndEncodedNormals.y); currentLatitude = clamp(currentLatitude, -czm_webMercatorMaxLatitude, czm_webMercatorMaxLatitude); positionFraction = czm_latitudeToWebMercatorFraction(currentLatitude, southMercatorYLow, southMercatorYHigh, oneOverMercatorHeight); } @@ -49,13 +50,13 @@ float get2DMercatorYPositionFraction() float get2DGeographicYPositionFraction() { - return textureCoordinates.y; + return textureCoordAndEncodedNormals.y; } vec4 getPositionPlanarEarth(vec3 position3DWC, float height2D) { float yPositionFraction = get2DYPositionFraction(); - vec4 rtcPosition2D = vec4(height2D, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordinates.x, yPositionFraction)), 1.0); + vec4 rtcPosition2D = vec4(height2D, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordAndEncodedNormals.x, yPositionFraction)), 1.0); return czm_projection * (u_modifiedModelView * rtcPosition2D); } @@ -74,7 +75,7 @@ vec4 getPositionMorphingMode(vec3 position3DWC) // We do not do RTC while morphing, so there is potential for jitter. // This is unlikely to be noticeable, though. float yPositionFraction = get2DYPositionFraction(); - vec4 position2DWC = vec4(0.0, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordinates.x, yPositionFraction)), 1.0); + vec4 position2DWC = vec4(0.0, mix(u_tileRectangle.st, u_tileRectangle.pq, vec2(textureCoordAndEncodedNormals.x, yPositionFraction)), 1.0); vec4 morphPosition = czm_columbusViewMorph(position2DWC, vec4(position3DWC, 1.0), czm_morphTime); return czm_modelViewProjection * morphPosition; } @@ -88,7 +89,14 @@ void main() #if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_LIGHTING) v_positionEC = (czm_modelView3D * vec4(position3DWC, 1.0)).xyz; v_positionMC = position3DWC; // position in model coordinates + vec2 encodedNormal = textureCoordAndEncodedNormals.zw; + encodedNormal = encodedNormal / 255.0 * 2.0 - 1.0; + v_normal = czm_octDecode(encodedNormal); + //if (dot(v_normal, v_normal) < 0.9) + //{ + // v_normal = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates + //} #endif - v_textureCoordinates = textureCoordinates; + v_textureCoordinates = textureCoordAndEncodedNormals.xy; } diff --git a/Source/Workers/createVerticesFromQuantizedTerrainMesh.js b/Source/Workers/createVerticesFromQuantizedTerrainMesh.js index 393f053e46eb..8444e1373269 100644 --- a/Source/Workers/createVerticesFromQuantizedTerrainMesh.js +++ b/Source/Workers/createVerticesFromQuantizedTerrainMesh.js @@ -2,18 +2,20 @@ define([ '../Core/Cartesian3', '../Core/Cartographic', + '../Core/defined', '../Core/Ellipsoid', '../Core/Math', './createTaskProcessorWorker' ], function( Cartesian3, Cartographic, + defined, Ellipsoid, CesiumMath, createTaskProcessorWorker) { "use strict"; - var vertexStride = 6; + var vertexStride = 8; var maxShort = 32767; var xIndex = 0; @@ -22,13 +24,18 @@ define([ var hIndex = 3; var uIndex = 4; var vIndex = 5; + var nxIndex = 6; + var nyIndex = 7; var cartesian3Scratch = new Cartesian3(); + var cartesian3Scratch2 = new Cartesian3(); + var cartesian3Scratch3 = new Cartesian3(); var cartographicScratch = new Cartographic(); function createVerticesFromQuantizedTerrainMesh(parameters, transferableObjects) { var quantizedVertices = parameters.quantizedVertices; var quantizedVertexCount = quantizedVertices.length / 3; + var octEncodedNormals = parameters.octEncodedNormals; var edgeVertexCount = parameters.westIndices.length + parameters.eastIndices.length + parameters.southIndices.length + parameters.northIndices.length; var minimumHeight = parameters.minimumHeight; @@ -49,7 +56,7 @@ define([ var vertexBuffer = new Float32Array(quantizedVertexCount * vertexStride + edgeVertexCount * vertexStride); - for (var i = 0, bufferIndex = 0; i < quantizedVertexCount; ++i, bufferIndex += vertexStride) { + for (var i = 0, bufferIndex = 0, n = 0; i < quantizedVertexCount; ++i, bufferIndex += vertexStride, n += 2) { var u = uBuffer[i] / maxShort; var v = vBuffer[i] / maxShort; var height = CesiumMath.lerp(minimumHeight, maximumHeight, heightBuffer[i] / maxShort); @@ -66,6 +73,13 @@ define([ vertexBuffer[bufferIndex + hIndex] = height; vertexBuffer[bufferIndex + uIndex] = u; vertexBuffer[bufferIndex + vIndex] = v; + if (defined(octEncodedNormals)) { + vertexBuffer[bufferIndex + nxIndex] = octEncodedNormals[n]; + vertexBuffer[bufferIndex + nyIndex] = octEncodedNormals[n + 1]; + } else { + vertexBuffer[bufferIndex + nxIndex] = 0.0; + vertexBuffer[bufferIndex + nyIndex] = 0.0; + } } var edgeTriangleCount = Math.max(0, (edgeVertexCount - 4) * 2); @@ -108,12 +122,15 @@ define([ var vertexIndex = vertexBufferIndex / vertexStride; + for (var i = start; i !== end; i += increment) { var index = edgeVertices[i]; var offset = index * vertexStride; var u = vertexBuffer[offset + uIndex]; var v = vertexBuffer[offset + vIndex]; var h = vertexBuffer[offset + hIndex]; + var nx = vertexBuffer[offset + nxIndex]; + var ny = vertexBuffer[offset + nyIndex]; cartographicScratch.longitude = CesiumMath.lerp(rectangle.west, rectangle.east, u); cartographicScratch.latitude = CesiumMath.lerp(rectangle.south, rectangle.north, v); @@ -128,6 +145,8 @@ define([ vertexBuffer[vertexBufferIndex++] = cartographicScratch.height; vertexBuffer[vertexBufferIndex++] = u; vertexBuffer[vertexBufferIndex++] = v; + vertexBuffer[vertexBufferIndex++] = nx; + vertexBuffer[vertexBufferIndex++] = ny; if (previousIndex !== -1) { indexBuffer[indexBufferIndex++] = previousIndex; diff --git a/Source/Workers/upsampleQuantizedTerrainMesh.js b/Source/Workers/upsampleQuantizedTerrainMesh.js index c601559e2d27..ff85ebe73b2c 100644 --- a/Source/Workers/upsampleQuantizedTerrainMesh.js +++ b/Source/Workers/upsampleQuantizedTerrainMesh.js @@ -32,6 +32,7 @@ define([ var vScratch = []; var heightScratch = []; var indicesScratch = []; + var normalsScratch = []; var horizonOcclusionPointScratch = new Cartesian3(); var boundingSphereScratch = new BoundingSphere(); @@ -47,10 +48,12 @@ define([ var uBuffer = uScratch; var vBuffer = vScratch; var heightBuffer = heightScratch; + var normalBuffer = normalsScratch; uBuffer.length = 0; vBuffer.length = 0; heightBuffer.length = 0; + normalBuffer.length = 0; var indices = indicesScratch; indices.length = 0; @@ -58,6 +61,7 @@ define([ var vertexMap = {}; var parentVertices = parameters.vertices; + var parentNormalBuffer = parameters.encodedNormals; var parentIndices = parameters.indices; var quantizedVertexCount = parentVertices.length / 3; @@ -67,8 +71,8 @@ define([ var vertexCount = 0; - var i, u, v; - for (i = 0; i < quantizedVertexCount; ++i) { + var i, n, u, v; + for (i = 0, n = 0; i < quantizedVertexCount; ++i, n += 2) { u = parentUBuffer[i] / maxShort; v = parentVBuffer[i] / maxShort; if ((isEastChild && u >= 0.5 || !isEastChild && u <= 0.5) && @@ -78,6 +82,9 @@ define([ uBuffer.push(u); vBuffer.push(v); heightBuffer.push(parentHeightBuffer[i]); + normalBuffer.push(parentNormalBuffer[n]); + normalBuffer.push(parentNormalBuffer[n + 1]); + ++vertexCount; } } @@ -104,9 +111,9 @@ define([ var u1 = parentUBuffer[i1] / maxShort; var u2 = parentUBuffer[i2] / maxShort; - triangleVertices[0].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, i0); - triangleVertices[1].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, i1); - triangleVertices[2].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, i2); + triangleVertices[0].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, parentNormalBuffer, i0); + triangleVertices[1].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, parentNormalBuffer, i1); + triangleVertices[2].initializeIndexed(parentUBuffer, parentVBuffer, parentHeightBuffer, parentNormalBuffer, i2); // Clip triangle on the east-west boundary. var clipped = Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, isEastChild, u0, u1, u2, clipScratch); @@ -131,7 +138,7 @@ define([ // Clip the triangle against the North-south boundary. clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, isNorthChild, clippedTriangleVertices[0].getV(), clippedTriangleVertices[1].getV(), clippedTriangleVertices[2].getV(), clipScratch2); - addClippedPolygon(uBuffer, vBuffer, heightBuffer, indices, vertexMap, clipped2, clippedTriangleVertices); + addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices); // If there's another vertex in the original clipped result, // it forms a second triangle. Clip it as well. @@ -140,7 +147,7 @@ define([ clippedTriangleVertices[2].initializeFromClipResult(clipped, clippedIndex, triangleVertices); clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, isNorthChild, clippedTriangleVertices[0].getV(), clippedTriangleVertices[1].getV(), clippedTriangleVertices[2].getV(), clipScratch2); - addClippedPolygon(uBuffer, vBuffer, heightBuffer, indices, vertexMap, clipped2, clippedTriangleVertices); + addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices); } } @@ -238,10 +245,12 @@ define([ } var indicesTypedArray = new Uint16Array(indices); - transferableObjects.push(vertices.buffer, indicesTypedArray.buffer); + var normalArray = new Uint8Array(normalBuffer); + transferableObjects.push(vertices.buffer, indicesTypedArray.buffer, normalArray.buffer); return { vertices : vertices.buffer, + encodedNormals : normalArray.buffer, indices : indicesTypedArray.buffer, minimumHeight : minimumHeight, maximumHeight : maximumHeight, @@ -270,6 +279,7 @@ define([ result.uBuffer = this.uBuffer; result.vBuffer = this.vBuffer; result.heightBuffer = this.heightBuffer; + result.normalBuffer = this.normalBuffer; result.index = this.index; result.first = this.first; result.second = this.second; @@ -278,10 +288,11 @@ define([ return result; }; - Vertex.prototype.initializeIndexed = function(uBuffer, vBuffer, heightBuffer, index) { + Vertex.prototype.initializeIndexed = function(uBuffer, vBuffer, heightBuffer, normalBuffer, index) { this.uBuffer = uBuffer; this.vBuffer = vBuffer; this.heightBuffer = heightBuffer; + this.normalBuffer = normalBuffer; this.index = index; this.first = undefined; this.second = undefined; @@ -352,13 +363,27 @@ define([ return CesiumMath.lerp(this.first.getV(), this.second.getV(), this.ratio); }; + Vertex.prototype.getNormalX = function() { + if (defined(this.index)) { + return this.normalBuffer[this.index * 2]; + } + return CesiumMath.lerp(this.first.getNormalX(), this.second.getNormalX(), this.ratio); + }; + + Vertex.prototype.getNormalY = function() { + if (defined(this.index)) { + return this.normalBuffer[this.index * 2 + 1]; + } + return CesiumMath.lerp(this.first.getNormalY(), this.second.getNormalY(), this.ratio); + }; + var polygonVertices = []; polygonVertices.push(new Vertex()); polygonVertices.push(new Vertex()); polygonVertices.push(new Vertex()); polygonVertices.push(new Vertex()); - function addClippedPolygon(uBuffer, vBuffer, heightBuffer, indices, vertexMap, clipped, triangleVertices) { + function addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped, triangleVertices) { if (clipped.length === 0) { return; } @@ -380,6 +405,8 @@ define([ uBuffer.push(polygonVertex.getU()); vBuffer.push(polygonVertex.getV()); heightBuffer.push(polygonVertex.getH()); + normalBuffer.push(polygonVertex.getNormalX()); + normalBuffer.push(polygonVertex.getNormalY()); polygonVertex.newIndex = newIndex; vertexMap[key] = newIndex; } @@ -388,6 +415,7 @@ define([ polygonVertex.uBuffer = uBuffer; polygonVertex.vBuffer = vBuffer; polygonVertex.heightBuffer = heightBuffer; + polygonVertex.normalBuffer = normalBuffer; } } From 718bc01b1c79618dc006ad229200540efcaf2880 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Tue, 10 Jun 2014 16:46:11 -0400 Subject: [PATCH 02/22] Added new request headers to that specifies the content type as quantized-mesh or a quantized-mesh with vertex normals. Added flags to CesiumTerrainProvider that specify (1) should the client request vertex normals and (2) does the server have vertex normals. --- .../Core/ArcGisImageServerTerrainProvider.js | 11 +++ Source/Core/CesiumTerrainProvider.js | 75 +++++++++++++++++-- Source/Core/EllipsoidTerrainProvider.js | 11 +++ Source/Core/TerrainProvider.js | 10 +++ Source/Core/VRTheWorldTerrainProvider.js | 11 +++ Source/Scene/Globe.js | 6 +- 6 files changed, 118 insertions(+), 6 deletions(-) diff --git a/Source/Core/ArcGisImageServerTerrainProvider.js b/Source/Core/ArcGisImageServerTerrainProvider.js index 2642214b5682..ae81a4ff8e12 100644 --- a/Source/Core/ArcGisImageServerTerrainProvider.js +++ b/Source/Core/ArcGisImageServerTerrainProvider.js @@ -229,5 +229,16 @@ define([ return false; }; + /** + * Gets a value indicating whether or not the provider includes vertex normals + * + * @memberof ArcGisImageServerTerrainProvider + * + * @returns {Boolean} True if the provider has vertex normals; otherwise, false. + */ + ArcGisImageServerTerrainProvider.prototype.hasVertexNormals = function() { + return false; + }; + return ArcGisImageServerTerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index 334beefb2f38..ca40e5af58da 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -79,6 +79,8 @@ define([ this._heightmapStructure = undefined; this._hasWaterMask = false; + this._hasVertexNormals = false; // does the server provide vertex normals? + this._requestVertexNormals = defaultValue(options.requestVertexNormals, false); // does the client even want these normals? this._errorEvent = new Event(); @@ -144,6 +146,10 @@ define([ that._credit = new Credit(data.attribution); } + if (defined(data.extensions) && data.extensions.indexOf("vertexnormals") > -1) { + that._hasVertexNormals = true; + } + that._ready = true; } @@ -173,12 +179,23 @@ define([ requestMetadata(); }; - var requestHeaders = { - Accept : 'application/octet-stream,*/*;q=0.01' + var requestHeadersVertexNormals = { + // prefer quantized-mesh media-type + // only request vertex normals if Lighting is enabled on the CesiumTerrainProvider + Accept : 'application/vnd.quantized-mesh;extensions=vertexnormals,application/octet-stream;q=0.9,*/*;q=0.01' + }; + + function loadTileVertexNormals(url) { + return loadArrayBuffer(url, requestHeadersVertexNormals); + } + + var requestHeadersDefault = { + // prefer quantized-mesh media-type + Accept : 'application/vnd.quantized-mesh,application/octet-stream;q=0.9,*/*;q=0.01' }; function loadTile(url) { - return loadArrayBuffer(url, requestHeaders); + return loadArrayBuffer(url, requestHeadersDefault); } function createHeightmapTerrainData(provider, buffer, level, x, y, tmsY) { @@ -299,8 +316,15 @@ define([ pos += northVertexCount * uint16Length; var encodedNormalBuffer; + if (pos < view.byteLength) { + var extensionsflag = view.getInt8(pos); + pos += uint8Length; + + if (extensionsflag | 0x1) { encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); pos += vertexCount * 2 * uint8Length; + } + } var skirtHeight = provider.getLevelMaximumGeometricError(level) * 5.0; @@ -369,14 +393,19 @@ define([ var promise; + var tileLoader = loadTile; + if (this._requestVertexNormals && this._hasVertexNormals) { + tileLoader = loadTileVertexNormals; + } + throttleRequests = defaultValue(throttleRequests, true); if (throttleRequests) { - promise = throttleRequestByServer(url, loadTile); + promise = throttleRequestByServer(url, tileLoader); if (!defined(promise)) { return undefined; } } else { - promise = loadTile(url); + promise = tileLoader(url); } var that = this; @@ -448,6 +477,21 @@ define([ get : function() { return this._ready; } + }, + + /** + * Gets or sets a value indicating whether or to request vertex normals from the server. This + * property has no effect if {@link CesiumTerrainProvider#hasVertexNormals} is false. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + */ + requestVertexNormals : { + get : function() { + return this._requestVertexNormals; + }, + set : function(value) { + this._requestVertexNormals = value; + } } }); @@ -481,6 +525,27 @@ define([ return this._hasWaterMask; }; + /** + * Gets a value indicating whether or not vertex normals can be requested from the server. + * + * @memberof CesiumTerrainProvider + * + * @returns {Boolean} True if the provider has vertex normals; otherwise, false. + * + * @exception {DeveloperError} This function must not be called before {@link CesiumTerrainProvider#ready} + * returns true. + */ + CesiumTerrainProvider.prototype.hasVertexNormals = function() { + //>>includeStart('debug', pragmas.debug) + if (!this._ready) { + throw new DeveloperError('hasVertexNormals must not be called before the terrain provider is ready.'); + } + //>>includeEnd('debug'); + + // returns true if we can request vertex normals from the server + return this._hasVertexNormals && this._requestVertexNormals; + }; + function getChildMaskForTile(terrainProvider, level, x, y) { var available = terrainProvider._availableTiles; if (!available || available.length === 0) { diff --git a/Source/Core/EllipsoidTerrainProvider.js b/Source/Core/EllipsoidTerrainProvider.js index 73b7a2e1de0b..07f6f3a4f95e 100644 --- a/Source/Core/EllipsoidTerrainProvider.js +++ b/Source/Core/EllipsoidTerrainProvider.js @@ -151,5 +151,16 @@ define([ return false; }; + /** + * Gets a value indicating whether or not the provider includes vertex normals. + * + * @memberof EllipsoidTerrainProvider + * + * @returns {Boolean} True if the provider has vertex normals; otherwise, false. + */ + EllipsoidTerrainProvider.prototype.hasVertexNormals = function() { + return false; + }; + return EllipsoidTerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/TerrainProvider.js b/Source/Core/TerrainProvider.js index c8d2bbd3428c..dd82f7c29e70 100644 --- a/Source/Core/TerrainProvider.js +++ b/Source/Core/TerrainProvider.js @@ -181,5 +181,15 @@ define([ */ TerrainProvider.prototype.hasWaterMask = DeveloperError.throwInstantiationError; + /** + * Gets a value indicating whether or not the provider includes vertex normals. + * This function should not be called before {@link TerrainProvider#ready} returns true. + * @memberof TerrainProvider + * @function + * + * @returns {Boolean} True if the provider will supply vertex normals; otherwise, false. + */ + TerrainProvider.prototype.hasVertexNormals = DeveloperError.throwInstantiationError; + return TerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/VRTheWorldTerrainProvider.js b/Source/Core/VRTheWorldTerrainProvider.js index 2824ed13cb68..0d39c8c4f4c5 100644 --- a/Source/Core/VRTheWorldTerrainProvider.js +++ b/Source/Core/VRTheWorldTerrainProvider.js @@ -277,6 +277,17 @@ define([ return false; }; + /** + * Gets a value indicating whether or not the provider includes vertex normals. + * + * @memberof VRTheWorldTerrainProvider + * + * @returns {Boolean} True if the provider has vertex normals; otherwise, false. + */ + VRTheWorldTerrainProvider.prototype.hasVertexNormals = function() { + return false; + }; + var rectangleScratch = new Rectangle(); function getChildMask(provider, x, y, level) { diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 00124ed5a6c4..0d4404ab4267 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -252,6 +252,7 @@ define([ this._zoomedOutOceanSpecularIntensity = 0.5; this._showingPrettyOcean = false; this._hasWaterMask = false; + this._hasVertexNormals = false; this._lightingFadeDistance = new Cartesian2(this.lightingFadeOutDistance, this.lightingFadeInDistance); var that = this; @@ -666,7 +667,9 @@ define([ // Initial compile or re-compile if uber-shader parameters changed var hasWaterMask = this._surface._terrainProvider.ready && this._surface._terrainProvider.hasWaterMask(); + var hasVertexNormals = this._surface._terrainProvider.ready && this._surface._terrainProvider.hasVertexNormals(); var hasWaterMaskChanged = this._hasWaterMask !== hasWaterMask; + var hasVertexNormalsChanged = this._hasVertexNormals !== hasVertexNormalsChanged; var hasEnableLightingChanged = this._enableLighting !== this.enableLighting; if (!defined(this._surfaceShaderSet) || @@ -674,6 +677,7 @@ define([ !defined(this._southPoleCommand.shaderProgram) || modeChanged || hasWaterMaskChanged || + hasVertexNormalsChanged || hasEnableLightingChanged || (defined(this._oceanNormalMap)) !== this._showingPrettyOcean) { @@ -724,7 +728,7 @@ define([ defines : [ (hasWaterMask ? 'SHOW_REFLECTIVE_OCEAN' : ''), (showPrettyOcean ? 'SHOW_OCEAN_WAVES' : ''), - (this.enableLighting ? 'ENABLE_LIGHTING' : '') + (this.enableLighting && hasVertexNormals ? 'ENABLE_LIGHTING' : '') ], sources : [GlobeFS] }); From 1f31313d422233359229cfda1a762bc108b8a28f Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Mon, 16 Jun 2014 08:32:15 -0400 Subject: [PATCH 03/22] Minor cleanup. --- Source/Core/CesiumTerrainProvider.js | 45 ++++++++++++++-------------- Source/Shaders/GlobeVS.glsl | 4 --- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index ca40e5af58da..0638c76fca58 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -79,8 +79,20 @@ define([ this._heightmapStructure = undefined; this._hasWaterMask = false; - this._hasVertexNormals = false; // does the server provide vertex normals? - this._requestVertexNormals = defaultValue(options.requestVertexNormals, false); // does the client even want these normals? + + /** + * Boolean flag that indicates if the Terrain Server can provide vertex normals. + * @type {Boolean} + * @default false + * @private + */ + this._hasVertexNormals = false; + /** + * Boolean flag that indicates if the client should request vertex normals from the server. + * @type {Boolean} + * @default false + */ + this.requestVertexNormals = defaultValue(options.requestVertexNormals, false); this._errorEvent = new Event(); @@ -317,12 +329,12 @@ define([ var encodedNormalBuffer; if (pos < view.byteLength) { - var extensionsflag = view.getInt8(pos); + var extensionsflag = view.getUint8(pos); pos += uint8Length; - if (extensionsflag | 0x1) { - encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); - pos += vertexCount * 2 * uint8Length; + if (extensionsflag & 0x1) { + encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); + pos += vertexCount * 2 * uint8Length; } } @@ -394,7 +406,7 @@ define([ var promise; var tileLoader = loadTile; - if (this._requestVertexNormals && this._hasVertexNormals) { + if (this.requestVertexNormals && this._hasVertexNormals) { tileLoader = loadTileVertexNormals; } @@ -477,21 +489,6 @@ define([ get : function() { return this._ready; } - }, - - /** - * Gets or sets a value indicating whether or to request vertex normals from the server. This - * property has no effect if {@link CesiumTerrainProvider#hasVertexNormals} is false. - * @memberof CesiumTerrainProvider.prototype - * @type {Boolean} - */ - requestVertexNormals : { - get : function() { - return this._requestVertexNormals; - }, - set : function(value) { - this._requestVertexNormals = value; - } } }); @@ -527,6 +524,8 @@ define([ /** * Gets a value indicating whether or not vertex normals can be requested from the server. + * This requires that the both the server supports vertex normals and that the client is + * configured to {@link CesiumTerrainProvider#requestVertexNormals}. * * @memberof CesiumTerrainProvider * @@ -543,7 +542,7 @@ define([ //>>includeEnd('debug'); // returns true if we can request vertex normals from the server - return this._hasVertexNormals && this._requestVertexNormals; + return this._hasVertexNormals && this.requestVertexNormals; }; function getChildMaskForTile(terrainProvider, level, x, y) { diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl index 8801ff61a57a..05aebcfd69a0 100644 --- a/Source/Shaders/GlobeVS.glsl +++ b/Source/Shaders/GlobeVS.glsl @@ -92,10 +92,6 @@ void main() vec2 encodedNormal = textureCoordAndEncodedNormals.zw; encodedNormal = encodedNormal / 255.0 * 2.0 - 1.0; v_normal = czm_octDecode(encodedNormal); - //if (dot(v_normal, v_normal) < 0.9) - //{ - // v_normal = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates - //} #endif v_textureCoordinates = textureCoordAndEncodedNormals.xy; From d5f5e0503b09244b1d4a4d69a82a616ef2975035 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Mon, 16 Jun 2014 18:51:43 -0400 Subject: [PATCH 04/22] If no vertex normals are in the mesh, then do not add junk normal data to the vertex buffer. Fixed Globe shader so that day-night shading can be used again. --- Source/Core/QuantizedMeshTerrainData.js | 6 ++- Source/Scene/Globe.js | 7 +++- Source/Scene/TileTerrain.js | 15 +++++-- Source/Shaders/GlobeFS.glsl | 27 +++++++------ Source/Shaders/GlobeVS.glsl | 5 ++- .../createVerticesFromQuantizedTerrainMesh.js | 34 +++++++++------- .../Workers/upsampleQuantizedTerrainMesh.js | 39 ++++++++++++------- 7 files changed, 87 insertions(+), 46 deletions(-) diff --git a/Source/Core/QuantizedMeshTerrainData.js b/Source/Core/QuantizedMeshTerrainData.js index 6210b2e9e244..5d4cbfa045b5 100644 --- a/Source/Core/QuantizedMeshTerrainData.js +++ b/Source/Core/QuantizedMeshTerrainData.js @@ -365,10 +365,14 @@ define([ var northSkirtHeight = isNorthChild ? this._northSkirtHeight : (shortestSkirt * 0.5); return when(upsamplePromise, function(result) { + var encodedNormals; + if (defined(result.encodedNormals)) { + encodedNormals = new Uint8Array(result.encodedNormals); + } return new QuantizedMeshTerrainData({ quantizedVertices : new Uint16Array(result.vertices), indices : new Uint16Array(result.indices), - encodedNormals : new Uint8Array(result.encodedNormals), + encodedNormals : encodedNormals, minimumHeight : result.minimumHeight, maximumHeight : result.maximumHeight, boundingSphere : BoundingSphere.clone(result.boundingSphere), diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 0d4404ab4267..f96e45de1990 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -717,7 +717,8 @@ define([ this._surfaceShaderSet.baseVertexShaderString = createShaderSource({ defines : [ (hasWaterMask ? 'SHOW_REFLECTIVE_OCEAN' : ''), - (this.enableLighting ? 'ENABLE_LIGHTING' : '') + (this.enableLighting && !hasVertexNormals ? 'ENABLE_DAYNIGHT_SHADING' : ''), + (this.enableLighting && hasVertexNormals ? 'ENABLE_VERTEX_LIGHTING' : '') ], sources : [GlobeVS, getPositionMode, get2DYPositionFraction] }); @@ -728,7 +729,8 @@ define([ defines : [ (hasWaterMask ? 'SHOW_REFLECTIVE_OCEAN' : ''), (showPrettyOcean ? 'SHOW_OCEAN_WAVES' : ''), - (this.enableLighting && hasVertexNormals ? 'ENABLE_LIGHTING' : '') + (this.enableLighting && !hasVertexNormals ? 'ENABLE_DAYNIGHT_SHADING' : ''), + (this.enableLighting && hasVertexNormals ? 'ENABLE_VERTEX_LIGHTING' : '') ], sources : [GlobeFS] }); @@ -742,6 +744,7 @@ define([ this._showingPrettyOcean = defined(this._oceanNormalMap); this._hasWaterMask = hasWaterMask; + this._hasVertexNormals = hasVertexNormals; this._enableLighting = this.enableLighting; } diff --git a/Source/Scene/TileTerrain.js b/Source/Scene/TileTerrain.js index 4e848e39bb57..dec0c23c3270 100644 --- a/Source/Scene/TileTerrain.js +++ b/Source/Scene/TileTerrain.js @@ -207,9 +207,18 @@ define([ function createResources(tileTerrain, context, terrainProvider, x, y, level) { var datatype = ComponentDatatype.FLOAT; + var stride; + var numTexCoordComponents; var typedArray = tileTerrain.mesh.vertices; var buffer = context.createVertexBuffer(typedArray, BufferUsage.STATIC_DRAW); - var stride = 6 * ComponentDatatype.getSizeInBytes(datatype); + if (terrainProvider.hasVertexNormals()) { + stride = 8 * ComponentDatatype.getSizeInBytes(datatype); + numTexCoordComponents = 4; + } else { + stride = 6 * ComponentDatatype.getSizeInBytes(datatype); + numTexCoordComponents = 2; + } + var position3DAndHeightLength = 4; var attributes = [{ @@ -220,10 +229,10 @@ define([ offsetInBytes : 0, strideInBytes : stride }, { - index : terrainAttributeLocations.textureCoordinates, + index : terrainAttributeLocations.textureCoordAndEncodedNormals, vertexBuffer : buffer, componentDatatype : datatype, - componentsPerAttribute : 2, + componentsPerAttribute : numTexCoordComponents, offsetInBytes : position3DAndHeightLength * ComponentDatatype.getSizeInBytes(datatype), strideInBytes : stride }]; diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 4545fb1f0d6b..388e8c81b0e8 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -41,7 +41,7 @@ uniform float u_zoomedOutOceanSpecularIntensity; uniform sampler2D u_oceanNormalMap; #endif -#ifdef ENABLE_LIGHTING +#ifdef ENABLE_DAYNIGHT_SHADING uniform vec2 u_lightingFadeDistance; #endif @@ -128,9 +128,11 @@ void main() vec4 color = vec4(startDayColor, 1.0); -#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_LIGHTING) - //vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates - vec3 normalMC = normalize(v_normal); // normalized surface normal in model coordinates +#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) + vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates + vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes +#elif defined(ENABLE_VERTEX_LIGHTING) + vec3 normalMC = normalize(v_normal); // normalized surface normal in model coordinates vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes #endif @@ -154,16 +156,17 @@ void main() } #endif -#ifdef ENABLE_LIGHTING - //float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); - //float cameraDist = length(czm_view[3]); - //float fadeOutDist = u_lightingFadeDistance.x; - //float fadeInDist = u_lightingFadeDistance.y; - //float t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); - //diffuseIntensity = mix(1.0, diffuseIntensity, t); +#ifdef ENABLE_VERTEX_LIGHTING float diffuseIntensity = czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 0.8 + 0.2; gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); - //gl_FragColor = vec4(v_normal, 1.0); +#elif defined(ENABLE_DAYNIGHT_SHADING) + float diffuseIntensity = clamp(czm_getLambertDiffuse(czm_sunDirectionEC, normalEC) * 5.0 + 0.3, 0.0, 1.0); + float cameraDist = length(czm_view[3]); + float fadeOutDist = u_lightingFadeDistance.x; + float fadeInDist = u_lightingFadeDistance.y; + float t = clamp((cameraDist - fadeOutDist) / (fadeInDist - fadeOutDist), 0.0, 1.0); + diffuseIntensity = mix(1.0, diffuseIntensity, t); + gl_FragColor = vec4(color.rgb * diffuseIntensity, color.a); #else gl_FragColor = color; #endif diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl index 05aebcfd69a0..fdb57eec7932 100644 --- a/Source/Shaders/GlobeVS.glsl +++ b/Source/Shaders/GlobeVS.glsl @@ -86,7 +86,10 @@ void main() gl_Position = getPosition(position3DWC); -#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_LIGHTING) +#if defined(SHOW_REFLECTIVE_OCEAN) || defined(ENABLE_DAYNIGHT_SHADING) + v_positionEC = (czm_modelView3D * vec4(position3DWC, 1.0)).xyz; + v_positionMC = position3DWC; // position in model coordinates +#elif defined(ENABLE_VERTEX_LIGHTING) v_positionEC = (czm_modelView3D * vec4(position3DWC, 1.0)).xyz; v_positionMC = position3DWC; // position in model coordinates vec2 encodedNormal = textureCoordAndEncodedNormals.zw; diff --git a/Source/Workers/createVerticesFromQuantizedTerrainMesh.js b/Source/Workers/createVerticesFromQuantizedTerrainMesh.js index 8444e1373269..518560817d96 100644 --- a/Source/Workers/createVerticesFromQuantizedTerrainMesh.js +++ b/Source/Workers/createVerticesFromQuantizedTerrainMesh.js @@ -15,7 +15,6 @@ define([ createTaskProcessorWorker) { "use strict"; - var vertexStride = 8; var maxShort = 32767; var xIndex = 0; @@ -53,6 +52,12 @@ define([ var uBuffer = quantizedVertices.subarray(0, quantizedVertexCount); var vBuffer = quantizedVertices.subarray(quantizedVertexCount, 2 * quantizedVertexCount); var heightBuffer = quantizedVertices.subarray(quantizedVertexCount * 2, 3 * quantizedVertexCount); + var hasVertexNormals = defined(octEncodedNormals); + + var vertexStride = 6; + if (hasVertexNormals) { + vertexStride += 2; + } var vertexBuffer = new Float32Array(quantizedVertexCount * vertexStride + edgeVertexCount * vertexStride); @@ -73,12 +78,9 @@ define([ vertexBuffer[bufferIndex + hIndex] = height; vertexBuffer[bufferIndex + uIndex] = u; vertexBuffer[bufferIndex + vIndex] = v; - if (defined(octEncodedNormals)) { + if (hasVertexNormals) { vertexBuffer[bufferIndex + nxIndex] = octEncodedNormals[n]; vertexBuffer[bufferIndex + nyIndex] = octEncodedNormals[n + 1]; - } else { - vertexBuffer[bufferIndex + nxIndex] = 0.0; - vertexBuffer[bufferIndex + nyIndex] = 0.0; } } @@ -89,13 +91,13 @@ define([ // Add skirts. var vertexBufferIndex = quantizedVertexCount * vertexStride; var indexBufferIndex = parameters.indices.length; - indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.westIndices, center, ellipsoid, rectangle, parameters.westSkirtHeight, true); + indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.westIndices, center, ellipsoid, rectangle, parameters.westSkirtHeight, true, hasVertexNormals); vertexBufferIndex += parameters.westIndices.length * vertexStride; - indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.southIndices, center, ellipsoid, rectangle, parameters.southSkirtHeight, false); + indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.southIndices, center, ellipsoid, rectangle, parameters.southSkirtHeight, false, hasVertexNormals); vertexBufferIndex += parameters.southIndices.length * vertexStride; - indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.eastIndices, center, ellipsoid, rectangle, parameters.eastSkirtHeight, false); + indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.eastIndices, center, ellipsoid, rectangle, parameters.eastSkirtHeight, false, hasVertexNormals); vertexBufferIndex += parameters.eastIndices.length * vertexStride; - indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.northIndices, center, ellipsoid, rectangle, parameters.northSkirtHeight, true); + indexBufferIndex = addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, parameters.northIndices, center, ellipsoid, rectangle, parameters.northSkirtHeight, true, hasVertexNormals); vertexBufferIndex += parameters.northIndices.length * vertexStride; transferableObjects.push(vertexBuffer.buffer, indexBuffer.buffer); @@ -106,8 +108,12 @@ define([ }; } - function addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, edgeVertices, center, ellipsoid, rectangle, skirtLength, isWestOrNorthEdge) { + function addSkirt(vertexBuffer, vertexBufferIndex, indexBuffer, indexBufferIndex, edgeVertices, center, ellipsoid, rectangle, skirtLength, isWestOrNorthEdge, hasVertexNormals) { var start, end, increment; + var vertexStride = 6; + if (hasVertexNormals) { + vertexStride += 2; + } if (isWestOrNorthEdge) { start = edgeVertices.length - 1; end = -1; @@ -129,8 +135,6 @@ define([ var u = vertexBuffer[offset + uIndex]; var v = vertexBuffer[offset + vIndex]; var h = vertexBuffer[offset + hIndex]; - var nx = vertexBuffer[offset + nxIndex]; - var ny = vertexBuffer[offset + nyIndex]; cartographicScratch.longitude = CesiumMath.lerp(rectangle.west, rectangle.east, u); cartographicScratch.latitude = CesiumMath.lerp(rectangle.south, rectangle.north, v); @@ -145,8 +149,10 @@ define([ vertexBuffer[vertexBufferIndex++] = cartographicScratch.height; vertexBuffer[vertexBufferIndex++] = u; vertexBuffer[vertexBufferIndex++] = v; - vertexBuffer[vertexBufferIndex++] = nx; - vertexBuffer[vertexBufferIndex++] = ny; + if (hasVertexNormals) { + vertexBuffer[vertexBufferIndex++] = vertexBuffer[offset + nxIndex]; + vertexBuffer[vertexBufferIndex++] = vertexBuffer[offset + nyIndex]; + } if (previousIndex !== -1) { indexBuffer[indexBufferIndex++] = previousIndex; diff --git a/Source/Workers/upsampleQuantizedTerrainMesh.js b/Source/Workers/upsampleQuantizedTerrainMesh.js index ff85ebe73b2c..072bc718c9c6 100644 --- a/Source/Workers/upsampleQuantizedTerrainMesh.js +++ b/Source/Workers/upsampleQuantizedTerrainMesh.js @@ -70,6 +70,7 @@ define([ var parentHeightBuffer = parentVertices.subarray(quantizedVertexCount * 2, 3 * quantizedVertexCount); var vertexCount = 0; + var hasVertexNormals = defined(parentNormalBuffer); var i, n, u, v; for (i = 0, n = 0; i < quantizedVertexCount; ++i, n += 2) { @@ -82,8 +83,10 @@ define([ uBuffer.push(u); vBuffer.push(v); heightBuffer.push(parentHeightBuffer[i]); - normalBuffer.push(parentNormalBuffer[n]); - normalBuffer.push(parentNormalBuffer[n + 1]); + if (hasVertexNormals) { + normalBuffer.push(parentNormalBuffer[n]); + normalBuffer.push(parentNormalBuffer[n + 1]); + } ++vertexCount; } @@ -138,7 +141,7 @@ define([ // Clip the triangle against the North-south boundary. clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, isNorthChild, clippedTriangleVertices[0].getV(), clippedTriangleVertices[1].getV(), clippedTriangleVertices[2].getV(), clipScratch2); - addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices); + addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices, hasVertexNormals); // If there's another vertex in the original clipped result, // it forms a second triangle. Clip it as well. @@ -147,7 +150,7 @@ define([ clippedTriangleVertices[2].initializeFromClipResult(clipped, clippedIndex, triangleVertices); clipped2 = Intersections2D.clipTriangleAtAxisAlignedThreshold(0.5, isNorthChild, clippedTriangleVertices[0].getV(), clippedTriangleVertices[1].getV(), clippedTriangleVertices[2].getV(), clipScratch2); - addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices); + addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped2, clippedTriangleVertices, hasVertexNormals); } } @@ -245,12 +248,18 @@ define([ } var indicesTypedArray = new Uint16Array(indices); - var normalArray = new Uint8Array(normalBuffer); - transferableObjects.push(vertices.buffer, indicesTypedArray.buffer, normalArray.buffer); + var encodedNormals; + if (hasVertexNormals) { + var normalArray = new Uint8Array(normalBuffer); + transferableObjects.push(vertices.buffer, indicesTypedArray.buffer, normalArray.buffer); + encodedNormals = normalArray.buffer; + } else { + transferableObjects.push(vertices.buffer, indicesTypedArray.buffer); + } return { vertices : vertices.buffer, - encodedNormals : normalArray.buffer, + encodedNormals : encodedNormals, indices : indicesTypedArray.buffer, minimumHeight : minimumHeight, maximumHeight : maximumHeight, @@ -367,14 +376,14 @@ define([ if (defined(this.index)) { return this.normalBuffer[this.index * 2]; } - return CesiumMath.lerp(this.first.getNormalX(), this.second.getNormalX(), this.ratio); + return Math.round(CesiumMath.lerp(this.first.getNormalX(), this.second.getNormalX(), this.ratio)); }; Vertex.prototype.getNormalY = function() { if (defined(this.index)) { return this.normalBuffer[this.index * 2 + 1]; } - return CesiumMath.lerp(this.first.getNormalY(), this.second.getNormalY(), this.ratio); + return Math.round(CesiumMath.lerp(this.first.getNormalY(), this.second.getNormalY(), this.ratio)); }; var polygonVertices = []; @@ -383,7 +392,7 @@ define([ polygonVertices.push(new Vertex()); polygonVertices.push(new Vertex()); - function addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped, triangleVertices) { + function addClippedPolygon(uBuffer, vBuffer, heightBuffer, normalBuffer, indices, vertexMap, clipped, triangleVertices, hasVertexNormals) { if (clipped.length === 0) { return; } @@ -405,8 +414,10 @@ define([ uBuffer.push(polygonVertex.getU()); vBuffer.push(polygonVertex.getV()); heightBuffer.push(polygonVertex.getH()); - normalBuffer.push(polygonVertex.getNormalX()); - normalBuffer.push(polygonVertex.getNormalY()); + if (hasVertexNormals) { + normalBuffer.push(polygonVertex.getNormalX()); + normalBuffer.push(polygonVertex.getNormalY()); + } polygonVertex.newIndex = newIndex; vertexMap[key] = newIndex; } @@ -415,7 +426,9 @@ define([ polygonVertex.uBuffer = uBuffer; polygonVertex.vBuffer = vBuffer; polygonVertex.heightBuffer = heightBuffer; - polygonVertex.normalBuffer = normalBuffer; + if (hasVertexNormals) { + polygonVertex.normalBuffer = normalBuffer; + } } } From 37a7c2bdd3092cbb963b13947a8f2725aabe1287 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Mon, 23 Jun 2014 17:15:13 -0400 Subject: [PATCH 05/22] Updated hasWaterMask and hasVertexNormals to be properties. --- .../Core/ArcGisImageServerTerrainProvider.js | 48 ++++++----- Source/Core/CesiumTerrainProvider.js | 86 +++++++++---------- Source/Core/EllipsoidTerrainProvider.js | 48 ++++++----- Source/Core/QuantizedMeshTerrainData.js | 2 +- Source/Core/TerrainProvider.js | 42 ++++----- Source/Core/VRTheWorldTerrainProvider.js | 48 ++++++----- Source/Scene/Globe.js | 6 +- Source/Scene/Tile.js | 2 +- Source/Scene/TileTerrain.js | 2 +- .../ArcGisImageServerTerrainProviderSpec.js | 2 +- Specs/Core/CesiumTerrainProviderSpec.js | 40 ++++++++- Specs/Core/VRTheWorldTerrainProviderSpec.js | 2 +- .../VertexNormals.tile.json | 30 +++++++ Specs/Scene/TileSpec.js | 4 +- 14 files changed, 220 insertions(+), 142 deletions(-) create mode 100644 Specs/Data/CesiumTerrainTileJson/VertexNormals.tile.json diff --git a/Source/Core/ArcGisImageServerTerrainProvider.js b/Source/Core/ArcGisImageServerTerrainProvider.js index ae81a4ff8e12..8cc9217ca862 100644 --- a/Source/Core/ArcGisImageServerTerrainProvider.js +++ b/Source/Core/ArcGisImageServerTerrainProvider.js @@ -149,6 +149,32 @@ define([ get : function() { return true; } + }, + + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link ArcGisImageServerTerrainProvider#ready} returns true. + * @memberof ArcGisImageServerTerrainProvider.prototype + * @type {Boolean} + */ + hasWaterMask : { + get : function() { + return false; + } + }, + + /** + * Gets a value indicating whether or not the requested tiles includes vertex normals. + * This function should not be called before {@link ArcGisImageServerTerrainProvider#ready} returns true. + * @memberof ArcGisImageServerTerrainProvider.prototype + * @type {Boolean} + */ + hasVertexNormals : { + get : function() { + return false; + } } }); @@ -218,27 +244,5 @@ define([ return this._levelZeroMaximumGeometricError / (1 << level); }; - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. - * - * @returns {Boolean} True if the provider has a water mask; otherwise, false. - */ - ArcGisImageServerTerrainProvider.prototype.hasWaterMask = function() { - return false; - }; - - /** - * Gets a value indicating whether or not the provider includes vertex normals - * - * @memberof ArcGisImageServerTerrainProvider - * - * @returns {Boolean} True if the provider has vertex normals; otherwise, false. - */ - ArcGisImageServerTerrainProvider.prototype.hasVertexNormals = function() { - return false; - }; - return ArcGisImageServerTerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index 0638c76fca58..c679fdadd60f 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -158,7 +158,7 @@ define([ that._credit = new Credit(data.attribution); } - if (defined(data.extensions) && data.extensions.indexOf("vertexnormals") > -1) { + if (defined(data.extensions) && data.extensions.indexOf('vertexnormals') !== -1) { that._hasVertexNormals = true; } @@ -489,6 +489,47 @@ define([ get : function() { return this._ready; } + }, + + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link CesiumTerrainProvider#ready} returns true. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} + */ + hasWaterMask : { + get : function() { + //>>includeStart('debug', pragmas.debug) + if (!this._ready) { + throw new DeveloperError('hasWaterMask must not be called before the terrain provider is ready.'); + } + //>>includeEnd('debug'); + + return this._hasWaterMask; + } + }, + + /** + * Gets a value indicating whether or not the requested tiles includes vertex normals. + * This function should not be called before {@link CesiumTerrainProvider#ready} returns true. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + * @exception {DeveloperError} This property must not be called before {@link CesiumTerrainProvider#ready} + */ + hasVertexNormals : { + get : function() { + //>>includeStart('debug', pragmas.debug) + if (!this._ready) { + throw new DeveloperError('hasVertexNormals must not be called before the terrain provider is ready.'); + } + //>>includeEnd('debug'); + + // returns true if we can request vertex normals from the server + return this._hasVertexNormals && this.requestVertexNormals; + } } }); @@ -502,49 +543,6 @@ define([ return this._levelZeroMaximumGeometricError / (1 << level); }; - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. - * - * @returns {Boolean} True if the provider has a water mask; otherwise, false. - * - * @exception {DeveloperError} This function must not be called before {@link CesiumTerrainProvider#ready} - * returns true. - */ - CesiumTerrainProvider.prototype.hasWaterMask = function() { - //>>includeStart('debug', pragmas.debug) - if (!this._ready) { - throw new DeveloperError('hasWaterMask must not be called before the terrain provider is ready.'); - } - //>>includeEnd('debug'); - - return this._hasWaterMask; - }; - - /** - * Gets a value indicating whether or not vertex normals can be requested from the server. - * This requires that the both the server supports vertex normals and that the client is - * configured to {@link CesiumTerrainProvider#requestVertexNormals}. - * - * @memberof CesiumTerrainProvider - * - * @returns {Boolean} True if the provider has vertex normals; otherwise, false. - * - * @exception {DeveloperError} This function must not be called before {@link CesiumTerrainProvider#ready} - * returns true. - */ - CesiumTerrainProvider.prototype.hasVertexNormals = function() { - //>>includeStart('debug', pragmas.debug) - if (!this._ready) { - throw new DeveloperError('hasVertexNormals must not be called before the terrain provider is ready.'); - } - //>>includeEnd('debug'); - - // returns true if we can request vertex normals from the server - return this._hasVertexNormals && this.requestVertexNormals; - }; - function getChildMaskForTile(terrainProvider, level, x, y) { var available = terrainProvider._availableTiles; if (!available || available.length === 0) { diff --git a/Source/Core/EllipsoidTerrainProvider.js b/Source/Core/EllipsoidTerrainProvider.js index 07f6f3a4f95e..c38f89bded6a 100644 --- a/Source/Core/EllipsoidTerrainProvider.js +++ b/Source/Core/EllipsoidTerrainProvider.js @@ -108,6 +108,32 @@ define([ get : function() { return true; } + }, + + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link EllipsoidTerrainProvider#ready} returns true. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Boolean} + */ + hasWaterMask : { + get : function() { + return false; + } + }, + + /** + * Gets a value indicating whether or not the requested tiles includes vertex normals. + * This function should not be called before {@link EllipsoidTerrainProvider#ready} returns true. + * @memberof EllipsoidTerrainProvider.prototype + * @type {Boolean} + */ + hasVertexNormals : { + get : function() { + return false; + } } }); @@ -140,27 +166,5 @@ define([ return this._levelZeroMaximumGeometricError / (1 << level); }; - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. - * - * @returns {Boolean} True if the provider has a water mask; otherwise, false. - */ - EllipsoidTerrainProvider.prototype.hasWaterMask = function() { - return false; - }; - - /** - * Gets a value indicating whether or not the provider includes vertex normals. - * - * @memberof EllipsoidTerrainProvider - * - * @returns {Boolean} True if the provider has vertex normals; otherwise, false. - */ - EllipsoidTerrainProvider.prototype.hasVertexNormals = function() { - return false; - }; - return EllipsoidTerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/QuantizedMeshTerrainData.js b/Source/Core/QuantizedMeshTerrainData.js index 5d4cbfa045b5..e8605f15d72a 100644 --- a/Source/Core/QuantizedMeshTerrainData.js +++ b/Source/Core/QuantizedMeshTerrainData.js @@ -39,7 +39,7 @@ define([ * @param {Uint16Array} options.quantizedVertices The buffer containing the quantized mesh. * @param {Uint16Array} options.indices The indices specifying how the quantized vertices are linked * together into triangles. Each three indices specifies one triangle. - * @param {Uint8Array} description.encodedNormals The buffer containing per vertex normals, encoded using 'oct' encoding + * @param {Uint8Array} options.encodedNormals The buffer containing per vertex normals, encoded using 'oct' encoding * @param {Number} options.minimumHeight The minimum terrain height within the tile, in meters above the ellipsoid. * @param {Number} options.maximumHeight The maximum terrain height within the tile, in meters above the ellipsoid. * @param {BoundingSphere} options.boundingSphere A sphere bounding all of the vertices in the mesh. diff --git a/Source/Core/TerrainProvider.js b/Source/Core/TerrainProvider.js index dd82f7c29e70..0af3b6f18cc9 100644 --- a/Source/Core/TerrainProvider.js +++ b/Source/Core/TerrainProvider.js @@ -65,6 +65,27 @@ define([ */ ready : { get : DeveloperError.throwInstantiationError + }, + + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link TerrainProvider#ready} returns true. + * @type {Boolean} + */ + hasWaterMask : { + get : DeveloperError.throwInstantiationError + }, + + /** + * Gets a value indicating whether or not the requested tiles includes vertex normals. + * This function should not be called before {@link TerrainProvider#ready} returns true. + * @memberof TerrainProvider.prototype + * @type {Boolean} + */ + hasVertexNormals : { + get : DeveloperError.throwInstantiationError } }); @@ -170,26 +191,5 @@ define([ */ TerrainProvider.prototype.getLevelMaximumGeometricError = DeveloperError.throwInstantiationError; - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. This function should not be - * called before {@link TerrainProvider#ready} returns true. - * @function - * - * @returns {Boolean} True if the provider has a water mask; otherwise, false. - */ - TerrainProvider.prototype.hasWaterMask = DeveloperError.throwInstantiationError; - - /** - * Gets a value indicating whether or not the provider includes vertex normals. - * This function should not be called before {@link TerrainProvider#ready} returns true. - * @memberof TerrainProvider - * @function - * - * @returns {Boolean} True if the provider will supply vertex normals; otherwise, false. - */ - TerrainProvider.prototype.hasVertexNormals = DeveloperError.throwInstantiationError; - return TerrainProvider; }); \ No newline at end of file diff --git a/Source/Core/VRTheWorldTerrainProvider.js b/Source/Core/VRTheWorldTerrainProvider.js index 0d39c8c4f4c5..524b63219fd9 100644 --- a/Source/Core/VRTheWorldTerrainProvider.js +++ b/Source/Core/VRTheWorldTerrainProvider.js @@ -198,6 +198,32 @@ define([ get : function() { return this._ready; } + }, + + /** + * Gets a value indicating whether or not the provider includes a water mask. The water mask + * indicates which areas of the globe are water rather than land, so they can be rendered + * as a reflective surface with animated waves. This function should not be + * called before {@link VRTheWorldTerrainProvider#ready} returns true. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Boolean} + */ + hasWaterMask : { + get : function() { + return false; + } + }, + + /** + * Gets a value indicating whether or not the requested tiles includes vertex normals. + * This function should not be called before {@link VRTheWorldTerrainProvider#ready} returns true. + * @memberof VRTheWorldTerrainProvider.prototype + * @type {Boolean} + */ + hasVertexNormals : { + get : function() { + return false; + } } }); @@ -266,28 +292,6 @@ define([ return this._levelZeroMaximumGeometricError / (1 << level); }; - /** - * Gets a value indicating whether or not the provider includes a water mask. The water mask - * indicates which areas of the globe are water rather than land, so they can be rendered - * as a reflective surface with animated waves. - * - * @returns {Boolean} True if the provider has a water mask; otherwise, false. - */ - VRTheWorldTerrainProvider.prototype.hasWaterMask = function() { - return false; - }; - - /** - * Gets a value indicating whether or not the provider includes vertex normals. - * - * @memberof VRTheWorldTerrainProvider - * - * @returns {Boolean} True if the provider has vertex normals; otherwise, false. - */ - VRTheWorldTerrainProvider.prototype.hasVertexNormals = function() { - return false; - }; - var rectangleScratch = new Rectangle(); function getChildMask(provider, x, y, level) { diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index f96e45de1990..275adbf417dd 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -651,7 +651,7 @@ define([ } if (this._surface._terrainProvider.ready && - this._surface._terrainProvider.hasWaterMask() && + this._surface._terrainProvider.hasWaterMask && this.oceanNormalMapUrl !== this._lastOceanNormalMapUrl) { this._lastOceanNormalMapUrl = this.oceanNormalMapUrl; @@ -666,8 +666,8 @@ define([ } // Initial compile or re-compile if uber-shader parameters changed - var hasWaterMask = this._surface._terrainProvider.ready && this._surface._terrainProvider.hasWaterMask(); - var hasVertexNormals = this._surface._terrainProvider.ready && this._surface._terrainProvider.hasVertexNormals(); + var hasWaterMask = this._surface._terrainProvider.ready && this._surface._terrainProvider.hasWaterMask; + var hasVertexNormals = this._surface._terrainProvider.ready && this._surface._terrainProvider.hasVertexNormals; var hasWaterMaskChanged = this._hasWaterMask !== hasWaterMask; var hasVertexNormalsChanged = this._hasVertexNormals !== hasVertexNormalsChanged; var hasEnableLightingChanged = this._enableLighting !== this.enableLighting; diff --git a/Source/Scene/Tile.js b/Source/Scene/Tile.js index ab5415df0b65..e9b2366afe14 100644 --- a/Source/Scene/Tile.js +++ b/Source/Scene/Tile.js @@ -566,7 +566,7 @@ define([ // If the terrain provider has a water mask, "upsample" that as well // by computing texture translation and scale. - if (terrainProvider.hasWaterMask()) { + if (terrainProvider.hasWaterMask) { upsampleWaterMask(tile, context); } diff --git a/Source/Scene/TileTerrain.js b/Source/Scene/TileTerrain.js index dec0c23c3270..39111a94b87d 100644 --- a/Source/Scene/TileTerrain.js +++ b/Source/Scene/TileTerrain.js @@ -211,7 +211,7 @@ define([ var numTexCoordComponents; var typedArray = tileTerrain.mesh.vertices; var buffer = context.createVertexBuffer(typedArray, BufferUsage.STATIC_DRAW); - if (terrainProvider.hasVertexNormals()) { + if (terrainProvider.hasVertexNormals) { stride = 8 * ComponentDatatype.getSizeInBytes(datatype); numTexCoordComponents = 4; } else { diff --git a/Specs/Core/ArcGisImageServerTerrainProviderSpec.js b/Specs/Core/ArcGisImageServerTerrainProviderSpec.js index 7b1f97760f07..b33f4d1c1edf 100644 --- a/Specs/Core/ArcGisImageServerTerrainProviderSpec.js +++ b/Specs/Core/ArcGisImageServerTerrainProviderSpec.js @@ -103,7 +103,7 @@ defineSuite([ var provider = new ArcGisImageServerTerrainProvider({ url : 'made/up/url' }); - expect(provider.hasWaterMask()).toBe(false); + expect(provider.hasWaterMask).toBe(false); }); it('is ready immediately', function() { diff --git a/Specs/Core/CesiumTerrainProviderSpec.js b/Specs/Core/CesiumTerrainProviderSpec.js index 2d6a6ea1e519..8dd244ca79cc 100644 --- a/Specs/Core/CesiumTerrainProviderSpec.js +++ b/Specs/Core/CesiumTerrainProviderSpec.js @@ -55,6 +55,10 @@ defineSuite([ return returnTileJson('Data/CesiumTerrainTileJson/QuantizedMesh1.1.tile.json'); } + function returnVertexNormalTileJson() { + return returnTileJson('Data/CesiumTerrainTileJson/VertexNormals.tile.json'); + } + it('conforms to TerrainProvider interface', function() { expect(CesiumTerrainProvider).toConformToInterface(TerrainProvider); }); @@ -150,7 +154,41 @@ defineSuite([ }); runs(function() { - expect(provider.hasWaterMask()).toBe(true); + expect(provider.hasWaterMask).toBe(true); + }); + }); + + it('has vertex normals', function() { + returnVertexNormalTileJson(); + + var provider = new CesiumTerrainProvider({ + url : 'made/up/url', + requestVertexNormals : true + }); + + waitsFor(function() { + return provider.ready; + }); + + runs(function() { + expect(provider.hasVertexNormals).toBe(true); + }); + }); + + it('does not request vertex normals', function() { + returnVertexNormalTileJson(); + + var provider = new CesiumTerrainProvider({ + url : 'made/up/url', + requestVertexNormals : false + }); + + waitsFor(function() { + return provider.ready; + }); + + runs(function() { + expect(provider.hasVertexNormals).toBe(false); }); }); diff --git a/Specs/Core/VRTheWorldTerrainProviderSpec.js b/Specs/Core/VRTheWorldTerrainProviderSpec.js index 673f8aa37d01..ee1cb4a9cd4b 100644 --- a/Specs/Core/VRTheWorldTerrainProviderSpec.js +++ b/Specs/Core/VRTheWorldTerrainProviderSpec.js @@ -137,7 +137,7 @@ defineSuite([ var provider = new VRTheWorldTerrainProvider({ url : 'made/up/url' }); - expect(provider.hasWaterMask()).toBe(false); + expect(provider.hasWaterMask).toBe(false); }); it('is not ready immediately', function() { diff --git a/Specs/Data/CesiumTerrainTileJson/VertexNormals.tile.json b/Specs/Data/CesiumTerrainTileJson/VertexNormals.tile.json new file mode 100644 index 000000000000..716f4ee60ac1 --- /dev/null +++ b/Specs/Data/CesiumTerrainTileJson/VertexNormals.tile.json @@ -0,0 +1,30 @@ +{ + "tilejson": "2.1.0", + "format" : "quantized-mesh-1.0", + "version" : "1.0.0", + "scheme" : "tms", + "tiles" : [ + "{z}/{x}/{y}.terrain?v={version}" + ], + "extensions" : [ + "vertexnormals" + ], + "available" : [ + [ + { + "startX" : 0, + "startY" : 0, + "endX" : 1, + "endY" : 0 + } + ], + [ + { + "startX" : 0, + "startY" : 0, + "endX" : 3, + "endY" : 1 + } + ] + ] +} diff --git a/Specs/Scene/TileSpec.js b/Specs/Scene/TileSpec.js index d27465c365cc..7679e86b77ec 100644 --- a/Specs/Scene/TileSpec.js +++ b/Specs/Scene/TileSpec.js @@ -583,7 +583,7 @@ defineSuite([ }, tilingScheme : realTerrainProvider.tilingScheme, hasWaterMask : function() { - return realTerrainProvider.hasWaterMask(); + return realTerrainProvider.hasWaterMask; } }; @@ -620,7 +620,7 @@ defineSuite([ }, tilingScheme : realTerrainProvider.tilingScheme, hasWaterMask : function() { - return realTerrainProvider.hasWaterMask(); + return realTerrainProvider.hasWaterMask; } }; From e9c1376e2924c5df279967cd131131bceffa661b Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Tue, 24 Jun 2014 10:38:36 -0400 Subject: [PATCH 06/22] Added unit test to load QuantizedMeshTerrainData with VertexNormals. --- Specs/Core/CesiumTerrainProviderSpec.js | 38 ++++++++++++++++++ .../tile.vertexnormals.terrain | Bin 0 -> 4253 bytes 2 files changed, 38 insertions(+) create mode 100644 Specs/Data/CesiumTerrainTileJson/tile.vertexnormals.terrain diff --git a/Specs/Core/CesiumTerrainProviderSpec.js b/Specs/Core/CesiumTerrainProviderSpec.js index 8dd244ca79cc..7eea6712070b 100644 --- a/Specs/Core/CesiumTerrainProviderSpec.js +++ b/Specs/Core/CesiumTerrainProviderSpec.js @@ -444,6 +444,44 @@ defineSuite([ }); }); + it('provides QuantizedMeshTerrainData with VertexNormals', function() { + var baseUrl = 'made/up/url'; + + loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + return loadWithXhr.defaultLoad('Data/CesiumTerrainTileJson/tile.vertexnormals.terrain', responseType, method, data, headers, deferred); + }; + + returnVertexNormalTileJson(); + + var terrainProvider = new CesiumTerrainProvider({ + url : baseUrl, + requestVertexNormals : true + }); + + waitsFor(function() { + return terrainProvider.ready; + }); + + var loadedData; + + runs(function() { + var promise = terrainProvider.requestTileGeometry(0, 0, 0); + + when(promise, function(terrainData) { + loadedData = terrainData; + }); + }); + + waitsFor(function() { + return defined(loadedData); + }, 'request to complete'); + + runs(function() { + expect(loadedData).toBeInstanceOf(QuantizedMeshTerrainData); + expect(loadedData._encodedNormals).toBeDefined(); + }); + }); + it('returns undefined if too many requests are already in progress', function() { var baseUrl = 'made/up/url'; diff --git a/Specs/Data/CesiumTerrainTileJson/tile.vertexnormals.terrain b/Specs/Data/CesiumTerrainTileJson/tile.vertexnormals.terrain new file mode 100644 index 0000000000000000000000000000000000000000..78ab2fe0b3c36b00fd42c9b4aad61b92c6e56444 GIT binary patch literal 4253 zcmY*b3s6+o8UD|`yX>;C%d)#Hi;9au6x8yRV08r45R0H>q7e)}(3bHLBOs#DAQHz( z(8fIKOh(ffYg(N)jx@G)Y$utjsY!g4HXS3)*fwcmAJOR~)wW^k%yRpE=Rj@mopbIv z|No!=b-w?cd-BNhLk9=%&K8mC<4c;(o~id zrBdZ&I%$cj;S7mLRL03f5ho($lH>Sgk(2L4oq%IG5l1M87rkUTLCKMz6gXbYW{6h; z;7`LEk5eQuEfsdc666TnV#vlY%EwqR_Bvt5*4omXIHjZ*+!^==$<;D$NI+KGqn0~D2!)ZEF z0XbwY`8dX@|cUm|bVm+)!6Puz*L;WRW4B0*%1 z2lAG9kQ*1gMr_DsSZr~F>jpRESkRe{k$ISHtU(m%v<%yp1Ym`Fm>F=9X&Y;dZk-*D z>9bxtPEyGQjoxxkJXlTnI5Q8q6dEmvwSY9+M8KkqNR$ z&6E|YPv)tEa#tFx5?Lvg>H~0Q$VNFRH{>UBR@SNws!cAbpR2fv%YCXudaO$EtM_G_ z)Jco_SSG3^7>hb$T~vo$JyIb{MeN)1Q>$CDL77y_T*=h!N%)^? zos%Q-M;Vawa#J3cJ8D4XVp}TIEAn0S7x}B&iup9vE)OA=h|EJNzNfmSO{(DWF*zhl zzV?M4j{^AC&<1@8orPTEcQlo|IYAFT1Uy zlCHAU4`i`~RGqcl)#iFl^(nZa9}7Jj$_cMROau-aA#9D z(p>97qqIUXj?%rF&NZY1lDbd9N+aun&j2BsrN0XBvskKlC=u2gk#Jj0lG<`Y?E$MG8JdaGf*kY9DBbAII$9N-RiDl%BPU9Huui}IuW%Ln?W=E)-NT(IzfH)+|i9H*d zshhi=0v`8;5!~B<#zIQEj?d(dRb?Wg7GjUtBEtCCdY_mx;@j+#7gX9banKW5Oht|q zn#mb6Mh;I2LuZDGIg>f^qM$@|b!9--puGTeUi<}mHTRS{1UHU_v)kmC9^!Ha)y5B- z$rB|@Fe8=G5W!q&;~px-oz#qRDS9K#eg*hkr7&8Fz7sskTe!D6(Oc-ZfELz!!W}o( zGr)kp z88%*;oBG}@og^>9M}?lx0gS$no+x3qjb4s;K2VPONoU@TF2m)n5}mZ`!T$|C?niqA zukoEZ;X_G!PTWziK?`wbV!9%iHQ&}>C08JMSuV+Gd@mukiCCpj1^MXn@Z~=VcgP37 zU&4RgQP{mEzmN;^j{FjrShR{gg5`s1IiKeOh1+d#*O)d!jnui3k_XXaD2y-m-x_O`y-dSb)r zwzsyv+cmiLldd~mx7QA}e*VZ%;}`W`)_z_+RQ1L5yXAKZ{*`xX+v{D&x{tQMy!BgM z`?u}i{!-i19UVKjw6}Jw-QLx*aox7X>ld$Ey=L{YuI7!)cGhjK+qtB*dD;2}owY3s zH&=bV`q8hzjG}f%EdaAm!rlq`X#y9HgA835Ia$QM#d2eA|`TUy7#gjG_w#=%T z)>ybOYi;hzi9H#+te(({+=Y{CCe9o?-)^=x1Q%t@&YhlFY*z=$tkd3KPv89?Flt?z literal 0 HcmV?d00001 From 0a1d820e4296e732f5b309d65b844b5ea10654ec Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Mon, 30 Jun 2014 13:55:35 -0400 Subject: [PATCH 07/22] Added unit test to test rendering of quantized-mesh terrain with lighting enabled. --- Specs/Scene/GlobeSpec.js | 58 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/Specs/Scene/GlobeSpec.js b/Specs/Scene/GlobeSpec.js index ec3224a38bf9..bc5a0456fb31 100644 --- a/Specs/Scene/GlobeSpec.js +++ b/Specs/Scene/GlobeSpec.js @@ -1,7 +1,9 @@ /*global defineSuite*/ defineSuite([ 'Scene/Globe', + 'Core/CesiumTerrainProvider', 'Core/defined', + 'Core/loadWithXhr', 'Core/Ellipsoid', 'Core/Rectangle', 'Renderer/ClearCommand', @@ -12,7 +14,9 @@ defineSuite([ 'Specs/render' ], function( Globe, + CesiumTerrainProvider, defined, + loadWithXhr, Ellipsoid, Rectangle, ClearCommand, @@ -43,8 +47,25 @@ defineSuite([ afterEach(function() { globe.destroy(); + loadWithXhr.load = loadWithXhr.defaultLoad; }); + function returnTileJson(path) { + var oldLoad = loadWithXhr.load; + loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + if (url.indexOf('layer.json') >= 0) { + return loadWithXhr.defaultLoad(path, responseType, method, data, headers, deferred); + } else { + return oldLoad(url, responseType, method, data, headers, deferred, overrideMimeType); + } + }; + } + + function returnVertexNormalTileJson() { + return returnTileJson('Data/CesiumTerrainTileJson/VertexNormals.tile.json'); + } + + /** * Repeatedly calls update until the load queue is empty. You must wrap any code to follow * this in a "runs" function. @@ -78,4 +99,41 @@ defineSuite([ expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); }); }); + + it('renders terrain with enableLighting', function() { + globe.enableLighting = true; + + var layerCollection = globe.imageryLayers; + layerCollection.removeAll(); + layerCollection.addImageryProvider(new SingleTileImageryProvider({url : 'Data/Images/Red16x16.png'})); + + loadWithXhr.load = function(url, responseType, method, data, headers, deferred, overrideMimeType) { + return loadWithXhr.defaultLoad('Data/CesiumTerrainTileJson/tile.vertexnormals.terrain', responseType, method, data, headers, deferred); + }; + + returnVertexNormalTileJson(); + + var terrainProvider = new CesiumTerrainProvider({ + url : 'made/up/url', + requestVertexNormals : true + }); + + globe.terrainProvider = terrainProvider; + + waitsFor(function() { + return terrainProvider.ready; + }); + + frameState.camera.viewRectangle(new Rectangle(0.0001, 0.0001, 0.0025, 0.0025), Ellipsoid.WGS84); + + updateUntilDone(globe); + + runs(function() { + ClearCommand.ALL.execute(context); + expect(context.readPixels()).toEqual([0, 0, 0, 0]); + + render(context, frameState, globe); + expect(context.readPixels()).toNotEqual([0, 0, 0, 0]); + }); + }); }, 'WebGL'); \ No newline at end of file From 9f95331b365b3e3d128fbfb8dfae360f613a9e3b Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 09:16:45 -0400 Subject: [PATCH 08/22] Moved calculation of normal eye coordinates over to the vertex shader (in the case of pervertex lighting). --- Source/Shaders/GlobeFS.glsl | 7 ++++--- Source/Shaders/GlobeVS.glsl | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Source/Shaders/GlobeFS.glsl b/Source/Shaders/GlobeFS.glsl index 388e8c81b0e8..77512bbd7005 100644 --- a/Source/Shaders/GlobeFS.glsl +++ b/Source/Shaders/GlobeFS.glsl @@ -48,7 +48,8 @@ uniform vec2 u_lightingFadeDistance; varying vec3 v_positionMC; varying vec3 v_positionEC; varying vec2 v_textureCoordinates; -varying vec3 v_normal; +varying vec3 v_normalMC; +varying vec3 v_normalEC; vec3 sampleAndBlend( vec3 previousColor, @@ -132,8 +133,8 @@ void main() vec3 normalMC = normalize(czm_geodeticSurfaceNormal(v_positionMC, vec3(0.0), vec3(1.0))); // normalized surface normal in model coordinates vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes #elif defined(ENABLE_VERTEX_LIGHTING) - vec3 normalMC = normalize(v_normal); // normalized surface normal in model coordinates - vec3 normalEC = normalize(czm_normal3D * normalMC); // normalized surface normal in eye coordiantes + vec3 normalMC = normalize(v_normalMC); // normalized surface normal in model coordinates + vec3 normalEC = normalize(v_normalEC); // normalized surface normal in eye coordiantes #endif #ifdef SHOW_REFLECTIVE_OCEAN diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl index fdb57eec7932..f2416fc4ba6e 100644 --- a/Source/Shaders/GlobeVS.glsl +++ b/Source/Shaders/GlobeVS.glsl @@ -13,7 +13,8 @@ varying vec3 v_positionMC; varying vec3 v_positionEC; varying vec2 v_textureCoordinates; -varying vec3 v_normal; +varying vec3 v_normalMC; +varying vec3 v_normalEC; // These functions are generated at runtime. vec4 getPosition(vec3 position3DWC); @@ -94,7 +95,8 @@ void main() v_positionMC = position3DWC; // position in model coordinates vec2 encodedNormal = textureCoordAndEncodedNormals.zw; encodedNormal = encodedNormal / 255.0 * 2.0 - 1.0; - v_normal = czm_octDecode(encodedNormal); + v_normalMC = czm_octDecode(encodedNormal); + v_normalEC = czm_normal3D * normalMC; #endif v_textureCoordinates = textureCoordAndEncodedNormals.xy; From 49215229905a36dbdbdd4bc8ca0f900f823e8b45 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 10:40:45 -0400 Subject: [PATCH 09/22] Added unit tests for new builtin functions. --- Specs/Renderer/BuiltinFunctionsSpec.js | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Specs/Renderer/BuiltinFunctionsSpec.js b/Specs/Renderer/BuiltinFunctionsSpec.js index 771d18505e5e..ca25cd882ec0 100644 --- a/Specs/Renderer/BuiltinFunctionsSpec.js +++ b/Specs/Renderer/BuiltinFunctionsSpec.js @@ -223,4 +223,55 @@ defineSuite([ '}'; verifyDraw(fs); }); + + it('has czm_octDecode', function() { + var fs = + 'void main() { ' + + ' gl_FragColor = vec4(czm_octDecode(vec2(0.0, 0.0)) == vec3(0.0, 0.0, 1.0)); ' + + '}'; + verifyDraw(fs); + }); + + it('has signNotZero : float', function() { + var fs = + 'void main() { ' + + ' gl_FragColor = vec4(czm_signNotZero(0.0) == 1.0, ' + + ' czm_signNotZero(5.0) == 1.0, ' + + ' czm_signNotZero(-5.0) == -1.0, 1.0); ' + + '}'; + verifyDraw(fs); + }); + + it('has signNotZero : vec2', function() { + var fs = + 'void main() { ' + + ' gl_FragColor = vec4(czm_signNotZero(vec2(0.0, 0.0)) == vec2(1.0, 1.0), ' + + ' czm_signNotZero(vec2(1.0, 1.0)) == vec2(1.0, 1.0), ' + + ' czm_signNotZero(vec2(-1.0, -1.0)) == vec2(-1.0, -1.0), ' + + ' czm_signNotZero(vec2(-1.0, 0.0)) == vec2(-1.0, 1.0)); ' + + '}'; + verifyDraw(fs); + }); + + it('has signNotZero : vec3', function() { + var fs = + 'void main() { ' + + ' gl_FragColor = vec4(czm_signNotZero(vec3(0.0, 0.0, 0.0)) == vec3(1.0, 1.0, 1.0), ' + + ' czm_signNotZero(vec3(1.0, 1.0, 1.0)) == vec3(1.0, 1.0, 1.0), ' + + ' czm_signNotZero(vec3(-1.0, -1.0, -1.0)) == vec3(-1.0, -1.0, -1.0), ' + + ' czm_signNotZero(vec3(-1.0, 0.0, 1.0)) == vec3(-1.0, 1.0, 1.0)); ' + + '}'; + verifyDraw(fs); + }); + + it('has signNotZero : vec4', function() { + var fs = + 'void main() { ' + + ' gl_FragColor = vec4(czm_signNotZero(vec4(0.0, 0.0, 0.0, 0.0)) == vec4(1.0), ' + + ' czm_signNotZero(vec4(1.0, 1.0, 1.0, 1.0)) == vec4(1.0), ' + + ' czm_signNotZero(vec4(-1.0, -1.0, -1.0, -1.0)) == vec4(-1.0), ' + + ' czm_signNotZero(vec4(-1.0, 0.0, 1.0, -10.0)) == vec4(-1.0, 1.0, 1.0, -1.0)); ' + + '}'; + verifyDraw(fs); + }); }, 'WebGL'); \ No newline at end of file From 2ca1050792f418ba1afa724e81e3a3e1df99c713 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 10:56:10 -0400 Subject: [PATCH 10/22] Updated CesiumTerrainProvider.requestVertexNormals documentation, fixed copy/paste bug in GlobeVS.glsl --- Source/Core/CesiumTerrainProvider.js | 1 + Source/Shaders/GlobeVS.glsl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index c679fdadd60f..d9e1036a5ac6 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -52,6 +52,7 @@ define([ * @param {Object} options Object with the following properties: * @param {String} options.url The URL of the Cesium terrain server. * @param {Proxy} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL, if needed. + * @param {Boolean} [options.requestVertexNormals] If true, the client will request that vertex normals be included in terrain tile response from the server. * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * * @see TerrainProvider diff --git a/Source/Shaders/GlobeVS.glsl b/Source/Shaders/GlobeVS.glsl index f2416fc4ba6e..28caba1c7ee3 100644 --- a/Source/Shaders/GlobeVS.glsl +++ b/Source/Shaders/GlobeVS.glsl @@ -96,7 +96,7 @@ void main() vec2 encodedNormal = textureCoordAndEncodedNormals.zw; encodedNormal = encodedNormal / 255.0 * 2.0 - 1.0; v_normalMC = czm_octDecode(encodedNormal); - v_normalEC = czm_normal3D * normalMC; + v_normalEC = czm_normal3D * v_normalMC; #endif v_textureCoordinates = textureCoordAndEncodedNormals.xy; From 768defc49cb4f291038d83e90ac4c981fe8b4ff4 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 11:04:34 -0400 Subject: [PATCH 11/22] Removed local data type byte length in favor of using TypedArrays.BYTES_PER_ELEMENT --- Source/Core/CesiumTerrainProvider.js | 43 ++++++++++++---------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index d9e1036a5ac6..7c49eef4de2e 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -52,7 +52,7 @@ define([ * @param {Object} options Object with the following properties: * @param {String} options.url The URL of the Cesium terrain server. * @param {Proxy} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL, if needed. - * @param {Boolean} [options.requestVertexNormals] If true, the client will request that vertex normals be included in terrain tile response from the server. + * @param {Boolean} [options.requestVertexNormals=false] If true, the client will request that vertex normals be included in terrain tile response from the server. * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * * @see TerrainProvider @@ -225,29 +225,24 @@ define([ function createQuantizedMeshTerrainData(provider, buffer, level, x, y, tmsY) { var pos = 0; - var uint8Length = 1; - var uint16Length = 2; - var uint32Length = 4; - var float32Length = 4; - var float64Length = 8; var cartesian3Elements = 3; var boundingSphereElements = cartesian3Elements + 1; - var cartesian3Length = float64Length * cartesian3Elements; - var boundingSphereLength = float64Length * boundingSphereElements; + var cartesian3Length = Float64Array.BYTES_PER_ELEMENT * cartesian3Elements; + var boundingSphereLength = Float64Array.BYTES_PER_ELEMENT * boundingSphereElements; var vertexElements = 6; var encodedVertexElements = 3; - var encodedVertexLength = uint16Length * encodedVertexElements; + var encodedVertexLength = Uint16Array.BYTES_PER_ELEMENT * encodedVertexElements; var triangleElements = 3; - var triangleLength = uint16Length * triangleElements; + var triangleLength = Uint16Array.BYTES_PER_ELEMENT * triangleElements; var view = new DataView(buffer); var center = new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)); pos += cartesian3Length; var minimumHeight = view.getFloat32(pos, true); - pos += float32Length; + pos += Float32Array.BYTES_PER_ELEMENT; var maximumHeight = view.getFloat32(pos, true); - pos += float32Length; + pos += Float32Array.BYTES_PER_ELEMENT; var boundingSphere = new BoundingSphere( new Cartesian3(view.getFloat64(pos, true), view.getFloat64(pos + 8, true), view.getFloat64(pos + 16, true)), @@ -258,7 +253,7 @@ define([ pos += cartesian3Length; var vertexCount = view.getUint32(pos, true); - pos += uint32Length; + pos += Uint32Array.BYTES_PER_ELEMENT; var encodedVertexBuffer = new Uint16Array(buffer, pos, vertexCount * 3); pos += vertexCount * encodedVertexLength; @@ -292,7 +287,7 @@ define([ } var triangleCount = view.getUint32(pos, true); - pos += uint32Length; + pos += Uint32Array.BYTES_PER_ELEMENT; var indices = new Uint16Array(buffer, pos, triangleCount * triangleElements); pos += triangleCount * triangleLength; @@ -309,33 +304,33 @@ define([ } var westVertexCount = view.getUint32(pos, true); - pos += uint32Length; + pos += Uint32Array.BYTES_PER_ELEMENT; var westIndices = new Uint16Array(buffer, pos, westVertexCount); - pos += westVertexCount * uint16Length; + pos += westVertexCount * Uint16Array.BYTES_PER_ELEMENT; var southVertexCount = view.getUint32(pos, true); - pos += uint32Length; + pos += Uint32Array.BYTES_PER_ELEMENT; var southIndices = new Uint16Array(buffer, pos, southVertexCount); - pos += southVertexCount * uint16Length; + pos += southVertexCount * Uint16Array.BYTES_PER_ELEMENT; var eastVertexCount = view.getUint32(pos, true); - pos += uint32Length; + pos += Uint32Array.BYTES_PER_ELEMENT; var eastIndices = new Uint16Array(buffer, pos, eastVertexCount); - pos += eastVertexCount * uint16Length; + pos += eastVertexCount * Uint16Array.BYTES_PER_ELEMENT; var northVertexCount = view.getUint32(pos, true); - pos += uint32Length; + pos += Uint32Array.BYTES_PER_ELEMENT; var northIndices = new Uint16Array(buffer, pos, northVertexCount); - pos += northVertexCount * uint16Length; + pos += northVertexCount * Uint16Array.BYTES_PER_ELEMENT; var encodedNormalBuffer; if (pos < view.byteLength) { var extensionsflag = view.getUint8(pos); - pos += uint8Length; + pos += Uint8Array.BYTES_PER_ELEMENT; if (extensionsflag & 0x1) { encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); - pos += vertexCount * 2 * uint8Length; + pos += vertexCount * 2 * Uint8Array.BYTES_PER_ELEMENT; } } From ff0300479ed9cd95215a3c454820429058f8d706 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 11:59:32 -0400 Subject: [PATCH 12/22] Added private QuantizedMeshExtensionFlags enum and cleaned up test for the octencoded vertex normals extension. --- Source/Core/CesiumTerrainProvider.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index 7c49eef4de2e..8a6765e88db3 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -192,6 +192,26 @@ define([ requestMetadata(); }; + /** + * When using the Quantized-Mesh format, a tile may be returned that includes additional extensions, such as PerVertexNormals, watermask, etc. + * This enumeration defines the bitwise flags that define the type of extension data that has been appended to the standard mesh data. + * + * @namespace + * @alias QuantizedMeshExtensionFlags + * @see CesiumTerrainProvider + * @private + */ + var QuantizedMeshExtensionFlags = { + /** + * Oct-Encoded Per-Vertex Normals are included as an extension to the tile mesh + * + * @type {Number} + * @constant + * @default 0x1 + */ + OCT_VERTEX_NORMALS: 0x1 + }; + var requestHeadersVertexNormals = { // prefer quantized-mesh media-type // only request vertex normals if Lighting is enabled on the CesiumTerrainProvider @@ -328,7 +348,7 @@ define([ var extensionsflag = view.getUint8(pos); pos += Uint8Array.BYTES_PER_ELEMENT; - if (extensionsflag & 0x1) { + if (extensionsflag & QuantizedMeshExtensionFlags.OCT_VERTEX_NORMALS !== 0) { encodedNormalBuffer = new Uint8Array(buffer, pos, vertexCount * 2); pos += vertexCount * 2 * Uint8Array.BYTES_PER_ELEMENT; } From 2dd1becd449b0b9d00fe31e0743ba753ba9258b2 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 14:13:00 -0400 Subject: [PATCH 13/22] Updated Changes.MD. Globe.js change was supposed to be in the last commit. This was a change that resulted from the last merge from master. --- CHANGES.md | 10 ++++++++++ Source/Scene/Globe.js | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 51156e27a8c6..204e20b2ac85 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,13 @@ Change Log * All `Matrix2`, `Matrix3`, `Matrix4` and `Quaternion` functions that take a `result` parameter now require the parameter (except for functions starting with `from`). * Removed the following from the Cesium API: `Transforms.earthOrientationParameters`, `EarthOrientationParameters`, `EarthOrientationParametersSample`, `Transforms.iau2006XysData`, `Iau2006XysData`, `Iau2006XysSample`, `IauOrientationAxes`, `TimeConstants`, `Scene.frameState`, `FrameState`, `EncodedCartesian3`, `EllipsoidalOccluder`, and `FAR`. These are still available but are not part of the official API and may change in future versions. * Removed `DynamicObject.vertexPositions`. Use `DynamicWall.positions`, `DynamicPolygon.positions`, and `DynamicPolyline.positions` instead. + * Transformed the following class the methods to a property: + * `TerrainProvider.hasWaterMask` + * `CesiumTerrainProvider.hasWaterMask` + * `ArcGisImageServerTerrainProvider.hasWaterMask` + * `EllipsoidTerrainProvider.hasWaterMask` + * `VRTheWorldTerrainProvider.hasWaterMask` + * Renamed preprocessor define, `ENABLE_LIGHTING` used by `Globe` shaders to `ENABLE_DAYNIGHT_SHADING` * The `DynamicScene` layer has been renamed to `DataSources` additionally, the following objects have all been renamed. * `DynamicBillboard` -> `BillboardGraphics` * `DynamicBillboardVisualizer` -> `BillboardVisualizer` @@ -40,6 +47,9 @@ Change Log * `Viewer.trackedObject` and `Viewer.selectedObject` have been renamed to `Viewer.trackedEntity` and `Viewer.selectedEntity` when using the `viewerEntityMixin`. * Added northUpEast transform to help support display of glTF models because Y is their up axis. * Cesium can now render an unlimited number of imagery layers, no matter how few texture units are supported by the hardware. +* Added `czm_octDecode` and `czm_signNotZero` builtin functions. +* Added `CesiumTerrainProvider.requestVertexNormals` to request per vertex normals from the provider, if they are available. +* Added support for rendering the globe with oct-encoded per vertex normals . * Added `Primitive.ready`. Beta Releases diff --git a/Source/Scene/Globe.js b/Source/Scene/Globe.js index 9ec91fe47fbf..a8174c33cfa9 100644 --- a/Source/Scene/Globe.js +++ b/Source/Scene/Globe.js @@ -673,7 +673,7 @@ define([ // Initial compile or re-compile if uber-shader parameters changed var hasWaterMask = this._surface.tileProvider.ready && this._surface.tileProvider.terrainProvider.hasWaterMask; - var hasVertexNormals = this._surface._terrainProvider.ready && this._surface._terrainProvider.hasVertexNormals; + var hasVertexNormals = this._surface.tileProvider.ready && this._surface.tileProvider.terrainProvider.hasVertexNormals; var hasWaterMaskChanged = this._hasWaterMask !== hasWaterMask; var hasVertexNormalsChanged = this._hasVertexNormals !== hasVertexNormalsChanged; var hasEnableLightingChanged = this._enableLighting !== this.enableLighting; From f328757e417deb4cb9ca609caecd0735b44667ea Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 14:24:20 -0400 Subject: [PATCH 14/22] Updated CHANGES.md. Minor cleanup. --- CHANGES.md | 1 + Source/Workers/createVerticesFromQuantizedTerrainMesh.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 204e20b2ac85..5efcb7045c88 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -49,6 +49,7 @@ Change Log * Cesium can now render an unlimited number of imagery layers, no matter how few texture units are supported by the hardware. * Added `czm_octDecode` and `czm_signNotZero` builtin functions. * Added `CesiumTerrainProvider.requestVertexNormals` to request per vertex normals from the provider, if they are available. +* Added new property to all terrain providers: `TerrainProvider.hasVertexNormals`, `CesiumTerrainProvider.hasVertexNormals`, `ArcGisImageServerTerrainProvider.hasVertexNormals`, `EllipsoidTerrainProvider.hasVertexNormals`, `VRTheWorldTerrainProvider.hasVertexNormals`. This property indicates whether or not vertex normals will be included in the terrain tile responses. * Added support for rendering the globe with oct-encoded per vertex normals . * Added `Primitive.ready`. diff --git a/Source/Workers/createVerticesFromQuantizedTerrainMesh.js b/Source/Workers/createVerticesFromQuantizedTerrainMesh.js index 518560817d96..e5fc806cd329 100644 --- a/Source/Workers/createVerticesFromQuantizedTerrainMesh.js +++ b/Source/Workers/createVerticesFromQuantizedTerrainMesh.js @@ -128,7 +128,6 @@ define([ var vertexIndex = vertexBufferIndex / vertexStride; - for (var i = start; i !== end; i += increment) { var index = edgeVertices[i]; var offset = index * vertexStride; From d8d6691152d1e5b3a233eb3ba59646ce12c5c463 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 15:34:08 -0400 Subject: [PATCH 15/22] CesiumTerrainProvider.requestVertexNormals is now readonly. --- Source/Core/CesiumTerrainProvider.js | 23 ++++++++++++++++++++--- Specs/Core/CesiumTerrainProviderSpec.js | 2 ++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index 8a6765e88db3..a7600f098008 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -92,8 +92,9 @@ define([ * Boolean flag that indicates if the client should request vertex normals from the server. * @type {Boolean} * @default false + * @private */ - this.requestVertexNormals = defaultValue(options.requestVertexNormals, false); + this._requestVertexNormals = defaultValue(options.requestVertexNormals, false); this._errorEvent = new Event(); @@ -422,7 +423,7 @@ define([ var promise; var tileLoader = loadTile; - if (this.requestVertexNormals && this._hasVertexNormals) { + if (this._requestVertexNormals && this._hasVertexNormals) { tileLoader = loadTileVertexNormals; } @@ -544,7 +545,23 @@ define([ //>>includeEnd('debug'); // returns true if we can request vertex normals from the server - return this._hasVertexNormals && this.requestVertexNormals; + return this._hasVertexNormals && this._requestVertexNormals; + } + }, + + /** + * Boolean flag that indicates if the client should request vertex normals from the server. + * Vertex normals data is appended to the standard tile mesh data only if the client requests the vertex normals and + * if the server provides vertex normals. + * + * This property is read only. To change this value, a new CesiumTerrainProvider must be constructed that requests + * vertex normals to ensure that all existing tiles are requested that includes/excludes vertex normal extension data. + * @memberof CesiumTerrainProvider.prototype + * @type {Boolean} + */ + requestVertexNormals : { + get : function() { + return this._requestVertexNormals; } } }); diff --git a/Specs/Core/CesiumTerrainProviderSpec.js b/Specs/Core/CesiumTerrainProviderSpec.js index 7eea6712070b..e580ae08f47b 100644 --- a/Specs/Core/CesiumTerrainProviderSpec.js +++ b/Specs/Core/CesiumTerrainProviderSpec.js @@ -171,6 +171,7 @@ defineSuite([ }); runs(function() { + expect(provider.requestVertexNormals).toBe(true); expect(provider.hasVertexNormals).toBe(true); }); }); @@ -188,6 +189,7 @@ defineSuite([ }); runs(function() { + expect(provider.requestVertexNormals).toBe(false); expect(provider.hasVertexNormals).toBe(false); }); }); From 774588319692aaa175f08b0d257a68c234401b72 Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 15:52:09 -0400 Subject: [PATCH 16/22] Minor doc updates. --- CHANGES.md | 2 +- Source/Core/CesiumTerrainProvider.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5efcb7045c88..91c2842eaf23 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,7 +7,7 @@ Change Log * All `Matrix2`, `Matrix3`, `Matrix4` and `Quaternion` functions that take a `result` parameter now require the parameter (except for functions starting with `from`). * Removed the following from the Cesium API: `Transforms.earthOrientationParameters`, `EarthOrientationParameters`, `EarthOrientationParametersSample`, `Transforms.iau2006XysData`, `Iau2006XysData`, `Iau2006XysSample`, `IauOrientationAxes`, `TimeConstants`, `Scene.frameState`, `FrameState`, `EncodedCartesian3`, `EllipsoidalOccluder`, and `FAR`. These are still available but are not part of the official API and may change in future versions. * Removed `DynamicObject.vertexPositions`. Use `DynamicWall.positions`, `DynamicPolygon.positions`, and `DynamicPolyline.positions` instead. - * Transformed the following class the methods to a property: + * Refactored the following methods into a properties: * `TerrainProvider.hasWaterMask` * `CesiumTerrainProvider.hasWaterMask` * `ArcGisImageServerTerrainProvider.hasWaterMask` diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index a7600f098008..c845e6234330 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -52,7 +52,7 @@ define([ * @param {Object} options Object with the following properties: * @param {String} options.url The URL of the Cesium terrain server. * @param {Proxy} [options.proxy] A proxy to use for requests. This object is expected to have a getURL function which returns the proxied URL, if needed. - * @param {Boolean} [options.requestVertexNormals=false] If true, the client will request that vertex normals be included in terrain tile response from the server. + * @param {Boolean} [options.requestVertexNormals=false] Flag that indicates if the client should request additional lighting information from the server, in the form of per vertex normals if available. * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * * @see TerrainProvider From a0dbffd4c0f9713ff2d9aeb2a9c4636371faf88c Mon Sep 17 00:00:00 2001 From: Alex Wood Date: Wed, 9 Jul 2014 16:08:33 -0400 Subject: [PATCH 17/22] Added an example that demonstrates the use of the per-vertex normals for the CesiumTerrainProvider. --- Source/Core/CesiumTerrainProvider.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index c845e6234330..48cd4e5aa688 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -56,6 +56,30 @@ define([ * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas. * * @see TerrainProvider + * + * @example + * // Construct a terrain provider that uses per vertex normals for lighting + * // to add shading detail to an imagery provider. + * var terrainProvider = new Cesium.CesiumTerrainProvider({ + * url : '//cesiumjs.org/stk-terrain/tilesets/world/tiles', + * requestVertexNormals : true + * }); + * + * // Terrain geometry near the surface of the globe is difficult to view when using NaturalEarthII imagery, + * // unless the TerrainProvider provides additional lighting information to shade the terrain (as shown above). + * var imageryProvider = new Cesium.TileMapServiceImageryProvider({ + * url : 'http://localhost:8080/Source/Assets/Textures/NaturalEarthII', + * fileExtension : 'jpg' + * }); + * + * var viewer = new Cesium.Viewer('cesiumContainer', { + * imageryProvider : imageryProvider, + * baseLayerPicker : false, + * terrainProvider : terrainProvider + * }); + * + * // The globe must enable lighting to make use of the terrain's vertex normals + * viewer.scene.globe.enableLighting = true; */ var CesiumTerrainProvider = function CesiumTerrainProvider(options) { //>>includeStart('debug', pragmas.debug) From c1e90905e04da5d504c03b77ca93f489733928c9 Mon Sep 17 00:00:00 2001 From: hpinkos Date: Wed, 16 Jul 2014 13:53:04 -0400 Subject: [PATCH 18/22] fix spec --- Specs/Core/SimplePolylineGeometrySpec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Specs/Core/SimplePolylineGeometrySpec.js b/Specs/Core/SimplePolylineGeometrySpec.js index d441bb3dd031..248cc3e19535 100644 --- a/Specs/Core/SimplePolylineGeometrySpec.js +++ b/Specs/Core/SimplePolylineGeometrySpec.js @@ -5,6 +5,7 @@ defineSuite([ 'Core/Cartesian3', 'Core/Color', 'Core/Ellipsoid', + 'Core/Math', 'Core/PrimitiveType' ], function( SimplePolylineGeometry, @@ -12,6 +13,7 @@ defineSuite([ Cartesian3, Color, Ellipsoid, + CesiumMath, PrimitiveType) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/ @@ -47,7 +49,7 @@ defineSuite([ ellipsoid: Ellipsoid.UNIT_SPHERE })); - expect(line.attributes.position.values).toEqual([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]); + expect(line.attributes.position.values).toEqualEpsilon([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0], CesiumMath.EPSILON10); expect(line.indices).toEqual([0, 1, 1, 2]); expect(line.primitiveType).toEqual(PrimitiveType.LINES); expect(line.boundingSphere).toEqual(BoundingSphere.fromPoints(positions)); From 0fdb2570d5a0588944553149d4230edd99dba6d7 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 17 Jul 2014 13:14:17 -0400 Subject: [PATCH 19/22] Clean up sensor API This are changes needed ahead of #1887 to ensure API/CZML compatibility with 1.0 --- Apps/SampleData/LotsOfSensors.czml | 62 +++---- Apps/SampleData/simple.czml | 2 +- Apps/Sandcastle/gallery/Sensors.html | 32 ++-- Source/DataSources/ConeGraphics.js | 47 +---- Source/DataSources/ConeVisualizer.js | 116 +++++-------- Source/DataSources/CzmlDataSource.js | 30 ++-- Source/DataSources/PyramidGraphics.js | 60 ++++--- Source/DataSources/PyramidVisualizer.js | 115 +++++-------- Source/Scene/CustomSensorVolume.js | 63 +++---- .../Scene/RectangularPyramidSensorVolume.js | 14 +- Source/Scene/SensorVolumeCollection.js | 161 ------------------ Specs/DataSources/ConeGraphicsSpec.js | 58 ++----- Specs/DataSources/ConeVisualizerSpec.js | 13 +- Specs/DataSources/CzmlDataSourceSpec.js | 99 +++-------- Specs/DataSources/PyramidGraphicsSpec.js | 16 +- Specs/DataSources/PyramidVisualizerSpec.js | 11 +- 16 files changed, 274 insertions(+), 625 deletions(-) delete mode 100644 Source/Scene/SensorVolumeCollection.js diff --git a/Apps/SampleData/LotsOfSensors.czml b/Apps/SampleData/LotsOfSensors.czml index 967525b00ea1..837aa5a53d6f 100644 --- a/Apps/SampleData/LotsOfSensors.czml +++ b/Apps/SampleData/LotsOfSensors.czml @@ -9418,7 +9418,7 @@ 0,255,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -11055,7 +11055,7 @@ 0,255,255,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -12692,7 +12692,7 @@ 255,0,255,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -14329,7 +14329,7 @@ 255,255,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -15966,7 +15966,7 @@ 0,0,255,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -17603,7 +17603,7 @@ 255,0,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -19240,7 +19240,7 @@ 65,105,225,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -20877,7 +20877,7 @@ 135,206,250,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -22514,7 +22514,7 @@ 107,142,35,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -24151,7 +24151,7 @@ 143,188,143,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -25788,7 +25788,7 @@ 255,215,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -27425,7 +27425,7 @@ 186,85,211,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -29062,7 +29062,7 @@ 255,105,180,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -30699,7 +30699,7 @@ 210,105,30,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -32336,7 +32336,7 @@ 255,240,245,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -33973,7 +33973,7 @@ 127,255,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -35610,7 +35610,7 @@ 255,106,106,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -37247,7 +37247,7 @@ 155,48,255,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -38884,7 +38884,7 @@ 255,165,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -40521,7 +40521,7 @@ 240,128,128,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -42158,7 +42158,7 @@ 240,230,140,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -43795,7 +43795,7 @@ 153,153,153,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -45432,7 +45432,7 @@ 64,128,128,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -47068,7 +47068,7 @@ 255,0,128,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -47102,7 +47102,7 @@ 255,128,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -48739,7 +48739,7 @@ 203,132,52,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -50376,7 +50376,7 @@ 127,255,0,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -52013,7 +52013,7 @@ 163,143,239,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -53650,7 +53650,7 @@ 201,193,54,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -55287,7 +55287,7 @@ 210,105,30,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ @@ -56924,7 +56924,7 @@ 155,48,255,255 ] }, - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ diff --git a/Apps/SampleData/simple.czml b/Apps/SampleData/simple.czml index 685149f8f8de..8c487a8527c9 100644 --- a/Apps/SampleData/simple.czml +++ b/Apps/SampleData/simple.czml @@ -846,7 +846,7 @@ } }, "portionToDisplay":"COMPLETE", - "material":{ + "lateralSurfaceMaterial":{ "solidColor":{ "color":{ "rgba":[ diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 3518202fec13..ac61afc909d9 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -87,8 +87,8 @@ return Cesium.Matrix4.multiply(modelMatrix, Cesium.Matrix4.fromRotationTranslation(orientation, Cesium.Cartesian3.ZERO), new Cesium.Matrix4()); } - function addRectangularSensor(sensors, ellipsoid, scene) { - var rectangularPyramidSensor = sensors.addRectangularPyramid(); + function addRectangularSensor(primitives, ellipsoid, scene) { + var rectangularPyramidSensor = new Cesium.RectangularPyramidSensorVolume(); Sandcastle.declare(rectangularPyramidSensor); // For highlighting in Sandcastle. rectangularPyramidSensor.modelMatrix = getModelMatrix(ellipsoid); @@ -96,17 +96,18 @@ rectangularPyramidSensor.xHalfAngle = Cesium.Math.toRadians(40.0); rectangularPyramidSensor.yHalfAngle = Cesium.Math.toRadians(20.0); - rectangularPyramidSensor.material = Cesium.Material.fromType('Color'); - rectangularPyramidSensor.material.uniforms.color = { + rectangularPyramidSensor.lateralSurfaceMaterial = Cesium.Material.fromType('Color'); + rectangularPyramidSensor.lateralSurfaceMaterial.uniforms.color = { red : 0.0, green : 1.0, blue : 1.0, alpha : 0.5 }; + primitives.add(rectangularPyramidSensor); } - function addCustomSensor(sensors, ellipsoid, scene) { - var customSensor = sensors.addCustom(); + function addCustomSensor(primitives, ellipsoid, scene) { + var customSensor = new Cesium.CustomSensorVolume(); Sandcastle.declare(customSensor); // For highlighting in Sandcastle. var directions = []; @@ -119,10 +120,11 @@ customSensor.modelMatrix = getModelMatrix(ellipsoid); customSensor.radius = 20000000.0; - customSensor.setDirections(directions); + customSensor.directions = directions; + primitives.add(customSensor); } - function createUserInterface(viewer, sensors) { + function createUserInterface(viewer) { var tp = new TitlePane({ title: 'Manipulate Sensor', id:'title-pane', @@ -135,23 +137,22 @@ var scene = viewer.scene; var ellipsoid = scene.globe.ellipsoid; var primitives = scene.primitives; - primitives.add(sensors); var sensorMenu = new DropDownMenu({ style: 'display: none;'}); function updateSensor() { - sensors.removeAll(); + primitives.removeAll(); switch (selection) { case 'Rectangular': - addRectangularSensor(sensors, ellipsoid, scene); + addRectangularSensor(primitives, ellipsoid, scene); break; case 'Custom': - addCustomSensor(sensors, ellipsoid, scene); + addCustomSensor(primitives, ellipsoid, scene); break; case 'Rectangular': - addRectangularSensor(sensors, ellipsoid, scene); + addRectangularSensor(primitives, ellipsoid, scene); } } @@ -258,7 +259,7 @@ } var viewer = new Cesium.Viewer('cesiumContainer', { - sceneModePicker : false //sensors currently only work in 3D + sceneModePicker : false }); viewer.screenSpaceEventHandler.setInputAction(function(movement) { @@ -266,8 +267,7 @@ Sandcastle.highlight(pickedPrimitive); }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); - var sensors = new Cesium.SensorVolumeCollection(); - createUserInterface(viewer, sensors); + createUserInterface(viewer); }); //Sandcastle_End Sandcastle.finishedLoading(); diff --git a/Source/DataSources/ConeGraphics.js b/Source/DataSources/ConeGraphics.js index 84c176a3f702..29a1854b8925 100644 --- a/Source/DataSources/ConeGraphics.js +++ b/Source/DataSources/ConeGraphics.js @@ -30,14 +30,8 @@ define([ this._innerHalfAngleSubscription = undefined; this._outerHalfAngle = undefined; this._outerHalfAngleSubscription = undefined; - this._capMaterial = undefined; - this._capMaterialSubscription = undefined; - this._innerMaterial = undefined; - this._innerMaterialSubscription = undefined; - this._outerMaterial = undefined; - this._outerMaterialSubscription = undefined; - this._silhouetteMaterial = undefined; - this._silhouetteMaterialSubscription = undefined; + this._lateralSurfaceMaterial = undefined; + this._lateralSurfaceMaterialSubscription = undefined; this._intersectionColor = undefined; this._intersectionColorSubscription = undefined; this._intersectionWidth = undefined; @@ -94,32 +88,11 @@ define([ outerHalfAngle : createPropertyDescriptor('outerHalfAngle'), /** - * Gets or sets the {@link MaterialProperty} specifying the the cone's cap material. + * Gets or sets the {@link MaterialProperty} specifying the the cone's appearance. * @memberof ConeGraphics.prototype * @type {MaterialProperty} */ - capMaterial : createPropertyDescriptor('capMaterial'), - - /** - * Gets or sets the {@link MaterialProperty} specifying the the cone's inner material. - * @memberof ConeGraphics.prototype - * @type {MaterialProperty} - */ - innerMaterial : createPropertyDescriptor('innerMaterial'), - - /** - * Gets or sets the {@link MaterialProperty} specifying the the cone's outer material. - * @memberof ConeGraphics.prototype - * @type {MaterialProperty} - */ - outerMaterial : createPropertyDescriptor('outerMaterial'), - - /** - * Gets or sets the {@link MaterialProperty} specifying the the cone's silhouette material. - * @memberof ConeGraphics.prototype - * @type {MaterialProperty} - */ - silhouetteMaterial : createPropertyDescriptor('silhouetteMaterial'), + lateralSurfaceMaterial : createPropertyDescriptor('lateralSurfaceMaterial'), /** * Gets or sets the {@link Color} {@link Property} specifying the color of the line formed by the intersection of the cone and other central bodies. @@ -176,10 +149,7 @@ define([ result.showIntersection = this.showIntersection; result.intersectionColor = this.intersectionColor; result.intersectionWidth = this.intersectionWidth; - result.capMaterial = this.capMaterial; - result.innerMaterial = this.innerMaterial; - result.outerMaterial = this.outerMaterial; - result.silhouetteMaterial = this.silhouetteMaterial; + result.lateralSurfaceMaterial = this.lateralSurfaceMaterial; return result; }; @@ -205,11 +175,8 @@ define([ this.showIntersection = defaultValue(this.showIntersection, source.showIntersection); this.intersectionColor = defaultValue(this.intersectionColor, source.intersectionColor); this.intersectionWidth = defaultValue(this.intersectionWidth, source.intersectionWidth); - this.capMaterial = defaultValue(this.capMaterial, source.capMaterial); - this.innerMaterial = defaultValue(this.innerMaterial, source.innerMaterial); - this.outerMaterial = defaultValue(this.outerMaterial, source.outerMaterial); - this.silhouetteMaterial = defaultValue(this.silhouetteMaterial, source.silhouetteMaterial); + this.lateralSurfaceMaterial = defaultValue(this.lateralSurfaceMaterial, source.lateralSurfaceMaterial); }; return ConeGraphics; -}); +}); \ No newline at end of file diff --git a/Source/DataSources/ConeVisualizer.js b/Source/DataSources/ConeVisualizer.js index 43ef7b7793dc..ab74a8ea541a 100644 --- a/Source/DataSources/ConeVisualizer.js +++ b/Source/DataSources/ConeVisualizer.js @@ -41,7 +41,8 @@ define([ spherical.magnitude = 1.0; } - function computeDirections(minimumClockAngle, maximumClockAngle, innerHalfAngle, outerHalfAngle, result) { + function computeDirections(cone, minimumClockAngle, maximumClockAngle, innerHalfAngle, outerHalfAngle) { + var directions = cone.directions; var angle; var i = 0; var angleStep = CesiumMath.toRadians(2.0); @@ -49,25 +50,25 @@ define([ // No clock angle limits, so this is just a circle. // There might be a hole but we're ignoring it for now. for (angle = 0.0; angle < CesiumMath.TWO_PI; angle += angleStep) { - assignSpherical(i++, result, angle, outerHalfAngle); + assignSpherical(i++, directions, angle, outerHalfAngle); } } else { // There are clock angle limits. for (angle = minimumClockAngle; angle < maximumClockAngle; angle += angleStep) { - assignSpherical(i++, result, angle, outerHalfAngle); + assignSpherical(i++, directions, angle, outerHalfAngle); } - assignSpherical(i++, result, maximumClockAngle, outerHalfAngle); + assignSpherical(i++, directions, maximumClockAngle, outerHalfAngle); if (innerHalfAngle) { for (angle = maximumClockAngle; angle > minimumClockAngle; angle -= angleStep) { - assignSpherical(i++, result, angle, innerHalfAngle); + assignSpherical(i++, directions, angle, innerHalfAngle); } - assignSpherical(i++, result, minimumClockAngle, innerHalfAngle); + assignSpherical(i++, directions, minimumClockAngle, innerHalfAngle); } else { - assignSpherical(i++, result, maximumClockAngle, 0.0); + assignSpherical(i++, directions, maximumClockAngle, 0.0); } } - result.length = i; - return result; + directions.length = i; + cone.directions = directions; } /** @@ -91,9 +92,7 @@ define([ entityCollection.collectionChanged.addEventListener(ConeVisualizer.prototype._onObjectsRemoved, this); this._scene = scene; - this._unusedIndexes = []; this._primitives = scene.primitives; - this._coneCollection = []; this._entityCollection = entityCollection; }; @@ -133,27 +132,15 @@ define([ ConeVisualizer.prototype.destroy = function() { var entityCollection = this._entityCollection; entityCollection.collectionChanged.removeEventListener(ConeVisualizer.prototype._onObjectsRemoved, this); - - var i; - var entities = entityCollection.entities; - var length = entities.length; - for (i = 0; i < length; i++) { - entities[i]._coneVisualizerIndex = undefined; - } - - length = this._coneCollection.length; - for (i = 0; i < length; i++) { - this._primitives.remove(this._coneCollection[i]); - } - + this._onObjectsRemoved(entityCollection, undefined, entityCollection.entities); return destroyObject(this); }; var cachedPosition = new Cartesian3(); var cachedOrientation = new Quaternion(); - function updateObject(coneVisualizer, time, entity) { - var coneGraphics = entity._cone; - if (!defined(coneGraphics)) { + function updateObject(visualizer, time, entity) { + var dynamicCone = entity._cone; + if (!defined(dynamicCone)) { return; } @@ -167,51 +154,29 @@ define([ return; } - var cone; - var showProperty = coneGraphics._show; - var coneVisualizerIndex = entity._coneVisualizerIndex; + var cone = entity._conePrimitive; + var showProperty = dynamicCone._show; var show = entity.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); if (!show) { //don't bother creating or updating anything else - if (defined(coneVisualizerIndex)) { - cone = coneVisualizer._coneCollection[coneVisualizerIndex]; + if (defined(cone)) { cone.show = false; - entity._coneVisualizerIndex = undefined; - coneVisualizer._unusedIndexes.push(coneVisualizerIndex); } return; } - if (!defined(coneVisualizerIndex)) { - var unusedIndexes = coneVisualizer._unusedIndexes; - var length = unusedIndexes.length; - if (length > 0) { - coneVisualizerIndex = unusedIndexes.pop(); - cone = coneVisualizer._coneCollection[coneVisualizerIndex]; - } else { - coneVisualizerIndex = coneVisualizer._coneCollection.length; - cone = new CustomSensorVolume(); - cone._directionsScratch = []; - coneVisualizer._coneCollection.push(cone); - coneVisualizer._primitives.add(cone); - } - entity._coneVisualizerIndex = coneVisualizerIndex; + if (!defined(cone)) { + cone = new CustomSensorVolume(); cone.id = entity; - - cone.material = Material.fromType(Material.ColorType); - cone.intersectionColor = Color.clone(Color.YELLOW); - cone.intersectionWidth = 5.0; - cone.radius = Number.POSITIVE_INFINITY; - cone.showIntersection = true; - } else { - cone = coneVisualizer._coneCollection[coneVisualizerIndex]; + cone.lateralSurfaceMaterial = Material.fromType(Material.ColorType); + entity._conePrimitive = cone; + visualizer._primitives.add(cone); } - cone.show = true; var minimumClockAngle; - var property = coneGraphics._minimumClockAngle; + var property = dynamicCone._minimumClockAngle; if (defined(property)) { minimumClockAngle = property.getValue(time); } @@ -220,7 +185,7 @@ define([ } var maximumClockAngle; - property = coneGraphics._maximumClockAngle; + property = dynamicCone._maximumClockAngle; if (defined(property)) { maximumClockAngle = property.getValue(time); } @@ -229,7 +194,7 @@ define([ } var innerHalfAngle; - property = coneGraphics._innerHalfAngle; + property = dynamicCone._innerHalfAngle; if (defined(property)) { innerHalfAngle = property.getValue(time); } @@ -238,7 +203,7 @@ define([ } var outerHalfAngle; - property = coneGraphics._outerHalfAngle; + property = dynamicCone._outerHalfAngle; if (defined(property)) { outerHalfAngle = property.getValue(time); } @@ -251,14 +216,14 @@ define([ innerHalfAngle !== cone.innerHalfAngle || outerHalfAngle !== cone.outerHalfAngle) { - cone.setDirections(computeDirections(minimumClockAngle, maximumClockAngle, innerHalfAngle, outerHalfAngle, cone._directionsScratch)); + computeDirections(cone, minimumClockAngle, maximumClockAngle, innerHalfAngle, outerHalfAngle); cone.innerHalfAngle = innerHalfAngle; cone.maximumClockAngle = maximumClockAngle; cone.outerHalfAngle = outerHalfAngle; cone.minimumClockAngle = minimumClockAngle; } - property = coneGraphics._radius; + property = dynamicCone._radius; if (defined(property)) { var radius = property.getValue(time); if (defined(radius)) { @@ -278,14 +243,14 @@ define([ cone._visualizerOrientation = Quaternion.clone(orientation, cone._visualizerOrientation); } - cone.material = MaterialProperty.getValue(time, coneGraphics._outerMaterial, cone.material); + cone.lateralSurfaceMaterial = MaterialProperty.getValue(time, dynamicCone._lateralSurfaceMaterial, cone.lateralSurfaceMaterial); - property = coneGraphics._intersectionColor; + property = dynamicCone._intersectionColor; if (defined(property)) { property.getValue(time, cone.intersectionColor); } - property = coneGraphics._intersectionWidth; + property = dynamicCone._intersectionWidth; if (defined(property)) { var intersectionWidth = property.getValue(time); if (defined(intersectionWidth)) { @@ -294,17 +259,14 @@ define([ } } - ConeVisualizer.prototype._onObjectsRemoved = function(entityCollection, added, entities) { - var thisConeCollection = this._coneCollection; - var thisUnusedIndexes = this._unusedIndexes; - for (var i = entities.length - 1; i > -1; i--) { - var entity = entities[i]; - var coneVisualizerIndex = entity._coneVisualizerIndex; - if (defined(coneVisualizerIndex)) { - var cone = thisConeCollection[coneVisualizerIndex]; - cone.show = false; - thisUnusedIndexes.push(coneVisualizerIndex); - entity._coneVisualizerIndex = undefined; + ConeVisualizer.prototype._onObjectsRemoved = function(entityCollection, added, removed) { + var primitives = this._primitives; + for (var i = removed.length - 1; i > -1; i--) { + var entity = removed[i]; + var cone = entity._conePrimitive; + if (defined(cone)) { + primitives.remove(cone); + entity._conePrimitive = undefined; } } }; diff --git a/Source/DataSources/CzmlDataSource.js b/Source/DataSources/CzmlDataSource.js index 71dfe04a876a..f64e0dbb3670 100644 --- a/Source/DataSources/CzmlDataSource.js +++ b/Source/DataSources/CzmlDataSource.js @@ -1071,10 +1071,7 @@ define([ processPacketData(Number, cone, 'outerHalfAngle', coneData.outerHalfAngle, interval, sourceUri, entityCollection); processPacketData(Number, cone, 'minimumClockAngle', coneData.minimumClockAngle, interval, sourceUri, entityCollection); processPacketData(Number, cone, 'maximumClockAngle', coneData.maximumClockAngle, interval, sourceUri, entityCollection); - processMaterialPacketData(cone, 'capMaterial', coneData.capMaterial, interval, sourceUri, entityCollection); - processMaterialPacketData(cone, 'innerMaterial', coneData.innerMaterial, interval, sourceUri, entityCollection); - processMaterialPacketData(cone, 'outerMaterial', coneData.outerMaterial, interval, sourceUri, entityCollection); - processMaterialPacketData(cone, 'silhouetteMaterial', coneData.silhouetteMaterial, interval, sourceUri, entityCollection); + processMaterialPacketData(cone, 'lateralSurfaceMaterial', coneData.lateralSurfaceMaterial, interval, sourceUri, entityCollection); } function processEllipse(entity, packet, entityCollection, sourceUri) { @@ -1373,18 +1370,23 @@ define([ var i; var len; var values = []; - var tmp = directions.unitSpherical; - if (defined(tmp)) { - for (i = 0, len = tmp.length; i < len; i += 2) { - values.push(new Spherical(tmp[i], tmp[i + 1])); + var unitSphericals = directions.unitSpherical; + var sphericals = directions.spherical; + var unitCartesians = directions.unitCartesian; + + if (defined(unitSphericals)) { + for (i = 0, len = unitSphericals.length; i < len; i += 2) { + values.push(new Spherical(unitSphericals[i], unitSphericals[i + 1])); } directions.array = values; + } else if (defined(sphericals)) { + for (i = 0, len = sphericals.length; i < len; i += 3) { + values.push(new Spherical(sphericals[i], sphericals[i + 1], sphericals[i + 2])); } - - tmp = directions.unitCartesian; - if (defined(tmp)) { - for (i = 0, len = tmp.length; i < len; i += 3) { - values.push(Spherical.fromCartesian3(new Cartesian3(tmp[i], tmp[i + 1], tmp[i + 2]))); + directions.array = values; + } else if (defined(unitCartesians)) { + for (i = 0, len = unitCartesians.length; i < len; i += 3) { + values.push(Spherical.fromCartesian3(new Cartesian3(unitCartesians[i], unitCartesians[i + 1], unitCartesians[i + 2]))); } directions.array = values; } @@ -1414,7 +1416,7 @@ define([ processPacketData(Boolean, pyramid, 'showIntersection', pyramidData.showIntersection, interval, sourceUri, entityCollection); processPacketData(Color, pyramid, 'intersectionColor', pyramidData.intersectionColor, interval, sourceUri, entityCollection); processPacketData(Number, pyramid, 'intersectionWidth', pyramidData.intersectionWidth, interval, sourceUri, entityCollection); - processMaterialPacketData(pyramid, 'material', pyramidData.material, interval, sourceUri, entityCollection); + processMaterialPacketData(pyramid, 'lateralSurfaceMaterial', pyramidData.lateralSurfaceMaterial, interval, sourceUri, entityCollection); //The directions property is a special case value that can be an array of unitSpherical or unit Cartesians. //We pre-process this into Spherical instances and then process it like any other array. diff --git a/Source/DataSources/PyramidGraphics.js b/Source/DataSources/PyramidGraphics.js index a5cc95fa08ed..1877bd57c4a0 100644 --- a/Source/DataSources/PyramidGraphics.js +++ b/Source/DataSources/PyramidGraphics.js @@ -22,20 +22,24 @@ define([ * @constructor */ var PyramidGraphics = function() { - this._show = undefined; - this._showSubscription = undefined; this._directions = undefined; this._directionsSubscription = undefined; - this._radius = undefined; - this._radiusSubscription = undefined; - this._showIntersection = undefined; - this._showIntersectionSubscription = undefined; + + this._lateralSurfaceMaterial = undefined; + this._lateralSurfaceMaterialSubscription = undefined; + + this._portionToDisplay = undefined; + this._portionToDisplaySubscription = undefined; this._intersectionColor = undefined; this._intersectionColorSubscription = undefined; this._intersectionWidth = undefined; this._intersectionWidthSubscription = undefined; - this._material = undefined; - this._materialSubscription = undefined; + this._showIntersection = undefined; + this._showIntersectionSubscription = undefined; + this._radius = undefined; + this._radiusSubscription = undefined; + this._show = undefined; + this._showSubscription = undefined; this._definitionChanged = new Event(); }; @@ -54,53 +58,53 @@ define([ }, /** - * Gets or sets the boolean {@link Property} specifying the visibility of the pyramid. + * A {@link Property} which returns an array of {@link Spherical} instances representing the pyramid's projection. * @memberof PyramidGraphics.prototype * @type {Property} */ - show : createPropertyDescriptor('show'), + directions : createPropertyDescriptor('directions'), /** - * A {@link Property} which returns an array of {@link Spherical} instances representing the pyramid's projection. + * Gets or sets the {@link MaterialProperty} specifying the the pyramid's appearance. * @memberof PyramidGraphics.prototype - * @type {Property} + * @type {MaterialProperty} */ - directions : createPropertyDescriptor('directions'), + lateralSurfaceMaterial : createPropertyDescriptor('lateralSurfaceMaterial'), /** - * Gets or sets the numeric {@link Property} specifying the radius of the pyramid's projection. + * Gets or sets the {@link Color} {@link Property} specifying the color of the line formed by the intersection of the pyramid and other central bodies. * @memberof PyramidGraphics.prototype * @type {Property} */ - radius : createPropertyDescriptor('radius'), + intersectionColor : createPropertyDescriptor('intersectionColor'), /** - * Gets or sets the boolean {@link Property} specifying the visibility of the line formed by the intersection of the pyramid and other central bodies. + * Gets or sets the numeric {@link Property} specifying the width of the line formed by the intersection of the pyramid and other central bodies. * @memberof PyramidGraphics.prototype * @type {Property} */ - showIntersection : createPropertyDescriptor('showIntersection'), + intersectionWidth : createPropertyDescriptor('intersectionWidth'), /** - * Gets or sets the {@link Color} {@link Property} specifying the color of the line formed by the intersection of the pyramid and other central bodies. + * Gets or sets the boolean {@link Property} specifying the visibility of the line formed by the intersection of the pyramid and other central bodies. * @memberof PyramidGraphics.prototype * @type {Property} */ - intersectionColor : createPropertyDescriptor('intersectionColor'), + showIntersection : createPropertyDescriptor('showIntersection'), /** - * Gets or sets the numeric {@link Property} specifying the width of the line formed by the intersection of the pyramid and other central bodies. + * Gets or sets the numeric {@link Property} specifying the radius of the pyramid's projection. * @memberof PyramidGraphics.prototype * @type {Property} */ - intersectionWidth : createPropertyDescriptor('intersectionWidth'), + radius : createPropertyDescriptor('radius'), /** - * Gets or sets the {@link MaterialProperty} specifying the the pyramid's appearance. + * Gets or sets the boolean {@link Property} specifying the visibility of the pyramid. * @memberof PyramidGraphics.prototype - * @type {MaterialProperty} + * @type {Property} */ - material : createPropertyDescriptor('material') + show : createPropertyDescriptor('show') }); /** @@ -113,13 +117,13 @@ define([ if (!defined(result)) { result = new PyramidGraphics(); } - result.show = this.show; result.directions = this.directions; result.radius = this.radius; + result.show = this.show; result.showIntersection = this.showIntersection; result.intersectionColor = this.intersectionColor; result.intersectionWidth = this.intersectionWidth; - result.material = this.material; + result.lateralSurfaceMaterial = this.lateralSurfaceMaterial; return result; }; @@ -136,13 +140,13 @@ define([ } //>>includeEnd('debug'); - this.show = defaultValue(this.show, source.show); this.directions = defaultValue(this.directions, source.directions); this.radius = defaultValue(this.radius, source.radius); + this.show = defaultValue(this.show, source.show); this.showIntersection = defaultValue(this.showIntersection, source.showIntersection); this.intersectionColor = defaultValue(this.intersectionColor, source.intersectionColor); this.intersectionWidth = defaultValue(this.intersectionWidth, source.intersectionWidth); - this.material = defaultValue(this.material, source.material); + this.lateralSurfaceMaterial = defaultValue(this.lateralSurfaceMaterial, source.lateralSurfaceMaterial); }; return PyramidGraphics; diff --git a/Source/DataSources/PyramidVisualizer.js b/Source/DataSources/PyramidVisualizer.js index c0001cfa73b6..95456d9ad343 100644 --- a/Source/DataSources/PyramidVisualizer.js +++ b/Source/DataSources/PyramidVisualizer.js @@ -50,9 +50,7 @@ define([ entityCollection.collectionChanged.addEventListener(PyramidVisualizer.prototype._onObjectsRemoved, this); this._scene = scene; - this._unusedIndexes = []; this._primitives = scene.primitives; - this._pyramidCollection = []; this._entityCollection = entityCollection; }; @@ -90,31 +88,21 @@ define([ * Removes and destroys all primitives created by this instance. */ PyramidVisualizer.prototype.destroy = function() { - var i; - var length = this._pyramidCollection.length; - var primitives = this._primitives; - for (i = 0; i < length; i++) { - primitives.remove(this._pyramidCollection[i]); - } - - var entities = this._entityCollection.entities; - length = entities.length; - for (i = 0; i < length; i++) { - entities[i]._pyramidVisualizerIndex = undefined; - } - + var entityCollection = this._entityCollection; + entityCollection.collectionChanged.removeEventListener(PyramidVisualizer.prototype._onObjectsRemoved, this); + this._onObjectsRemoved(entityCollection, undefined, entityCollection.entities); return destroyObject(this); }; var position; var orientation; - function updateObject(pyramidVisualizer, time, entity) { - var pyramidGraphics = entity._pyramid; - if (!defined(pyramidGraphics)) { + function updateObject(visualizer, time, entity) { + var dynamicPyramid = entity._pyramid; + if (!defined(dynamicPyramid)) { return; } - var directionsProperty = pyramidGraphics._directions; + var directionsProperty = dynamicPyramid._directions; if (!defined(directionsProperty)) { return; } @@ -129,55 +117,41 @@ define([ return; } - var pyramid; - var showProperty = pyramidGraphics._show; - var pyramidVisualizerIndex = entity._pyramidVisualizerIndex; + var pyramid = entity._pyramidPrimitive; + var showProperty = dynamicPyramid._show; var show = entity.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); if (!show) { //don't bother creating or updating anything else - if (defined(pyramidVisualizerIndex)) { - pyramid = pyramidVisualizer._pyramidCollection[pyramidVisualizerIndex]; + if (defined(pyramid)) { pyramid.show = false; - entity._pyramidVisualizerIndex = undefined; - pyramidVisualizer._unusedIndexes.push(pyramidVisualizerIndex); } return; } - if (!defined(pyramidVisualizerIndex)) { - var unusedIndexes = pyramidVisualizer._unusedIndexes; - var length = unusedIndexes.length; - if (length > 0) { - pyramidVisualizerIndex = unusedIndexes.pop(); - pyramid = pyramidVisualizer._pyramidCollection[pyramidVisualizerIndex]; - } else { - pyramidVisualizerIndex = pyramidVisualizer._pyramidCollection.length; - pyramid = new CustomSensorVolume(); - - pyramidVisualizer._pyramidCollection.push(pyramid); - pyramidVisualizer._primitives.add(pyramid); - } - entity._pyramidVisualizerIndex = pyramidVisualizerIndex; + if (!defined(pyramid)) { + pyramid = new CustomSensorVolume(); pyramid.id = entity; - - pyramid.radius = Number.POSITIVE_INFINITY; - pyramid.showIntersection = true; - pyramid.intersectionColor = Color.YELLOW; - pyramid.intersectionWidth = 5.0; - pyramid.material = Material.fromType(Material.ColorType); - } else { - pyramid = pyramidVisualizer._pyramidCollection[pyramidVisualizerIndex]; + pyramid.lateralSurfaceMaterial = Material.fromType(Material.ColorType); + entity._pyramidPrimitive = pyramid; + visualizer._primitives.add(pyramid); } - pyramid.show = true; var directions = directionsProperty.getValue(time); if (defined(directions) && pyramid._visualizerDirections !== directions) { - pyramid.setDirections(directions); + pyramid.directions = directions; pyramid._visualizerDirections = directions; } + var property = dynamicPyramid._radius; + if (defined(property)) { + var radius = property.getValue(time); + if (defined(radius)) { + pyramid.radius = radius; + } + } + position = defaultValue(positionProperty.getValue(time, position), pyramid._visualizerPosition); orientation = defaultValue(orientationProperty.getValue(time, orientation), pyramid._visualizerOrientation); @@ -186,48 +160,37 @@ define([ (!Cartesian3.equals(position, pyramid._visualizerPosition) || !Quaternion.equals(orientation, pyramid._visualizerOrientation))) { Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation, matrix3Scratch), position, pyramid.modelMatrix); - Cartesian3.clone(position, pyramid._visualizerPosition); - Quaternion.clone(orientation, pyramid._visualizerOrientation); + pyramid._visualizerPosition = Cartesian3.clone(position, pyramid._visualizerPosition); + pyramid._visualizerOrientation = Quaternion.clone(orientation, pyramid._visualizerOrientation); } - pyramid.material = MaterialProperty.getValue(time, pyramidGraphics._material, pyramid.material); + pyramid.lateralSurfaceMaterial = MaterialProperty.getValue(time, dynamicPyramid._lateralSurfaceMaterial, pyramid.lateralSurfaceMaterial); - var property = pyramidGraphics._intersectionColor; + property = dynamicPyramid._intersectionColor; if (defined(property)) { - var intersectionColor = property.getValue(time, intersectionColor); + var intersectionColor = property.getValue(time, pyramid.intersectionColor); if (defined(intersectionColor)) { pyramid.intersectionColor = intersectionColor; } } - property = pyramidGraphics._intersectionWidth; + property = dynamicPyramid._intersectionWidth; if (defined(property)) { - var intersectionWidth = property.getValue(time, intersectionWidth); + var intersectionWidth = property.getValue(time); if (defined(intersectionWidth)) { pyramid.intersectionWidth = intersectionWidth; } } - - property = pyramidGraphics._radius; - if (defined(property)) { - var radius = property.getValue(time, radius); - if (defined(radius)) { - pyramid.radius = radius; - } - } } - PyramidVisualizer.prototype._onObjectsRemoved = function(entityCollection, added, entities) { - var thisPyramidCollection = this._pyramidCollection; - var thisUnusedIndexes = this._unusedIndexes; - for (var i = entities.length - 1; i > -1; i--) { - var entity = entities[i]; - var pyramidVisualizerIndex = entity._pyramidVisualizerIndex; - if (defined(pyramidVisualizerIndex)) { - var pyramid = thisPyramidCollection[pyramidVisualizerIndex]; - pyramid.show = false; - thisUnusedIndexes.push(pyramidVisualizerIndex); - entity._pyramidVisualizerIndex = undefined; + PyramidVisualizer.prototype._onObjectsRemoved = function(entityCollection, added, removed) { + var primitives = this._primitives; + for (var i = removed.length - 1; i > -1; i--) { + var entity = removed[i]; + var pyramid = entity._pyramidPrimitive; + if (defined(pyramid)) { + primitives.remove(pyramid); + entity._pyramidPrimitive = undefined; } } }; diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 8391077359d3..ffcd7ef31de3 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -7,6 +7,7 @@ define([ '../Core/ComponentDatatype', '../Core/defaultValue', '../Core/defined', + '../Core/defineProperties', '../Core/destroyObject', '../Core/DeveloperError', '../Core/Matrix4', @@ -30,6 +31,7 @@ define([ ComponentDatatype, defaultValue, defined, + defineProperties, destroyObject, DeveloperError, Matrix4, @@ -59,8 +61,6 @@ define([ * * @alias CustomSensorVolume * @constructor - * - * @see SensorVolumeCollection#addCustom */ var CustomSensorVolume = function(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -151,7 +151,7 @@ define([ this._directions = undefined; this._directionsDirty = false; - this.setDirections(options.directions); + this.directions = defined(options.directions) ? options.directions : []; /** * The surface appearance of the sensor. This can be one of several built-in {@link Material} objects or a custom material, scripted with @@ -172,8 +172,8 @@ define([ * // 2. Change material to horizontal stripes * sensor.material = Cesium.Material.fromType(Material.StripeType); */ - this.material = defined(options.material) ? options.material : Material.fromType(Material.ColorType); - this._material = undefined; + this.lateralSurfaceMaterial = defined(options.lateralSurfaceMaterial) ? options.lateralSurfaceMaterial : Material.fromType(Material.ColorType); + this._lateralSurfaceMaterial = undefined; this._translucent = undefined; /** @@ -233,24 +233,17 @@ define([ this._mode = SceneMode.SCENE3D; }; - /** - * DOC_TBA - * - * @see CustomSensorVolume#getDirections - */ - CustomSensorVolume.prototype.setDirections = function(directions) { - this._directions = directions; - this._directionsDirty = true; - }; - - /** - * DOC_TBA - * - * @see CustomSensorVolume#setDirections - */ - CustomSensorVolume.prototype.getDirections = function() { - return this._directions; - }; + defineProperties(CustomSensorVolume.prototype, { + directions : { + get : function() { + return this._directions; + }, + set : function(value) { + this._directions = value; + this._directionsDirty = true; + } + } + }); var n0Scratch = new Cartesian3(); var n1Scratch = new Cartesian3(); @@ -352,7 +345,7 @@ define([ *

* * @exception {DeveloperError} this.radius must be greater than or equal to zero. - * @exception {DeveloperError} this.material must be defined. + * @exception {DeveloperError} this.lateralSurfaceMaterial must be defined. */ CustomSensorVolume.prototype.update = function(context, frameState, commandList) { this._mode = frameState.mode; @@ -364,12 +357,12 @@ define([ if (this.radius < 0.0) { throw new DeveloperError('this.radius must be greater than or equal to zero.'); } - if (!defined(this.material)) { - throw new DeveloperError('this.material must be defined.'); + if (!defined(this.lateralSurfaceMaterial)) { + throw new DeveloperError('this.lateralSurfaceMaterial must be defined.'); } //>>includeEnd('debug'); - var translucent = this.material.isTranslucent(); + var translucent = this.lateralSurfaceMaterial.isTranslucent(); // Initial render state creation if ((this._showThroughEllipsoid !== this.showThroughEllipsoid) || @@ -476,9 +469,9 @@ define([ this._backFaceColorCommand.modelMatrix = this._frontFaceColorCommand.modelMatrix; this._pickCommand.modelMatrix = this._frontFaceColorCommand.modelMatrix; - var materialChanged = this._material !== this.material; - this._material = this.material; - this._material.update(context); + var materialChanged = this._lateralSurfaceMaterial !== this.lateralSurfaceMaterial; + this._lateralSurfaceMaterial = this.lateralSurfaceMaterial; + this._lateralSurfaceMaterial.update(context); if (pass.render) { var frontFaceColorCommand = this._frontFaceColorCommand; @@ -487,15 +480,15 @@ define([ // Recompile shader when material changes if (materialChanged || !defined(frontFaceColorCommand.shaderProgram)) { var fsSource = createShaderSource({ - sources : [ShadersSensorVolume, this._material.shaderSource, CustomSensorVolumeFS] + sources : [ShadersSensorVolume, this._lateralSurfaceMaterial.shaderSource, CustomSensorVolumeFS] }); frontFaceColorCommand.shaderProgram = context.replaceShaderProgram( frontFaceColorCommand.shaderProgram, CustomSensorVolumeVS, fsSource, attributeLocations); - frontFaceColorCommand.uniformMap = combine(this._uniforms, this._material._uniforms); + frontFaceColorCommand.uniformMap = combine(this._uniforms, this._lateralSurfaceMaterial._uniforms); backFaceColorCommand.shaderProgram = frontFaceColorCommand.shaderProgram; - backFaceColorCommand.uniformMap = combine(this._uniforms, this._material._uniforms); + backFaceColorCommand.uniformMap = combine(this._uniforms, this._lateralSurfaceMaterial._uniforms); backFaceColorCommand.uniformMap.u_normalDirection = function() { return -1.0; }; @@ -523,7 +516,7 @@ define([ // Recompile shader when material changes if (materialChanged || !defined(pickCommand.shaderProgram)) { var pickFS = createShaderSource({ - sources : [ShadersSensorVolume, this._material.shaderSource, CustomSensorVolumeFS], + sources : [ShadersSensorVolume, this._lateralSurfaceMaterial.shaderSource, CustomSensorVolumeFS], pickColorQualifier : 'uniform' }); @@ -536,7 +529,7 @@ define([ return that._pickId.color; } }; - pickCommand.uniformMap = combine(combine(this._uniforms, this._material._uniforms), uniforms); + pickCommand.uniformMap = combine(combine(this._uniforms, this._lateralSurfaceMaterial._uniforms), uniforms); } pickCommand.pass = translucent ? Pass.TRANSLUCENT : Pass.OPAQUE; diff --git a/Source/Scene/RectangularPyramidSensorVolume.js b/Source/Scene/RectangularPyramidSensorVolume.js index 21c7c7c57fef..251bfed5062a 100644 --- a/Source/Scene/RectangularPyramidSensorVolume.js +++ b/Source/Scene/RectangularPyramidSensorVolume.js @@ -28,8 +28,6 @@ define([ * * @alias RectangularPyramidSensorVolume * @constructor - * - * @see SensorVolumeCollection#addRectangularPyramid */ var RectangularPyramidSensorVolume = function(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -131,12 +129,12 @@ define([ * * @example * // 1. Change the color of the default material to yellow - * sensor.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); + * sensor.lateralSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); * * // 2. Change material to horizontal stripes - * sensor.material = Cesium.Material.fromType(Cesium.Material.StripeType); + * sensor.lateralSurfaceMaterial = Cesium.Material.fromType(Cesium.Material.StripeType); */ - this.material = defined(options.material) ? options.material : Material.fromType(Material.ColorType); + this.lateralSurfaceMaterial = defined(options.lateralSurfaceMaterial) ? options.lateralSurfaceMaterial : Material.fromType(Material.ColorType); /** * The color of the polyline where the sensor outline intersects the globe. The default is {@link Color.WHITE}. @@ -199,7 +197,7 @@ define([ s.showThroughEllipsoid = this.showThroughEllipsoid; s.modelMatrix = this.modelMatrix; s.radius = this.radius; - s.material = this.material; + s.lateralSurfaceMaterial = this.lateralSurfaceMaterial; s.intersectionColor = this.intersectionColor; s.intersectionWidth = this.intersectionWidth; s.id = this.id; @@ -215,7 +213,7 @@ define([ var theta = Math.atan(tanX / tanY); var cone = Math.atan(Math.sqrt(tanX * tanX + tanY * tanY)); - s.setDirections([{ + s.directions = [{ clock : theta, cone : cone }, { @@ -227,7 +225,7 @@ define([ }, { clock : -theta, cone : cone - }]); + }]; } s.update(context, frameState, commandList); diff --git a/Source/Scene/SensorVolumeCollection.js b/Source/Scene/SensorVolumeCollection.js deleted file mode 100644 index f6527ca983b9..000000000000 --- a/Source/Scene/SensorVolumeCollection.js +++ /dev/null @@ -1,161 +0,0 @@ -/*global define*/ -define([ - '../Core/defined', - '../Core/defineProperties', - '../Core/destroyObject', - '../Core/DeveloperError', - './CustomSensorVolume', - './RectangularPyramidSensorVolume', - './SceneMode' - ], function( - defined, - defineProperties, - destroyObject, - DeveloperError, - CustomSensorVolume, - RectangularPyramidSensorVolume, - SceneMode) { - "use strict"; - - /** - * DOC_TBA - * - * @alias SensorVolumeCollection - * @constructor - * - * @demo {@link http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Sensors.html|Cesium Sandcastle Sensors Demo} - */ - var SensorVolumeCollection = function() { - this._sensors = []; - }; - - defineProperties(SensorVolumeCollection.prototype, { - /** - * DOC_TBA - * @memberof SensorVolumeCollection.prototype - * @type {Event} - */ - length : { - get : function() { - return this._sensors.length; - } - } - }); - - /** - * DOC_TBA - * - * @see SensorVolumeCollection#addCustom - * @see SensorVolumeCollection#addComplexConic - */ - SensorVolumeCollection.prototype.addRectangularPyramid = function(options) { - var sensor = new RectangularPyramidSensorVolume(options); - this._sensors.push(sensor); - return sensor; - }; - - /** - * DOC_TBA - * - * @see SensorVolumeCollection#addRectangularPyramid - * @see SensorVolumeCollection#addComplexConic - */ - SensorVolumeCollection.prototype.addCustom = function(options) { - var sensor = new CustomSensorVolume(options); - this._sensors.push(sensor); - return sensor; - }; - - /** - * DOC_TBA - * - * @see SensorVolumeCollection#removeAll - */ - SensorVolumeCollection.prototype.remove = function(sensor) { - if (sensor) { - var sensors = this._sensors; - var i = sensors.indexOf(sensor); - if (i !== -1) { - sensors[i].destroy(); - sensors.splice(i, 1); - return true; - } - } - - return false; - }; - - /** - * DOC_TBA - * - * @see SensorVolumeCollection#remove - */ - SensorVolumeCollection.prototype.removeAll = function() { - var sensors = this._sensors; - var length = sensors.length; - for ( var i = 0; i < length; ++i) { - sensors[i].destroy(); - } - - this._sensors = []; - }; - - /** - * DOC_TBA - */ - SensorVolumeCollection.prototype.contains = function(sensor) { - if (sensor) { - return (this._sensors.indexOf(sensor) !== -1); - } - - return false; - }; - - /** - * DOC_TBA - * - * @see SensorVolumeCollection#length - */ - SensorVolumeCollection.prototype.get = function(index) { - //>>includeStart('debug', pragmas.debug); - if (!defined(index)) { - throw new DeveloperError('index is required.'); - } - //>>includeEnd('debug'); - - return this._sensors[index]; - }; - - /** - * @private - */ - SensorVolumeCollection.prototype.update = function(context, frameState, commandList) { - var mode = frameState.mode; - if (mode !== SceneMode.SCENE3D) { - return; - } - - var sensors = this._sensors; - var length = sensors.length; - for (var i = 0; i < length; ++i) { - sensors[i].update(context, frameState, commandList); - } - }; - - /** - * DOC_TBA - */ - SensorVolumeCollection.prototype.isDestroyed = function() { - return false; - }; - - /** - * DOC_TBA - */ - SensorVolumeCollection.prototype.destroy = function() { - this.removeAll(); - return destroyObject(this); - }; - - return SensorVolumeCollection; -}); diff --git a/Specs/DataSources/ConeGraphicsSpec.js b/Specs/DataSources/ConeGraphicsSpec.js index 7e9860756a01..f8c6d07d0aae 100644 --- a/Specs/DataSources/ConeGraphicsSpec.js +++ b/Specs/DataSources/ConeGraphicsSpec.js @@ -14,10 +14,7 @@ defineSuite([ it('merge assigns unassigned properties', function() { var source = new ConeGraphics(); - source.capMaterial = new ColorMaterialProperty(); - source.innerMaterial = new ColorMaterialProperty(); - source.silhouetteMaterial = new ColorMaterialProperty(); - source.outerMaterial = new ColorMaterialProperty(); + source.lateralSurfaceMaterial = new ColorMaterialProperty(); source.innerHalfAngle = new ConstantProperty(1); source.maximumClockAngle = new ConstantProperty(1); source.minimumClockAngle = new ConstantProperty(1); @@ -32,10 +29,7 @@ defineSuite([ var target = new ConeGraphics(); target.merge(source); - expect(target.capMaterial).toBe(source.capMaterial); - expect(target.innerMaterial).toBe(source.innerMaterial); - expect(target.silhouetteMaterial).toBe(source.silhouetteMaterial); - expect(target.outerMaterial).toBe(source.outerMaterial); + expect(target.lateralSurfaceMaterial).toBe(source.lateralSurfaceMaterial); expect(target.innerHalfAngle).toBe(source.innerHalfAngle); expect(target.maximumClockAngle).toBe(source.maximumClockAngle); expect(target.minimumClockAngle).toBe(source.minimumClockAngle); @@ -49,10 +43,7 @@ defineSuite([ it('merge does not assign assigned properties', function() { var source = new ConeGraphics(); - source.capMaterial = new ColorMaterialProperty(); - source.innerMaterial = new ColorMaterialProperty(); - source.silhouetteMaterial = new ColorMaterialProperty(); - source.outerMaterial = new ColorMaterialProperty(); + source.lateralSurfaceMaterial = new ColorMaterialProperty(); source.innerHalfAngle = new ConstantProperty(1); source.maximumClockAngle = new ConstantProperty(1); source.minimumClockAngle = new ConstantProperty(1); @@ -63,10 +54,7 @@ defineSuite([ source.showIntersection = new ConstantProperty(true); source.intersectionWidth = new ConstantProperty(1); - var capMaterial = new ColorMaterialProperty(); - var innerMaterial = new ColorMaterialProperty(); - var silhouetteMaterial = new ColorMaterialProperty(); - var outerMaterial = new ColorMaterialProperty(); + var lateralSurfaceMaterial = new ColorMaterialProperty(); var innerHalfAngle = new ConstantProperty(1); var maximumClockAngle = new ConstantProperty(1); var minimumClockAngle = new ConstantProperty(1); @@ -78,26 +66,20 @@ defineSuite([ var intersectionWidth = new ConstantProperty(1); var target = new ConeGraphics(); - source.capMaterial = capMaterial; - source.innerMaterial = innerMaterial; - source.silhouetteMaterial = silhouetteMaterial; - source.outerMaterial = outerMaterial; - source.innerHalfAngle = innerHalfAngle; - source.maximumClockAngle = maximumClockAngle; - source.minimumClockAngle = minimumClockAngle; - source.outerHalfAngle = outerHalfAngle; - source.intersectionColor = intersectionColor; - source.radius = radius; - source.show = show; - source.showIntersection = showIntersection; - source.intersectionWidth = intersectionWidth; + target.lateralSurfaceMaterial = lateralSurfaceMaterial; + target.innerHalfAngle = innerHalfAngle; + target.maximumClockAngle = maximumClockAngle; + target.minimumClockAngle = minimumClockAngle; + target.outerHalfAngle = outerHalfAngle; + target.intersectionColor = intersectionColor; + target.radius = radius; + target.show = show; + target.showIntersection = showIntersection; + target.intersectionWidth = intersectionWidth; target.merge(source); - expect(target.capMaterial).toBe(capMaterial); - expect(target.innerMaterial).toBe(innerMaterial); - expect(target.silhouetteMaterial).toBe(silhouetteMaterial); - expect(target.outerMaterial).toBe(outerMaterial); + expect(target.lateralSurfaceMaterial).toBe(lateralSurfaceMaterial); expect(target.innerHalfAngle).toBe(innerHalfAngle); expect(target.maximumClockAngle).toBe(maximumClockAngle); expect(target.minimumClockAngle).toBe(minimumClockAngle); @@ -111,10 +93,7 @@ defineSuite([ it('clone works', function() { var source = new ConeGraphics(); - source.capMaterial = new ColorMaterialProperty(); - source.innerMaterial = new ColorMaterialProperty(); - source.silhouetteMaterial = new ColorMaterialProperty(); - source.outerMaterial = new ColorMaterialProperty(); + source.lateralSurfaceMaterial = new ColorMaterialProperty(); source.innerHalfAngle = new ConstantProperty(1); source.maximumClockAngle = new ConstantProperty(1); source.minimumClockAngle = new ConstantProperty(1); @@ -126,10 +105,7 @@ defineSuite([ source.intersectionWidth = new ConstantProperty(1); var result = source.clone(); - expect(result.capMaterial).toBe(source.capMaterial); - expect(result.innerMaterial).toBe(source.innerMaterial); - expect(result.silhouetteMaterial).toBe(source.silhouetteMaterial); - expect(result.outerMaterial).toBe(source.outerMaterial); + expect(result.lateralSurfaceMaterial).toBe(source.lateralSurfaceMaterial); expect(result.innerHalfAngle).toBe(source.innerHalfAngle); expect(result.maximumClockAngle).toBe(source.maximumClockAngle); expect(result.minimumClockAngle).toBe(source.minimumClockAngle); diff --git a/Specs/DataSources/ConeVisualizerSpec.js b/Specs/DataSources/ConeVisualizerSpec.js index 2f1f7c339397..dc20577fcbe4 100644 --- a/Specs/DataSources/ConeVisualizerSpec.js +++ b/Specs/DataSources/ConeVisualizerSpec.js @@ -126,11 +126,11 @@ defineSuite([ cone.showIntersection = new ConstantProperty(true); cone.radius = new ConstantProperty(123.5); cone.show = new ConstantProperty(true); + cone.lateralSurfaceMaterial = new ColorMaterialProperty.fromColor(Color.WHITE); - cone.outerMaterial = new ColorMaterialProperty(); visualizer.update(time); - expect(scene.primitives.length).toEqual(1); + var c = scene.primitives.get(0); expect(c.minimumClockAngle).toEqual(testObject.cone.minimumClockAngle.getValue(time)); expect(c.maximumClockAngle).toEqual(testObject.cone.maximumClockAngle.getValue(time)); @@ -140,9 +140,9 @@ defineSuite([ expect(c.intersectionWidth).toEqual(testObject.cone.intersectionWidth.getValue(time)); expect(c.showIntersection).toEqual(testObject.cone.showIntersection.getValue(time)); expect(c.radius).toEqual(testObject.cone.radius.getValue(time)); - expect(c.show).toEqual(testObject.cone.show.getValue(time)); - expect(c.material.uniforms).toEqual(testObject.cone.outerMaterial.getValue(time)); expect(c.modelMatrix).toEqual(Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(testObject.orientation.getValue(time)), testObject.position.getValue(time))); + expect(c.show).toEqual(testObject.cone.show.getValue(time)); + expect(c.lateralSurfaceMaterial.uniforms).toEqual(testObject.cone.lateralSurfaceMaterial.getValue(time)); cone.show.value = false; visualizer.update(time); @@ -200,7 +200,7 @@ defineSuite([ expect(c.show).toEqual(true); }); - it('clear hides cones.', function() { + it('clear removed primitives.', function() { var entityCollection = new EntityCollection(); visualizer = new ConeVisualizer(scene, entityCollection); @@ -218,8 +218,7 @@ defineSuite([ expect(scene.primitives.get(0).show).toEqual(true); entityCollection.removeAll(); visualizer.update(time); - expect(scene.primitives.length).toEqual(1); - expect(scene.primitives.get(0).show).toEqual(false); + expect(scene.primitives.length).toEqual(0); }); it('Visualizer sets entity property.', function() { diff --git a/Specs/DataSources/CzmlDataSourceSpec.js b/Specs/DataSources/CzmlDataSourceSpec.js index 6df8deb2e545..39472f4506cb 100644 --- a/Specs/DataSources/CzmlDataSourceSpec.js +++ b/Specs/DataSources/CzmlDataSourceSpec.js @@ -637,38 +637,17 @@ defineSuite([ maximumClockAngle : 1.3, radius : 2.0, show : true, + intersectionColor : { + rgbaf : [0.5, 0.5, 0.5, 0.5] + }, showIntersection : false, intersectionWidth : 6.0, - capMaterial : { + lateralSurfaceMaterial : { solidColor : { color : { rgbaf : [0.1, 0.1, 0.1, 0.1] } } - }, - innerMaterial : { - solidColor : { - color : { - rgbaf : [0.2, 0.2, 0.2, 0.2] - } - } - }, - outerMaterial : { - solidColor : { - color : { - rgbaf : [0.3, 0.3, 0.3, 0.3] - } - } - }, - silhouetteMaterial : { - solidColor : { - color : { - rgbaf : [0.4, 0.4, 0.4, 0.4] - } - } - }, - intersectionColor : { - rgbaf : [0.5, 0.5, 0.5, 0.5] } } }; @@ -685,12 +664,7 @@ defineSuite([ expect(entity.cone.radius.getValue(Iso8601.MINIMUM_VALUE)).toEqual(conePacket.cone.radius); expect(entity.cone.show.getValue(Iso8601.MINIMUM_VALUE)).toEqual(conePacket.cone.show); expect(entity.cone.showIntersection.getValue(Iso8601.MINIMUM_VALUE)).toEqual(conePacket.cone.showIntersection); - expect(entity.cone.capMaterial.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); - expect(entity.cone.innerMaterial.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); - expect(entity.cone.outerMaterial.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.3, 0.3, 0.3, 0.3)); - expect(entity.cone.silhouetteMaterial.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.4, 0.4, 0.4, 0.4)); - expect(entity.cone.intersectionColor.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.5, 0.5, 0.5, 0.5)); - expect(entity.cone.intersectionWidth.getValue(Iso8601.MINIMUM_VALUE)).toEqual(conePacket.cone.intersectionWidth); + expect(entity.cone.lateralSurfaceMaterial.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); }); it('CZML adds data for constrained cone.', function() { @@ -703,38 +677,17 @@ defineSuite([ maximumClockAngle : 1.3, radius : 2.0, show : true, + intersectionColor : { + rgbaf : [0.5, 0.5, 0.5, 0.5] + }, showIntersection : false, - intersectionWidth : 4.0, - capMaterial : { + intersectionWidth : 6.0, + lateralSurfaceMaterial : { solidColor : { color : { rgbaf : [0.1, 0.1, 0.1, 0.1] } } - }, - innerMaterial : { - solidColor : { - color : { - rgbaf : [0.2, 0.2, 0.2, 0.2] - } - } - }, - outerMaterial : { - solidColor : { - color : { - rgbaf : [0.3, 0.3, 0.3, 0.3] - } - } - }, - silhouetteMaterial : { - solidColor : { - color : { - rgbaf : [0.4, 0.4, 0.4, 0.4] - } - } - }, - intersectionColor : { - rgbaf : [0.5, 0.5, 0.5, 0.5] } } }; @@ -756,10 +709,7 @@ defineSuite([ expect(entity.cone.radius.getValue(validTime)).toEqual(conePacket.cone.radius); expect(entity.cone.show.getValue(validTime)).toEqual(conePacket.cone.show); expect(entity.cone.showIntersection.getValue(validTime)).toEqual(conePacket.cone.showIntersection); - expect(entity.cone.capMaterial.getValue(validTime).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); - expect(entity.cone.innerMaterial.getValue(validTime).color).toEqual(new Color(0.2, 0.2, 0.2, 0.2)); - expect(entity.cone.outerMaterial.getValue(validTime).color).toEqual(new Color(0.3, 0.3, 0.3, 0.3)); - expect(entity.cone.silhouetteMaterial.getValue(validTime).color).toEqual(new Color(0.4, 0.4, 0.4, 0.4)); + expect(entity.cone.lateralSurfaceMaterial.getValue(validTime).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(entity.cone.intersectionColor.getValue(validTime)).toEqual(new Color(0.5, 0.5, 0.5, 0.5)); expect(entity.cone.intersectionWidth.getValue(validTime)).toEqual(conePacket.cone.intersectionWidth); @@ -770,10 +720,7 @@ defineSuite([ expect(entity.cone.radius.getValue(invalidTime)).toBeUndefined(); expect(entity.cone.show.getValue(invalidTime)).toBeUndefined(); expect(entity.cone.showIntersection.getValue(invalidTime)).toBeUndefined(); - expect(entity.cone.capMaterial.getValue(invalidTime)).toBeUndefined(); - expect(entity.cone.innerMaterial.getValue(invalidTime)).toBeUndefined(); - expect(entity.cone.outerMaterial.getValue(invalidTime)).toBeUndefined(); - expect(entity.cone.silhouetteMaterial.getValue(invalidTime)).toBeUndefined(); + expect(entity.cone.lateralSurfaceMaterial.getValue(invalidTime)).toBeUndefined(); expect(entity.cone.intersectionColor.getValue(invalidTime)).toBeUndefined(); expect(entity.cone.intersectionWidth.getValue(invalidTime)).toBeUndefined(); }); @@ -1679,17 +1626,17 @@ defineSuite([ }, radius : 2.0, show : true, + intersectionColor : { + rgbaf : [0.5, 0.5, 0.5, 0.5] + }, showIntersection : false, intersectionWidth : 7.0, - material : { + lateralSurfaceMaterial : { solidColor : { color : { rgbaf : [0.1, 0.1, 0.1, 0.1] } } - }, - intersectionColor : { - rgbaf : [0.5, 0.5, 0.5, 0.5] } } }; @@ -1703,7 +1650,7 @@ defineSuite([ expect(entity.pyramid.radius.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pyramidPacket.pyramid.radius); expect(entity.pyramid.show.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pyramidPacket.pyramid.show); expect(entity.pyramid.showIntersection.getValue(Iso8601.MINIMUM_VALUE)).toEqual(pyramidPacket.pyramid.showIntersection); - expect(entity.pyramid.material.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); + expect(entity.pyramid.lateralSurfaceMaterial.getValue(Iso8601.MINIMUM_VALUE).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(entity.pyramid.intersectionColor.getValue(Iso8601.MINIMUM_VALUE)).toEqual(new Color(0.5, 0.5, 0.5, 0.5)); expect(entity.pyramid.intersectionWidth.getValue(Iso8601.MINIMUM_VALUE)).toEqual(7.0); }); @@ -1740,17 +1687,17 @@ defineSuite([ }, radius : 2.0, show : true, + intersectionColor : { + rgbaf : [0.5, 0.5, 0.5, 0.5] + }, showIntersection : false, intersectionWidth : 8.0, - material : { + lateralSurfaceMaterial : { solidColor : { color : { rgbaf : [0.1, 0.1, 0.1, 0.1] } } - }, - intersectionColor : { - rgbaf : [0.5, 0.5, 0.5, 0.5] } } }; @@ -1769,7 +1716,7 @@ defineSuite([ expect(entity.pyramid.radius.getValue(validTime)).toEqual(pyramidPacket.pyramid.radius); expect(entity.pyramid.show.getValue(validTime)).toEqual(pyramidPacket.pyramid.show); expect(entity.pyramid.showIntersection.getValue(validTime)).toEqual(pyramidPacket.pyramid.showIntersection); - expect(entity.pyramid.material.getValue(validTime).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); + expect(entity.pyramid.lateralSurfaceMaterial.getValue(validTime).color).toEqual(new Color(0.1, 0.1, 0.1, 0.1)); expect(entity.pyramid.intersectionColor.getValue(validTime)).toEqual(new Color(0.5, 0.5, 0.5, 0.5)); expect(entity.pyramid.intersectionWidth.getValue(validTime)).toEqual(8.0); @@ -1777,7 +1724,7 @@ defineSuite([ expect(entity.pyramid.radius.getValue(invalidTime)).toBeUndefined(); expect(entity.pyramid.show.getValue(invalidTime)).toBeUndefined(); expect(entity.pyramid.showIntersection.getValue(invalidTime)).toBeUndefined(); - expect(entity.pyramid.material.getValue(invalidTime)).toBeUndefined(); + expect(entity.pyramid.lateralSurfaceMaterial.getValue(invalidTime)).toBeUndefined(); expect(entity.pyramid.intersectionColor.getValue(invalidTime)).toBeUndefined(); expect(entity.pyramid.intersectionWidth.getValue(invalidTime)).toBeUndefined(); }); diff --git a/Specs/DataSources/PyramidGraphicsSpec.js b/Specs/DataSources/PyramidGraphicsSpec.js index 84ba333326d7..c657bea0c1f4 100644 --- a/Specs/DataSources/PyramidGraphicsSpec.js +++ b/Specs/DataSources/PyramidGraphicsSpec.js @@ -14,7 +14,7 @@ defineSuite([ it('merge assigns unassigned properties', function() { var source = new PyramidGraphics(); - source.material = new ColorMaterialProperty(); + source.lateralSurfaceMaterial = new ColorMaterialProperty(); source.directions = new ConstantProperty([]); source.intersectionColor = new ConstantProperty(Color.WHITE); source.radius = new ConstantProperty(1); @@ -25,7 +25,7 @@ defineSuite([ var target = new PyramidGraphics(); target.merge(source); - expect(target.material).toBe(source.material); + expect(target.lateralSurfaceMaterial).toBe(source.lateralSurfaceMaterial); expect(target.directions).toBe(source.directions); expect(target.intersectionColor).toBe(source.intersectionColor); expect(target.radius).toBe(source.radius); @@ -36,7 +36,7 @@ defineSuite([ it('merge does not assign assigned properties', function() { var source = new PyramidGraphics(); - source.material = new ColorMaterialProperty(); + source.lateralSurfaceMaterial = new ColorMaterialProperty(); source.directions = new ConstantProperty([]); source.intersectionColor = new ConstantProperty(Color.WHITE); source.radius = new ConstantProperty(1); @@ -44,7 +44,7 @@ defineSuite([ source.showIntersection = new ConstantProperty(true); source.intersectionWidth = new ConstantProperty(1); - var material = new ColorMaterialProperty(); + var lateralSurfaceMaterial = new ColorMaterialProperty(); var directions = new ConstantProperty([]); var intersectionColor = new ConstantProperty(Color.WHITE); var radius = new ConstantProperty(1); @@ -53,7 +53,7 @@ defineSuite([ var intersectionWidth = new ConstantProperty(1); var target = new PyramidGraphics(); - target.material = material; + target.lateralSurfaceMaterial = lateralSurfaceMaterial; target.directions = directions; target.intersectionColor = intersectionColor; target.radius = radius; @@ -63,7 +63,7 @@ defineSuite([ target.merge(source); - expect(target.material).toBe(material); + expect(target.lateralSurfaceMaterial).toBe(lateralSurfaceMaterial); expect(target.directions).toBe(directions); expect(target.intersectionColor).toBe(intersectionColor); expect(target.radius).toBe(radius); @@ -74,7 +74,7 @@ defineSuite([ it('clone works', function() { var source = new PyramidGraphics(); - source.material = new ColorMaterialProperty(); + source.lateralSurfaceMaterial = new ColorMaterialProperty(); source.directions = new ConstantProperty([]); source.intersectionColor = new ConstantProperty(Color.WHITE); source.radius = new ConstantProperty(1); @@ -83,7 +83,7 @@ defineSuite([ source.intersectionWidth = new ConstantProperty(1); var result = source.clone(); - expect(result.material).toBe(source.material); + expect(result.lateralSurfaceMaterial).toBe(source.lateralSurfaceMaterial); expect(result.directions).toBe(source.directions); expect(result.intersectionColor).toBe(source.intersectionColor); expect(result.radius).toBe(source.radius); diff --git a/Specs/DataSources/PyramidVisualizerSpec.js b/Specs/DataSources/PyramidVisualizerSpec.js index 6adbd7fb0d54..b66adc14868a 100644 --- a/Specs/DataSources/PyramidVisualizerSpec.js +++ b/Specs/DataSources/PyramidVisualizerSpec.js @@ -123,7 +123,7 @@ defineSuite([ pyramid.showIntersection = new ConstantProperty(true); pyramid.radius = new ConstantProperty(123.5); pyramid.show = new ConstantProperty(true); - pyramid.material = new ColorMaterialProperty(); + pyramid.lateralSurfaceMaterial = ColorMaterialProperty.fromColor(Color.WHITE); visualizer.update(time); expect(scene.primitives.length).toEqual(1); @@ -132,16 +132,16 @@ defineSuite([ expect(p.intersectionWidth).toEqual(testObject.pyramid.intersectionWidth.getValue(time)); expect(p.showIntersection).toEqual(testObject.pyramid.showIntersection.getValue(time)); expect(p.radius).toEqual(testObject.pyramid.radius.getValue(time)); - expect(p.show).toEqual(testObject.pyramid.show.getValue(time)); - expect(p.material.uniforms).toEqual(testObject.pyramid.material.getValue(time)); expect(p.modelMatrix).toEqual(Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(testObject.orientation.getValue(time)), testObject.position.getValue(time))); + expect(p.show).toEqual(testObject.pyramid.show.getValue(time)); + expect(p.lateralSurfaceMaterial.uniforms).toEqual(testObject.pyramid.lateralSurfaceMaterial.getValue(time)); pyramid.show.value = false; visualizer.update(time); expect(p.show).toEqual(testObject.pyramid.show.getValue(time)); }); - it('clear hides pyramids.', function() { + it('clear removes pyramids.', function() { var entityCollection = new EntityCollection(); visualizer = new PyramidVisualizer(scene, entityCollection); @@ -158,8 +158,7 @@ defineSuite([ expect(scene.primitives.get(0).show).toEqual(true); entityCollection.removeAll(); visualizer.update(time); - expect(scene.primitives.length).toEqual(1); - expect(scene.primitives.get(0).show).toEqual(false); + expect(scene.primitives.length).toEqual(0); }); it('Visualizer sets entity property.', function() { From ebc45c175c675d802a99f68c87a0773f47ad1d12 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 17 Jul 2014 13:27:13 -0400 Subject: [PATCH 20/22] Undo unintentional variable rename. --- Source/DataSources/ConeVisualizer.js | 22 +++++++++++----------- Source/DataSources/PyramidVisualizer.js | 16 ++++++++-------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Source/DataSources/ConeVisualizer.js b/Source/DataSources/ConeVisualizer.js index ab74a8ea541a..823f810c0cbf 100644 --- a/Source/DataSources/ConeVisualizer.js +++ b/Source/DataSources/ConeVisualizer.js @@ -139,8 +139,8 @@ define([ var cachedPosition = new Cartesian3(); var cachedOrientation = new Quaternion(); function updateObject(visualizer, time, entity) { - var dynamicCone = entity._cone; - if (!defined(dynamicCone)) { + var coneGraphics = entity._cone; + if (!defined(coneGraphics)) { return; } @@ -155,7 +155,7 @@ define([ } var cone = entity._conePrimitive; - var showProperty = dynamicCone._show; + var showProperty = coneGraphics._show; var show = entity.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); if (!show) { @@ -176,7 +176,7 @@ define([ cone.show = true; var minimumClockAngle; - var property = dynamicCone._minimumClockAngle; + var property = coneGraphics._minimumClockAngle; if (defined(property)) { minimumClockAngle = property.getValue(time); } @@ -185,7 +185,7 @@ define([ } var maximumClockAngle; - property = dynamicCone._maximumClockAngle; + property = coneGraphics._maximumClockAngle; if (defined(property)) { maximumClockAngle = property.getValue(time); } @@ -194,7 +194,7 @@ define([ } var innerHalfAngle; - property = dynamicCone._innerHalfAngle; + property = coneGraphics._innerHalfAngle; if (defined(property)) { innerHalfAngle = property.getValue(time); } @@ -203,7 +203,7 @@ define([ } var outerHalfAngle; - property = dynamicCone._outerHalfAngle; + property = coneGraphics._outerHalfAngle; if (defined(property)) { outerHalfAngle = property.getValue(time); } @@ -223,7 +223,7 @@ define([ cone.minimumClockAngle = minimumClockAngle; } - property = dynamicCone._radius; + property = coneGraphics._radius; if (defined(property)) { var radius = property.getValue(time); if (defined(radius)) { @@ -243,14 +243,14 @@ define([ cone._visualizerOrientation = Quaternion.clone(orientation, cone._visualizerOrientation); } - cone.lateralSurfaceMaterial = MaterialProperty.getValue(time, dynamicCone._lateralSurfaceMaterial, cone.lateralSurfaceMaterial); + cone.lateralSurfaceMaterial = MaterialProperty.getValue(time, coneGraphics._lateralSurfaceMaterial, cone.lateralSurfaceMaterial); - property = dynamicCone._intersectionColor; + property = coneGraphics._intersectionColor; if (defined(property)) { property.getValue(time, cone.intersectionColor); } - property = dynamicCone._intersectionWidth; + property = coneGraphics._intersectionWidth; if (defined(property)) { var intersectionWidth = property.getValue(time); if (defined(intersectionWidth)) { diff --git a/Source/DataSources/PyramidVisualizer.js b/Source/DataSources/PyramidVisualizer.js index 95456d9ad343..67bdf2532d3b 100644 --- a/Source/DataSources/PyramidVisualizer.js +++ b/Source/DataSources/PyramidVisualizer.js @@ -97,12 +97,12 @@ define([ var position; var orientation; function updateObject(visualizer, time, entity) { - var dynamicPyramid = entity._pyramid; - if (!defined(dynamicPyramid)) { + var pyramidGraphics = entity._pyramid; + if (!defined(pyramidGraphics)) { return; } - var directionsProperty = dynamicPyramid._directions; + var directionsProperty = pyramidGraphics._directions; if (!defined(directionsProperty)) { return; } @@ -118,7 +118,7 @@ define([ } var pyramid = entity._pyramidPrimitive; - var showProperty = dynamicPyramid._show; + var showProperty = pyramidGraphics._show; var show = entity.isAvailable(time) && (!defined(showProperty) || showProperty.getValue(time)); if (!show) { @@ -144,7 +144,7 @@ define([ pyramid._visualizerDirections = directions; } - var property = dynamicPyramid._radius; + var property = pyramidGraphics._radius; if (defined(property)) { var radius = property.getValue(time); if (defined(radius)) { @@ -164,9 +164,9 @@ define([ pyramid._visualizerOrientation = Quaternion.clone(orientation, pyramid._visualizerOrientation); } - pyramid.lateralSurfaceMaterial = MaterialProperty.getValue(time, dynamicPyramid._lateralSurfaceMaterial, pyramid.lateralSurfaceMaterial); + pyramid.lateralSurfaceMaterial = MaterialProperty.getValue(time, pyramidGraphics._lateralSurfaceMaterial, pyramid.lateralSurfaceMaterial); - property = dynamicPyramid._intersectionColor; + property = pyramidGraphics._intersectionColor; if (defined(property)) { var intersectionColor = property.getValue(time, pyramid.intersectionColor); if (defined(intersectionColor)) { @@ -174,7 +174,7 @@ define([ } } - property = dynamicPyramid._intersectionWidth; + property = pyramidGraphics._intersectionWidth; if (defined(property)) { var intersectionWidth = property.getValue(time); if (defined(intersectionWidth)) { From 160d149e614c29aaa928404ace668e1be315ef9f Mon Sep 17 00:00:00 2001 From: Scott Hunter Date: Thu, 17 Jul 2014 14:06:00 -0400 Subject: [PATCH 21/22] Fix dependency on non-relative modules. --- .../NavigationHelpButton/NavigationHelpButtonViewModel.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Widgets/NavigationHelpButton/NavigationHelpButtonViewModel.js b/Source/Widgets/NavigationHelpButton/NavigationHelpButtonViewModel.js index a919a24154ea..00648e3cc9fa 100644 --- a/Source/Widgets/NavigationHelpButton/NavigationHelpButtonViewModel.js +++ b/Source/Widgets/NavigationHelpButton/NavigationHelpButtonViewModel.js @@ -1,8 +1,8 @@ /*global define*/ define([ - 'Core/defined', - 'Core/defineProperties', - 'ThirdParty/knockout', + '../../Core/defined', + '../../Core/defineProperties', + '../../ThirdParty/knockout', '../createCommand' ], function( defined, From be4a1404d50664de1050dfcd806af0a315201adb Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 17 Jul 2014 16:48:12 -0400 Subject: [PATCH 22/22] Fix doc. --- Source/Scene/CustomSensorVolume.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index ffcd7ef31de3..ded7a24f6dc0 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -167,10 +167,10 @@ define([ * * @example * // 1. Change the color of the default material to yellow - * sensor.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); + * sensor.lateralSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); * * // 2. Change material to horizontal stripes - * sensor.material = Cesium.Material.fromType(Material.StripeType); + * sensor.lateralSurfaceMaterial = Cesium.Material.fromType(Material.StripeType); */ this.lateralSurfaceMaterial = defined(options.lateralSurfaceMaterial) ? options.lateralSurfaceMaterial : Material.fromType(Material.ColorType); this._lateralSurfaceMaterial = undefined;