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;