From 817fe931c072bfe0f5e11e07142cec695ecfe1aa Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Tue, 8 Apr 2014 13:27:36 -0400 Subject: [PATCH 01/49] Capturing initial spherical polygon implementation. --- Apps/Sandcastle/gallery/Sensors.html | 34 ++- Source/Core/SphericalPolygon.js | 360 +++++++++++++++++++++++++++ Source/Scene/CustomSensorVolume.js | 10 + Source/Shaders/SensorVolume.glsl | 2 +- 4 files changed, 397 insertions(+), 9 deletions(-) create mode 100644 Source/Core/SphericalPolygon.js diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 35b9cf7bf002..05634c22e8d7 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -73,13 +73,13 @@ { "use strict"; - var longitude = Cesium.Math.toRadians(-90.0); - var latitude = Cesium.Math.toRadians(30.0); - var altitude = 3500000.0; + var longitude = Cesium.Math.toRadians(0.0); + var latitude = Cesium.Math.toRadians(0.0); + var altitude = 150000.0; var clock = 0.0; - var cone = Cesium.Math.toRadians(15.0); + var cone = Cesium.Math.toRadians(0.0); var twist = 0.0; - var selection = 'Rectangular'; + var selection = 'Custom'; var portion = Cesium.SensorVolumePortionToDisplay.COMPLETE; function getModelMatrix(ellipsoid) @@ -122,11 +122,18 @@ function addCustomSensor(ellipsoid) { var customSensor = new Cesium.CustomSensorVolume(); + var numberOfVertices = 180; + var azimuthDivision = 360.0 / numberOfVertices; + var directions = []; - for (var i = 0; i < 8; ++i) { + for (var i = 0; i < numberOfVertices; ++i) { + var clockAngle = (180.0 + azimuthDivision * i) % 360.0; // clockwise about z. (correct convention) +// var clockAngle = 360.0 - azimuthDivision * i; // counter clockwise about z. + var coneAngle = (clockAngle > 90 && clockAngle < 270.0) ? 30.0 : 60.0; + clockAngle = (clockAngle > 90 && clockAngle < 270.0) ? 180.0 - clockAngle : clockAngle; directions.push({ - clock : Cesium.Math.toRadians(45.0 * i), - cone : Cesium.Math.toRadians(25.0) + clock : Cesium.Math.toRadians(clockAngle), + cone : Cesium.Math.toRadians(coneAngle) }); } @@ -134,6 +141,15 @@ customSensor.radius = 20000000.0; customSensor.setDirections(directions); customSensor.portionToDisplay = portion; + + customSensor.material = Cesium.Material.fromType('Color'); + customSensor.material.uniforms.color = new Cesium.Color(0.0, 1.0, 1.0, 0.5); + + customSensor.ellipsoidHorizonSurfaceMaterial = Cesium.Material.fromType('Color'); + customSensor.ellipsoidHorizonSurfaceMaterial.uniforms.color = new Cesium.Color(0.4, 1.0, 0.0, 0.0); + + customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); + customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.0); return customSensor; } @@ -314,6 +330,8 @@ sceneModePicker : false //sensors currently only work in 3D }); + viewer.scene.camera.lookAt(new Cesium.Cartesian3(10000000.0, 0.0, 0.0), Cesium.Cartesian3.ZERO, Cesium.Cartesian3.UNIT_Z); + createUserInterface(viewer); Sandcastle.finishedLoading(); diff --git a/Source/Core/SphericalPolygon.js b/Source/Core/SphericalPolygon.js new file mode 100644 index 000000000000..b167ba76cc1c --- /dev/null +++ b/Source/Core/SphericalPolygon.js @@ -0,0 +1,360 @@ +/*global define*/ +define([ + './freezeObject', + './defaultValue', + './defined', + './defineProperties', + './DeveloperError', + './Math', + './Cartesian3' + ], function( + freezeObject, + defaultValue, + defined, + defineProperties, + DeveloperError, + CesiumMath, + Cartesian3) { + "use strict"; + + var SphericalPolygon = function(vertices) { + this._isConvex = undefined; + this._vertices = undefined; + this._directionsNormalsAndBisectorsWithMagnitudeSquared = undefined; + this._referenceDirection = new Cartesian3(); + this._referencePoint = new Cartesian3(); + + // cameraPosition fills in the above values + if (defined(vertices)) { + this.vertices = vertices; + } + }; + + var vertex = new Cartesian3(); + + function elliminateInteriorPoints(sphericalPolygon, n, d, index1, index2, index3, candidates, result) { + var minDotProduct = 1.0; + var indexOfMin = -1; + var length = candidates.length; + for (var i = 0; i < length; ++i) { + var index = candidates[i]; + if (index === index1 || index === index2 || index === index3) { + result.push(index); + } + var stride = 10; + vertex = Cartesian3.fromArray(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, index * stride, vertex); + var dotProduct = Cartesian3.dot(vertex, n); + if (dotProduct < d) { + result.push(index); + if (dotProduct < minDotProduct) { + minDotProduct = dotProduct; + indexOfMin = index; + } + } + } + return indexOfMin; + } + + var crossProduct = new Cartesian3(); + var sum = new Cartesian3(); + var average = new Cartesian3(); + var chord12 = new Cartesian3(); + var chord23 = new Cartesian3(); + + function computeReference(p1, p2, p3, direction) { + chord12 = Cartesian3.subtract(p2, p1, chord12); + chord23 = Cartesian3.subtract(p3, p2, chord23); + crossProduct = Cartesian3.cross(chord12, chord23, crossProduct); + sum = Cartesian3.add(Cartesian3.add(p1, p2, sum), p3, sum); + average = Cartesian3.divideByScalar(sum, 3.0, average); + + direction = Cartesian3.normalize(crossProduct, direction); + var magnitude = Cartesian3.dot(average, direction); + return magnitude; + } + + var axis1 = new Cartesian3(); + var axis2 = new Cartesian3(); + var firstDirection = new Cartesian3(); + var secondDirection = new Cartesian3(); + var thirdDirection = new Cartesian3(); + var tempDirection = new Cartesian3(); + + SphericalPolygon.computeBoundingCone = function(sphericalPolygon, axis) { + var numberOfVertices = sphericalPolygon.vertices.length; + var offset = numberOfVertices / 3; + + var firstIndex = 0; + var secondIndex = offset; + var thirdIndex = offset + offset; + + var result = []; + for (var i = 0; i < numberOfVertices; ++i) { + result.push(i); + } + + var stride = 10; + firstDirection = Cartesian3.fromArray(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, firstIndex * stride, firstDirection); + secondDirection = Cartesian3.fromArray(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, secondIndex * stride, secondDirection); + thirdDirection = Cartesian3.fromArray(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, thirdIndex * stride, thirdDirection); + + var distance = computeReference(firstDirection, secondDirection, thirdDirection, axis); + + var candidates = []; + var notDone = true; + do { + candidates.length = 0; + var l = result.length; + for (var j = 0; j < l; ++j) { + candidates.push(result[j]); + } + result.length = 0; + + var indexOfMin = elliminateInteriorPoints(sphericalPolygon, axis, distance, firstIndex, secondIndex, thirdIndex, candidates, result); + tempDirection = Cartesian3.fromArray(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, indexOfMin * stride, tempDirection); + + if (result.length > 3) { + var distance1 = 1.0; + var distance2 = 1.0; + if (indexOfMin > thirdIndex) { + distance1 = computeReference(secondDirection, thirdDirection, tempDirection, axis1); + distance2 = computeReference(firstDirection, secondDirection, tempDirection, axis2); + if (distance2 < distance1) { + thirdIndex = indexOfMin; + distance = distance2; + axis = Cartesian3.clone(axis2, axis); + } else { + firstIndex = secondIndex; + secondIndex = thirdIndex; + thirdIndex = indexOfMin; + distance = distance1; + axis = Cartesian3.clone(axis1, axis); + } + } else if (indexOfMin > secondIndex) { + distance1 = computeReference(firstDirection, secondDirection, tempDirection, axis1); + distance2 = computeReference(firstDirection, tempDirection, thirdDirection, axis2); + if (distance2 < distance1) { + secondIndex = indexOfMin; + distance = distance2; + axis = Cartesian3.clone(axis2, axis); + } else { + thirdIndex = indexOfMin; + distance = distance1; + axis = Cartesian3.clone(axis1, axis); + } + } else if (indexOfMin > firstIndex) { + distance1 = computeReference(tempDirection, secondDirection, thirdDirection, axis1); + distance2 = computeReference(firstDirection, tempDirection, thirdDirection, axis2); + if (distance2 < distance1) { + secondIndex = indexOfMin; + distance = distance2; + axis = Cartesian3.clone(axis2, axis); + } else { + firstIndex = indexOfMin; + distance = distance1; + axis = Cartesian3.clone(axis1, axis); + } + } else { + distance1 = computeReference(tempDirection, secondDirection, thirdDirection, axis1); + distance2 = computeReference(tempDirection, firstDirection, secondDirection, axis2); + if (distance2 < distance1) { + thirdIndex = secondIndex; + secondIndex = firstIndex; + firstIndex = indexOfMin; + distance = distance2; + axis = Cartesian3.clone(axis2, axis); + } else { + firstIndex = indexOfMin; + distance = distance1; + axis = Cartesian3.clone(axis1, axis); + } + } + } else { + notDone = false; + } + } while (notDone); + + return distance; + }; + + var direction = new Cartesian3(); + var bisector = new Cartesian3(); + var normal = new Cartesian3(); + var lastDirection = new Cartesian3(); + var lastNormal = new Cartesian3(); + var initialNormal = new Cartesian3(); + var finalDirection = new Cartesian3(); + var nextDirection = new Cartesian3(); + var nextNormal = new Cartesian3(); + + SphericalPolygon.findConvexArcs = function(floats, stride, directionsOffset, normalsOffset, arcs) { + var isConvexArc = false; + var length = floats.length / stride; + var arc; + for (var index = 0; index < length; ++index) { + var offset = index * stride + directionsOffset; + direction = Cartesian3.fromArray(floats, offset, direction); + offset = index * stride + normalsOffset; + normal = Cartesian3.fromArray(floats, offset, normal); + offset = ((index + 1 === length) ? 0 : index + 1) * stride + normalsOffset; + nextNormal = Cartesian3.fromArray(floats, offset, nextNormal); + + if (Cartesian3.dot(Cartesian3.cross(normal, nextNormal, crossProduct), direction) >= 0.0) { + if (isConvexArc === false) { + arc = []; + arcs.push(arc); + isConvexArc = true; + } + arc.push(index); + } else { + isConvexArc = false; + } + } + if (arcs.length > 1) { + var first = arcs[0]; + var last = arcs[arcs.length - 1]; + if (first[0] === 0 && last[last.length - 1] === (length - 1)) { + arcs[0] = last.concat(first); + arcs.length = arcs.length - 1; + } + } + }; + + SphericalPolygon.findConvexHull = function(floats, stride, directionsOffset, sign, initialIndex, finalIndex, hull) { + var numberOfVertices = floats.length / stride; + + if (initialIndex < finalIndex) { + for (var i = initialIndex; i <= finalIndex; ++i) { + hull.push(i); + } + } else { + for (var j = initialIndex; j < numberOfVertices; ++j) { + hull.push(j); + } + for (var jj = 0; jj <= finalIndex; ++jj) { + hull.push(jj); + } + } + + var originalLength = hull.length; + + var initialLength; + do { + initialLength = hull.length; + var previousIndex = initialLength - 1; + var index = 0; + var nextIndex = 1; + do { + var offset = hull[previousIndex % hull.length] * stride + directionsOffset; + lastDirection = Cartesian3.fromArray(floats, offset, lastDirection); + offset = hull[index % hull.length] * stride + directionsOffset; + direction = Cartesian3.fromArray(floats, offset, direction); + offset = hull[nextIndex % hull.length] * stride + directionsOffset; + nextDirection = Cartesian3.fromArray(floats, offset, nextDirection); + + lastNormal = Cartesian3.cross(direction, lastDirection, lastNormal); + nextNormal = Cartesian3.cross(nextDirection, direction, nextNormal); + + if (sign * Cartesian3.dot(Cartesian3.cross(lastNormal, nextNormal, crossProduct), direction) >= 0.0) { + previousIndex = index; + index = index + 1; + nextIndex = index + 1; + } else { + hull.splice(index, 1); + } + } while (index !== hull.length); + } while (hull.length !== initialLength); + + var hole; + if (hull.length !== originalLength) { + hull.holes = []; + for (var k = 0; k < hull.length - 1; ++k) { + var current = hull[k]; + var next = hull[k + 1]; + if (next - current > 1) { + hole = []; + SphericalPolygon.findConvexHull(floats, stride, directionsOffset, sign * -1.0, current, next, hole); + hull.holes.push(hole); + } + } + + var firstIndex = hull[0]; + var lastIndex = hull[hull.length - 1]; + if (lastIndex === finalIndex && firstIndex !== initialIndex) { + hole = []; + SphericalPolygon.findConvexHull(floats, stride, directionsOffset, sign * -1.0, initialIndex, firstIndex, hole); + hull.holes.push(hole); + } else if (lastIndex !== finalIndex && firstIndex === initialIndex) { + hole = []; + SphericalPolygon.findConvexHull(floats, stride, directionsOffset, sign * -1.0, lastIndex, finalIndex, hole); + hull.holes.push(hole); + } else if (lastIndex !== finalIndex && firstIndex !== initialIndex) { + hole = []; + SphericalPolygon.findConvexHull(floats, stride, directionsOffset, sign * -1.0, lastIndex, firstIndex, hole); + hull.holes.push(hole); + } + } + }; + + defineProperties(SphericalPolygon.prototype, { + isConvex : { + get: function() { + return this._isConvex; + } + }, + + vertices : { + get: function() { + return this._vertices; + }, + set : function(vertices) { + var length = vertices.length; + var size = length * 3; + + this._directionsNormalsAndBisectorsWithMagnitudeSquared = new Float32Array(3 * size + length); + + // TODO: Enforce that angle between vertices cannot be zero or exceed 180 degrees. + + var convexVertices = []; + + this._isConvex = true; + finalDirection = Cartesian3.fromSpherical(vertices[length - 1], finalDirection); + lastDirection = Cartesian3.clone(finalDirection, lastDirection); + + for (var index = 0; index < length; ++index) { + direction = Cartesian3.fromSpherical(vertices[index], direction); + bisector = Cartesian3.divideByScalar(Cartesian3.add(lastDirection, direction, bisector), 2.0, bisector); + normal = Cartesian3.normalize(Cartesian3.cross(direction, lastDirection, normal), normal); + + if (index === 0) { + initialNormal = Cartesian3.clone(normal, initialNormal); + } else if (Cartesian3.dot(Cartesian3.cross(lastNormal, normal, crossProduct), lastDirection) < 0.0) { + this._isConvex = false; + } + + var offset = index * 10; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset] = direction.x; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 1] = direction.y; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 2] = direction.z; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 3] = normal.x; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 4] = normal.y; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 5] = normal.z; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 6] = bisector.x; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 7] = bisector.y; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 8] = bisector.z; + this._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 9] = Cartesian3.magnitudeSquared(bisector); + + lastDirection = Cartesian3.clone(direction, lastDirection); + lastNormal = Cartesian3.clone(normal, lastNormal); + } + if (Cartesian3.dot(Cartesian3.cross(lastNormal, initialNormal, crossProduct), finalDirection) < 0.0) { + this._isConvex = false; + } + + this._vertices = vertices; + } + } + }); + + return SphericalPolygon; +}); diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 30f85da002c2..13bdb6d5da0b 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -16,6 +16,7 @@ define([ '../Core/ComponentDatatype', '../Core/PrimitiveType', '../Core/BoundingSphere', + '../Core/SphericalPolygon', '../Renderer/BufferUsage', '../Renderer/BlendingState', '../Renderer/DrawCommand', @@ -54,6 +55,7 @@ define([ ComponentDatatype, PrimitiveType, BoundingSphere, + SphericalPolygon, BufferUsage, BlendingState, DrawCommand, @@ -463,6 +465,14 @@ define([ } function updateDefinitionDependentData(customSensorVolume, context) { + var sphericalPolygon = new SphericalPolygon(customSensorVolume._sphericals); + var arcs = []; + SphericalPolygon.findConvexArcs(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 3, arcs); + + var hull = []; + var holes = []; + SphericalPolygon.findConvexHull(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 1.0, 0, customSensorVolume._sphericals.length - 1, hull); + var sphericals = customSensorVolume._sphericals; var length = sphericals.length; var size = length * 3; diff --git a/Source/Shaders/SensorVolume.glsl b/Source/Shaders/SensorVolume.glsl index 0fd07ad2245f..c319899fc4bd 100644 --- a/Source/Shaders/SensorVolume.glsl +++ b/Source/Shaders/SensorVolume.glsl @@ -17,7 +17,7 @@ float getIntersectionWidth() vec2 sensorCartesianToNormalizedPolarTextureCoordinates(float radius, vec3 point) { - // Maps (-180 to 180, -radius to +radius) coordinates both to the range [0.0, 1.0]. + // Maps (-180 to 180, 0 to +radius) coordinates both to the range [0.0, 1.0]. return vec2(atan(point.y, point.x) * czm_oneOverTwoPi + 0.5, length(point) / radius); } From fc75441fc545c5742b7b56894393996e970d37ee Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Thu, 10 Apr 2014 13:45:39 -0400 Subject: [PATCH 02/49] Incremental changes. --- Apps/Sandcastle/gallery/Sensors.html | 2 +- Source/Core/SphericalPolygon.js | 182 +++++++++++++++++++++------ Source/Scene/CustomSensorVolume.js | 10 +- 3 files changed, 151 insertions(+), 43 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 05634c22e8d7..861f5a5c2a65 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -127,7 +127,7 @@ var directions = []; for (var i = 0; i < numberOfVertices; ++i) { - var clockAngle = (180.0 + azimuthDivision * i) % 360.0; // clockwise about z. (correct convention) + var clockAngle = azimuthDivision * i; // clockwise about z. (correct convention) // var clockAngle = 360.0 - azimuthDivision * i; // counter clockwise about z. var coneAngle = (clockAngle > 90 && clockAngle < 270.0) ? 30.0 : 60.0; clockAngle = (clockAngle > 90 && clockAngle < 270.0) ? 180.0 - clockAngle : clockAngle; diff --git a/Source/Core/SphericalPolygon.js b/Source/Core/SphericalPolygon.js index b167ba76cc1c..3fc506b1a3ba 100644 --- a/Source/Core/SphericalPolygon.js +++ b/Source/Core/SphericalPolygon.js @@ -178,48 +178,11 @@ define([ }; var direction = new Cartesian3(); - var bisector = new Cartesian3(); - var normal = new Cartesian3(); var lastDirection = new Cartesian3(); var lastNormal = new Cartesian3(); - var initialNormal = new Cartesian3(); - var finalDirection = new Cartesian3(); var nextDirection = new Cartesian3(); var nextNormal = new Cartesian3(); - SphericalPolygon.findConvexArcs = function(floats, stride, directionsOffset, normalsOffset, arcs) { - var isConvexArc = false; - var length = floats.length / stride; - var arc; - for (var index = 0; index < length; ++index) { - var offset = index * stride + directionsOffset; - direction = Cartesian3.fromArray(floats, offset, direction); - offset = index * stride + normalsOffset; - normal = Cartesian3.fromArray(floats, offset, normal); - offset = ((index + 1 === length) ? 0 : index + 1) * stride + normalsOffset; - nextNormal = Cartesian3.fromArray(floats, offset, nextNormal); - - if (Cartesian3.dot(Cartesian3.cross(normal, nextNormal, crossProduct), direction) >= 0.0) { - if (isConvexArc === false) { - arc = []; - arcs.push(arc); - isConvexArc = true; - } - arc.push(index); - } else { - isConvexArc = false; - } - } - if (arcs.length > 1) { - var first = arcs[0]; - var last = arcs[arcs.length - 1]; - if (first[0] === 0 && last[last.length - 1] === (length - 1)) { - arcs[0] = last.concat(first); - arcs.length = arcs.length - 1; - } - } - }; - SphericalPolygon.findConvexHull = function(floats, stride, directionsOffset, sign, initialIndex, finalIndex, hull) { var numberOfVertices = floats.length / stride; @@ -296,6 +259,151 @@ define([ } }; + function kDopFacetNormalName(i, j) { + return 'u_kDopFacetNormal_' + i + '_' + j; + } + + function convexHullImplicitSurfaceFunction(vertices, name, sign) { + var length = vertices.length; + var glsl = ''; + var result = ''; + var oppositeSign = (sign === '+') ? '-' : '+'; + for (var i = 0; i < length; ++i) { + var j = (i + 1 === length) ? 0 : i + 1; + var initialIndex = vertices[i]; + var finalIndex = vertices[j]; + var uniform = (initialIndex < finalIndex) ? sign + kDopFacetNormalName(initialIndex, finalIndex) : oppositeSign + kDopFacetNormalName(finalIndex, initialIndex); + if (i === 0) { + result += '\tfloat value = dot(displacement, ' + uniform + ');\n'; + } else { + result += '\tvalue = max(value, dot(displacement, ' + uniform + '));\n'; + } + } + glsl += '\nfloat ' + name + '(vec3 displacement)\n{\n' + result + '\treturn value;\n}\n'; + return glsl; + } + + function sphericalPolygonImplicitSurfaceFunction(hull, name, sign) { + var result = ''; + if (defined(hull.holes)) { + var oppositeSign = (sign === '+') ? '-' : '+'; + for (var h = 0; h < hull.holes.length; ++h) { + var functionName = name + '_' + h; + result += sphericalPolygonImplicitSurfaceFunction(hull.holes[h], functionName, oppositeSign); + } + } + result += convexHullImplicitSurfaceFunction(hull, name, sign); + return result; + } + + function sphericalPolygonImplicitSurfaceFunctionUniforms(hull) { + var result = ''; + if (defined(hull.holes)) { + for (var h = 0; h < hull.holes.length; ++h) { + result += sphericalPolygonImplicitSurfaceFunctionUniforms(hull.holes[h]); + } + } + var length = hull.length; + for (var i = 0; i < length; ++i) { + var j = (i + 1 === length) ? 0 : i + 1; + var initialIndex = hull[i]; + var finalIndex = hull[j]; + if (initialIndex < finalIndex) { + var uniform1 = kDopFacetNormalName(initialIndex, finalIndex); + result += 'uniform vec3 ' + uniform1 + ';\n'; + } else if (finalIndex === 0) { + var uniform2 = kDopFacetNormalName(finalIndex, initialIndex); + result += 'uniform vec3 ' + uniform2 + ';\n'; + } + } + return result; + } + + function aggregateFunction(hull, functionName, variableName) { + var result = '\tfloat ' + variableName + ' = ' + functionName + '(displacement);\n'; + if (defined(hull.holes)) { + for (var i = 0; i < hull.holes.length; ++i) { + var name = functionName + '_' + i; + result += '\t' + variableName + ' = max(' + variableName + ', -' + name + '(displacement));\n'; + var hole = hull.holes[i]; + if (defined(hole.holes)) { + var variable = variableName + '_' + i; + for (var j = 0; j < hole.holes.length; ++j) { + var v = variable + '_' + j; + result += aggregateFunction(hole.holes[j], name + '_' + j, v); + result += '\t' + variableName + ' = min(' + variableName + ', ' + v + ');\n'; + } + } + } + } + return result; + } + + function returnNormal(normal) { + return function() { + return normal; + }; + } + + var normal = new Cartesian3(); + var normals = []; + + function addUniforms(floats, stride, directionsOffset, hull, uniforms) { + if (defined(hull.holes)) { + for (var h = 0; h < hull.holes.length; ++h) { + addUniforms(floats, stride, directionsOffset, hull.holes[h], uniforms); + } + } + var length = hull.length; + for (var i = 0; i < length; ++i) { + var j = (i + 1 === length) ? 0 : i + 1; + var initialIndex = hull[i]; + var finalIndex = hull[j]; + + var offset = initialIndex * stride + directionsOffset; + lastDirection = Cartesian3.fromArray(floats, offset, lastDirection); + offset = finalIndex * stride + directionsOffset; + direction = Cartesian3.fromArray(floats, offset, direction); + + if (initialIndex < finalIndex) { + normal = Cartesian3.cross(direction, lastDirection, normal); + normals.push(Cartesian3.clone(normal)); + var uniform1 = kDopFacetNormalName(initialIndex, finalIndex); + uniforms[uniform1] = returnNormal(normals[i]); + } else if (finalIndex === 0) { + normal = Cartesian3.cross(lastDirection, direction, normal); + normals.push(Cartesian3.clone(normal)); + var uniform2 = kDopFacetNormalName(finalIndex, initialIndex); + uniforms[uniform2] = returnNormal(normals[i]); + } + } + } + + SphericalPolygon.uniforms = function(floats, stride, directionsOffset, hull) { + var length = normals.length; + var uniforms = { }; + addUniforms(floats, stride, directionsOffset, hull, uniforms); + return uniforms; + }; + + SphericalPolygon.implicitSurfaceFunction = function(hull, name, sign) { + var glsl = '\n'; + // Emit uniforms. + glsl += sphericalPolygonImplicitSurfaceFunctionUniforms(hull); + // Emit convex hull funtions. + var functionName = 'convexHull'; + var variableName = 'value'; + glsl += sphericalPolygonImplicitSurfaceFunction(hull, functionName, sign); + // Emit implicit surface function. + var result = aggregateFunction(hull, functionName, variableName); + glsl += '\nfloat ' + name + '(vec3 displacement)\n{\n' + result + '\treturn ' + variableName + ';\n}\n'; + return glsl; + }; + + var bisector = new Cartesian3(); + var initialNormal = new Cartesian3(); + var finalDirection = new Cartesian3(); + defineProperties(SphericalPolygon.prototype, { isConvex : { get: function() { diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 13bdb6d5da0b..4e69e80f151e 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -411,6 +411,8 @@ define([ this._cameraIsInsideEllipsoidHorizonCone = undefined; this._cameraIsInsideDome = undefined; + this._hull = []; + // These elements are for the scaled ellipsoid horizon cone. this._p = undefined; this._q = undefined; @@ -466,12 +468,10 @@ define([ function updateDefinitionDependentData(customSensorVolume, context) { var sphericalPolygon = new SphericalPolygon(customSensorVolume._sphericals); - var arcs = []; - SphericalPolygon.findConvexArcs(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 3, arcs); + SphericalPolygon.findConvexHull(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 1.0, 0, customSensorVolume._sphericals.length - 1, customSensorVolume._hull); - var hull = []; - var holes = []; - SphericalPolygon.findConvexHull(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 1.0, 0, customSensorVolume._sphericals.length - 1, hull); + var glsl = SphericalPolygon.implicitSurfaceFunction(customSensorVolume._hull, 'sensorSurfaceFunction', '+'); + var uniforms = SphericalPolygon.uniforms(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, customSensorVolume._hull); var sphericals = customSensorVolume._sphericals; var length = sphericals.length; From 4dcb284faa78502d25a76876b27781c72c83fccb Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Thu, 10 Apr 2014 14:32:31 -0400 Subject: [PATCH 03/49] Incremental changes. --- Source/Core/SphericalPolygon.js | 17 +++++++---------- Source/Scene/CustomSensorVolume.js | 7 +++++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Source/Core/SphericalPolygon.js b/Source/Core/SphericalPolygon.js index 3fc506b1a3ba..0e05f9836ce0 100644 --- a/Source/Core/SphericalPolygon.js +++ b/Source/Core/SphericalPolygon.js @@ -345,9 +345,6 @@ define([ }; } - var normal = new Cartesian3(); - var normals = []; - function addUniforms(floats, stride, directionsOffset, hull, uniforms) { if (defined(hull.holes)) { for (var h = 0; h < hull.holes.length; ++h) { @@ -366,21 +363,20 @@ define([ direction = Cartesian3.fromArray(floats, offset, direction); if (initialIndex < finalIndex) { - normal = Cartesian3.cross(direction, lastDirection, normal); - normals.push(Cartesian3.clone(normal)); + var normal1 = new Cartesian3(); + normal1 = Cartesian3.cross(direction, lastDirection, normal1); var uniform1 = kDopFacetNormalName(initialIndex, finalIndex); - uniforms[uniform1] = returnNormal(normals[i]); + uniforms[uniform1] = returnNormal(normal1); } else if (finalIndex === 0) { - normal = Cartesian3.cross(lastDirection, direction, normal); - normals.push(Cartesian3.clone(normal)); + var normal2 = new Cartesian3(); + normal2 = Cartesian3.cross(lastDirection, direction, normal2); var uniform2 = kDopFacetNormalName(finalIndex, initialIndex); - uniforms[uniform2] = returnNormal(normals[i]); + uniforms[uniform2] = returnNormal(normal2); } } } SphericalPolygon.uniforms = function(floats, stride, directionsOffset, hull) { - var length = normals.length; var uniforms = { }; addUniforms(floats, stride, directionsOffset, hull, uniforms); return uniforms; @@ -401,6 +397,7 @@ define([ }; var bisector = new Cartesian3(); + var normal = new Cartesian3(); var initialNormal = new Cartesian3(); var finalDirection = new Cartesian3(); diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 4e69e80f151e..596e22bc553d 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -373,6 +373,9 @@ define([ */ this.debugShowProxyGeometry = defaultValue(options.debugShowProxyGeometry, false); + this._sensorGlsl = undefined; + this._sensorUniforms = undefined; + var that = this; this._uniforms = { u_radii : function() { @@ -470,8 +473,8 @@ define([ var sphericalPolygon = new SphericalPolygon(customSensorVolume._sphericals); SphericalPolygon.findConvexHull(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 1.0, 0, customSensorVolume._sphericals.length - 1, customSensorVolume._hull); - var glsl = SphericalPolygon.implicitSurfaceFunction(customSensorVolume._hull, 'sensorSurfaceFunction', '+'); - var uniforms = SphericalPolygon.uniforms(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, customSensorVolume._hull); + customSensorVolume._sensorGlsl = SphericalPolygon.implicitSurfaceFunction(customSensorVolume._hull, 'sensorSurfaceFunction', '+'); + customSensorVolume._sensorUniforms = SphericalPolygon.uniforms(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, customSensorVolume._hull); var sphericals = customSensorVolume._sphericals; var length = sphericals.length; From f1edfca24d92143e36bee82510a803381ef1b8ff Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Fri, 11 Apr 2014 13:24:25 -0400 Subject: [PATCH 04/49] Incremental changes. --- Apps/Sandcastle/gallery/Sensors.html | 11 ++--- Source/Scene/CustomSensorVolume.js | 62 +++++++++++++++++----------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 861f5a5c2a65..ec47e094e0d2 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -74,8 +74,8 @@ "use strict"; var longitude = Cesium.Math.toRadians(0.0); - var latitude = Cesium.Math.toRadians(0.0); - var altitude = 150000.0; + var latitude = Cesium.Math.toRadians(90.0); + var altitude = 15000000.0; var clock = 0.0; var cone = Cesium.Math.toRadians(0.0); var twist = 0.0; @@ -97,7 +97,7 @@ var rectangularPyramidSensor = new Cesium.RectangularPyramidSensorVolume(); rectangularPyramidSensor.modelMatrix = getModelMatrix(ellipsoid); - rectangularPyramidSensor.radius = 20000000.0; + rectangularPyramidSensor.radius = 10000000.0; rectangularPyramidSensor.xHalfAngle = Cesium.Math.toRadians(45.0); rectangularPyramidSensor.yHalfAngle = Cesium.Math.toRadians(60.0); rectangularPyramidSensor.portionToDisplay = portion; @@ -138,7 +138,7 @@ } customSensor.modelMatrix = getModelMatrix(ellipsoid); - customSensor.radius = 20000000.0; + customSensor.radius = 10000000.0; customSensor.setDirections(directions); customSensor.portionToDisplay = portion; @@ -149,7 +149,8 @@ customSensor.ellipsoidHorizonSurfaceMaterial.uniforms.color = new Cesium.Color(0.4, 1.0, 0.0, 0.0); customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); - customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.0); + customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5); + customSensor.debugShowProxyGeometry = true; return customSensor; } diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 596e22bc553d..b07f75b92a23 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -373,9 +373,6 @@ define([ */ this.debugShowProxyGeometry = defaultValue(options.debugShowProxyGeometry, false); - this._sensorGlsl = undefined; - this._sensorUniforms = undefined; - var that = this; this._uniforms = { u_radii : function() { @@ -414,7 +411,11 @@ define([ this._cameraIsInsideEllipsoidHorizonCone = undefined; this._cameraIsInsideDome = undefined; + this._sphericalPolygon = undefined; this._hull = []; + this._sensorGlsl = undefined; + this._sensorUniforms = undefined; + // These elements are for the scaled ellipsoid horizon cone. this._p = undefined; @@ -470,11 +471,11 @@ define([ } function updateDefinitionDependentData(customSensorVolume, context) { - var sphericalPolygon = new SphericalPolygon(customSensorVolume._sphericals); - SphericalPolygon.findConvexHull(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 1.0, 0, customSensorVolume._sphericals.length - 1, customSensorVolume._hull); + customSensorVolume._sphericalPolygon = new SphericalPolygon(customSensorVolume._sphericals); + SphericalPolygon.findConvexHull(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 1.0, 0, customSensorVolume._sphericals.length - 1, customSensorVolume._hull); customSensorVolume._sensorGlsl = SphericalPolygon.implicitSurfaceFunction(customSensorVolume._hull, 'sensorSurfaceFunction', '+'); - customSensorVolume._sensorUniforms = SphericalPolygon.uniforms(sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, customSensorVolume._hull); + customSensorVolume._sensorUniforms = SphericalPolygon.uniforms(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, customSensorVolume._hull); var sphericals = customSensorVolume._sphericals; var length = sphericals.length; @@ -1102,18 +1103,23 @@ define([ customSensorVolume._ellipsoidHorizonSurfaceCommandsBuffer.copyFromArrayView(vertices, Float32Array.BYTES_PER_ELEMENT * (numberOfFloatsForCompleteHorizonPyramidalFrustumCommand + numberOfFloatsPerHorizonCommand * index)); } - function computeBoundingPyramidalFrustumVertices(directions, frontCenter, frontSides, backCenter, backSides, vertices) { + var previous = new Cartesian3(); + var current = new Cartesian3(); + var next = new Cartesian3(); + + function computeBoundingPyramidalFrustumVertices(customSensorVolume, directions, frontCenter, frontSides, backCenter, backSides, vertices) { + var stride = 10; var length = directions.length; var normals = []; var k = -1; - var last = directions[length - 1]; + previous = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[length - 1] * stride, previous); var lastFront = frontSides[length - 1]; var lastBack = backSides[length - 1]; for (var index = 0; index < length; ++index) { - var direction = directions[index]; + current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[index] * stride, current); var front = frontSides[index]; var back = backSides[index]; - n = Cartesian3.normalize(Cartesian3.cross(direction, last, n), n); + n = Cartesian3.normalize(Cartesian3.cross(current, previous, n), n); normals.push(Cartesian3.clone(n)); Cartesian3.pack(front, vertices, ++k * 3); Cartesian3.pack(n, vertices, ++k * 3); @@ -1143,7 +1149,7 @@ define([ Cartesian3.pack(lastBack, vertices, ++k * 3); Cartesian3.pack(n, vertices, ++k * 3); - last = direction; + previous = Cartesian3.clone(current, previous); lastFront = front; lastBack = back; } @@ -1188,53 +1194,58 @@ define([ var centerBack = new Cartesian3(); function computeDomeVertices(customSensorVolume, directions, radius, vertices) { + var stride = 10; var length = directions.length; d = Cartesian3.clone(Cartesian3.ZERO, d); for (var ii = 0; ii < length; ++ii) { - d = Cartesian3.add(d, directions[ii], d); + current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); + d = Cartesian3.add(d, current, d); } d = Cartesian3.magnitudeSquared(d) > CesiumMath.EPSILON15 ? Cartesian3.normalize(d, d) : Cartesian3.clone(Cartesian3.UNIT_Z, d); var minDot = 1.0; for (var iii = 0; iii < length; ++iii) { - minDot = Math.min(Cartesian3.dot(directions[iii], d), minDot); + current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); + minDot = Math.min(Cartesian3.dot(current, d), minDot); } var fronts = []; var backs = []; for ( var i = length - 2, j = length - 1, k = 0; k < length; i = j++, j = k++) { // PERFORMANCE_IDEA: We can avoid redundant operations for adjacent edges. - var previous = directions[i]; - var temp = directions[j]; - var next = directions[k]; + previous = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); + current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); + next = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); // Extend position so the volume encompasses the sensor's radius. Use the shorter bisector in the scaling. - var factor = 2.0 / Math.min(Cartesian3.magnitude(Cartesian3.add(previous, temp)), Cartesian3.magnitude(Cartesian3.add(temp, next))); - var dot = Cartesian3.dot(temp, d); - fronts.push(Cartesian3.add(Cartesian3.multiplyByScalar(temp, radius * factor), Cartesian3.multiplyByScalar(d, radius * (minDot - factor * dot)))); - backs.push(Cartesian3.add(Cartesian3.multiplyByScalar(temp, radius * factor), Cartesian3.multiplyByScalar(d, radius * (1.0 - factor * dot)))); + var factor = 2.0 / Math.min(Cartesian3.magnitude(Cartesian3.add(previous, current)), Cartesian3.magnitude(Cartesian3.add(current, next))); + var dot = Cartesian3.dot(current, d); + fronts.push(Cartesian3.add(Cartesian3.multiplyByScalar(current, radius * factor), Cartesian3.multiplyByScalar(d, radius * (minDot - factor * dot)))); + backs.push(Cartesian3.add(Cartesian3.multiplyByScalar(current, radius * factor), Cartesian3.multiplyByScalar(d, radius * (1.0 - factor * dot)))); } centerFront = Cartesian3.multiplyByScalar(d, radius * minDot, centerFront); centerBack = Cartesian3.multiplyByScalar(d, radius, centerBack); - return computeBoundingPyramidalFrustumVertices(directions, centerFront, fronts, centerBack, backs, vertices); + return computeBoundingPyramidalFrustumVertices(customSensorVolume, directions, centerFront, fronts, centerBack, backs, vertices); } function updateDomeCommand(command, index, customSensorVolume, context, directions, radius) { - var numberOfVertices = directions.length * 4 * 3; // (sides)(4 triangles/side)(3 vertices/triangle) + var numberOfVertices = customSensorVolume._hull.length * 4 * 3; // (sides)(4 triangles/side)(3 vertices/triangle) var numberOfFloats = numberOfVertices * numberOfFloatsPerVertex; var domeFloatOffset = customSensorVolume._domeVertexCount * numberOfFloatsPerVertex; var vertices = new Float32Array(customSensorVolume._domeCommandsVertices.buffer, Float32Array.BYTES_PER_ELEMENT * domeFloatOffset, numberOfFloats); - var normals = computeDomeVertices(customSensorVolume, directions, radius, vertices); - var uniforms = kDopUniforms(normals); + var normals = computeDomeVertices(customSensorVolume, customSensorVolume._hull, radius, vertices); +// var uniforms = kDopUniforms(normals); + var uniforms = customSensorVolume._sensorUniforms; command.offset = customSensorVolume._domeVertexCount; var boundingVolume = BoundingSphere.fromVertices(vertices, undefined, numberOfFloatsPerVertex, command.boundingVolume); command.uniformMap = combine(combine(customSensorVolume._uniforms, customSensorVolume._domeSurfaceMaterial._uniforms), uniforms); command.boundingVolume = BoundingSphere.transform(boundingVolume, customSensorVolume.modelMatrix, command.boundingVolume); command.modelMatrix = customSensorVolume.modelMatrix; +// command.debugShowBoundingVolume = true; customSensorVolume._domeVertexCount += numberOfVertices; customSensorVolume._domeCommandsBuffer.copyFromArrayView(vertices, Float32Array.BYTES_PER_ELEMENT * domeFloatOffset); @@ -1242,7 +1253,8 @@ define([ if (command.count !== numberOfVertices) { command.count = numberOfVertices; - var glsl = kDopImplicitSurfaceFunction(normals.length); +// var glsl = kDopImplicitSurfaceFunction(normals.length); + var glsl = customSensorVolume._sensorGlsl; customSensorVolume._domeColorCommandsSource[index] = glsl; var sensorDomeFS = customSensorVolume._cameraIsInsideDome ? SensorDomeInsideFS : SensorDomeOutsideFS; From e23b17bba418eba3f34f2c131e4916fd676e9b0e Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Fri, 11 Apr 2014 14:09:17 -0400 Subject: [PATCH 05/49] Incremental changes. --- Apps/Sandcastle/gallery/Sensors.html | 62 ++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index ec47e094e0d2..affd5ee7dc6d 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -154,6 +154,57 @@ return customSensor; } + function addFootprint(ellipsoid) { + var customSensor = new Cesium.CustomSensorVolume(); + + var numberOfVertices = 180; + var azimuthDivision = 360.0 / numberOfVertices; + + var directions = []; + directions.push({ clock : Cesium.Math.toRadians( 0 ), cone : Cesium.Math.toRadians( 14.03624347 )}); + directions.push({ clock : Cesium.Math.toRadians( 74.3 ), cone : Cesium.Math.toRadians( 32.98357092 )}); + directions.push({ clock : Cesium.Math.toRadians( 80.54 ), cone : Cesium.Math.toRadians( 37.23483398 )}); + directions.push({ clock : Cesium.Math.toRadians( 90 ), cone : Cesium.Math.toRadians( 37.77568431 )}); + directions.push({ clock : Cesium.Math.toRadians( 101.31 ), cone : Cesium.Math.toRadians( 37.41598862 )}); + directions.push({ clock : Cesium.Math.toRadians( 116.56 ), cone : Cesium.Math.toRadians( 29.20519037 )}); + directions.push({ clock : Cesium.Math.toRadians( 180 ), cone : Cesium.Math.toRadians( 14.03624347 )}); + directions.push({ clock : Cesium.Math.toRadians( 247.2 ), cone : Cesium.Math.toRadians( 34.11764003 )}); + directions.push({ clock : Cesium.Math.toRadians( 251.56 ), cone : Cesium.Math.toRadians( 44.67589157 )}); + directions.push({ clock : Cesium.Math.toRadians( 253.96 ), cone : Cesium.Math.toRadians( 46.12330271 )}); + directions.push({ clock : Cesium.Math.toRadians( 259.63 ), cone : Cesium.Math.toRadians( 46.19202903 )}); + directions.push({ clock : Cesium.Math.toRadians( 262.87 ), cone : Cesium.Math.toRadians( 45.21405547 )}); + directions.push({ clock : Cesium.Math.toRadians( 262.4 ), cone : Cesium.Math.toRadians( 37.09839406 )}); + directions.push({ clock : Cesium.Math.toRadians( 266.47 ), cone : Cesium.Math.toRadians( 45.42651157 )}); + directions.push({ clock : Cesium.Math.toRadians( 270 ), cone : Cesium.Math.toRadians( 45.42651157 )}); + directions.push({ clock : Cesium.Math.toRadians( 270.97 ), cone : Cesium.Math.toRadians( 36.40877457 )}); + directions.push({ clock : Cesium.Math.toRadians( 272.79 ), cone : Cesium.Math.toRadians( 45.70731937 )}); + directions.push({ clock : Cesium.Math.toRadians( 278.33 ), cone : Cesium.Math.toRadians( 45.98533395 )}); + directions.push({ clock : Cesium.Math.toRadians( 281.89 ), cone : Cesium.Math.toRadians( 36.0358894 )}); + directions.push({ clock : Cesium.Math.toRadians( 282.99 ), cone : Cesium.Math.toRadians( 45 )}); + directions.push({ clock : Cesium.Math.toRadians( 286.99 ), cone : Cesium.Math.toRadians( 43.26652934 )}); + directions.push({ clock : Cesium.Math.toRadians( 291.8 ), cone : Cesium.Math.toRadians( 33.97011942 )}); + directions.push({ clock : Cesium.Math.toRadians( 293.3 ), cone : Cesium.Math.toRadians( 41.50882857 )}); + directions.push({ clock : Cesium.Math.toRadians( 300.96 ), cone : Cesium.Math.toRadians( 36.0826946 )}); + directions.push({ clock : Cesium.Math.toRadians( 319.18 ), cone : Cesium.Math.toRadians( 19.9888568 )}); + directions.push({ clock : Cesium.Math.toRadians( 0 ), cone : Cesium.Math.toRadians( 14.03624347 )}); + + customSensor.modelMatrix = getModelMatrix(ellipsoid); + customSensor.radius = 10000000.0; + customSensor.setDirections(directions); + customSensor.portionToDisplay = portion; + + customSensor.material = Cesium.Material.fromType('Color'); + customSensor.material.uniforms.color = new Cesium.Color(0.0, 1.0, 1.0, 0.5); + + customSensor.ellipsoidHorizonSurfaceMaterial = Cesium.Material.fromType('Color'); + customSensor.ellipsoidHorizonSurfaceMaterial.uniforms.color = new Cesium.Color(0.4, 1.0, 0.0, 0.0); + + customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); + customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5); + customSensor.debugShowProxyGeometry = false; + return customSensor; + } + function createUserInterface(viewer) { var tp = new TitlePane({ title: 'Manipulate Sensor', @@ -179,6 +230,9 @@ case 'Custom': sensor = addCustomSensor(ellipsoid); break; + case 'Foot': + sensor = addFootprint(ellipsoid); + break; case 'Rectangular': sensor = addRectangularSensor(ellipsoid); } @@ -209,6 +263,14 @@ } })); + sensorMenu.addChild(new MenuItem({ + label: 'Foot', + onClick: function() { + selection = 'Foot'; + updateSensor(); + } + })); + new DropDownButton({ label : 'Select a sensor', dropDown: sensorMenu From 0e21596b5aaa14615d6fdf5b7a58852755b91fa5 Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Mon, 14 Apr 2014 10:35:18 -0400 Subject: [PATCH 06/49] Removed redundant pattern point. Uniforms tweaks. --- Apps/Sandcastle/gallery/Sensors.html | 5 ++--- Source/Core/SphericalPolygon.js | 33 ++++++++++++---------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index affd5ee7dc6d..724e26aab99a 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -79,7 +79,7 @@ var clock = 0.0; var cone = Cesium.Math.toRadians(0.0); var twist = 0.0; - var selection = 'Custom'; + var selection = 'Foot'; var portion = Cesium.SensorVolumePortionToDisplay.COMPLETE; function getModelMatrix(ellipsoid) @@ -186,7 +186,6 @@ directions.push({ clock : Cesium.Math.toRadians( 293.3 ), cone : Cesium.Math.toRadians( 41.50882857 )}); directions.push({ clock : Cesium.Math.toRadians( 300.96 ), cone : Cesium.Math.toRadians( 36.0826946 )}); directions.push({ clock : Cesium.Math.toRadians( 319.18 ), cone : Cesium.Math.toRadians( 19.9888568 )}); - directions.push({ clock : Cesium.Math.toRadians( 0 ), cone : Cesium.Math.toRadians( 14.03624347 )}); customSensor.modelMatrix = getModelMatrix(ellipsoid); customSensor.radius = 10000000.0; @@ -197,7 +196,7 @@ customSensor.material.uniforms.color = new Cesium.Color(0.0, 1.0, 1.0, 0.5); customSensor.ellipsoidHorizonSurfaceMaterial = Cesium.Material.fromType('Color'); - customSensor.ellipsoidHorizonSurfaceMaterial.uniforms.color = new Cesium.Color(0.4, 1.0, 0.0, 0.0); + customSensor.ellipsoidHorizonSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 0.0, 1.0, 0.5); customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5); diff --git a/Source/Core/SphericalPolygon.js b/Source/Core/SphericalPolygon.js index 0e05f9836ce0..c023908a9ca8 100644 --- a/Source/Core/SphericalPolygon.js +++ b/Source/Core/SphericalPolygon.js @@ -296,11 +296,11 @@ define([ return result; } - function sphericalPolygonImplicitSurfaceFunctionUniforms(hull) { + function sphericalPolygonImplicitSurfaceFunctionUniforms(hull, uniforms) { var result = ''; if (defined(hull.holes)) { for (var h = 0; h < hull.holes.length; ++h) { - result += sphericalPolygonImplicitSurfaceFunctionUniforms(hull.holes[h]); + result += sphericalPolygonImplicitSurfaceFunctionUniforms(hull.holes[h], uniforms); } } var length = hull.length; @@ -308,12 +308,11 @@ define([ var j = (i + 1 === length) ? 0 : i + 1; var initialIndex = hull[i]; var finalIndex = hull[j]; - if (initialIndex < finalIndex) { - var uniform1 = kDopFacetNormalName(initialIndex, finalIndex); - result += 'uniform vec3 ' + uniform1 + ';\n'; - } else if (finalIndex === 0) { - var uniform2 = kDopFacetNormalName(finalIndex, initialIndex); - result += 'uniform vec3 ' + uniform2 + ';\n'; + var name = (initialIndex < finalIndex) ? kDopFacetNormalName(initialIndex, finalIndex) : kDopFacetNormalName(finalIndex, initialIndex); + + if (!defined(uniforms[name])) { + uniforms[name] = true; + result += 'uniform vec3 ' + name + ';\n'; } } return result; @@ -361,17 +360,12 @@ define([ lastDirection = Cartesian3.fromArray(floats, offset, lastDirection); offset = finalIndex * stride + directionsOffset; direction = Cartesian3.fromArray(floats, offset, direction); + var name = (initialIndex < finalIndex) ? kDopFacetNormalName(initialIndex, finalIndex) : kDopFacetNormalName(finalIndex, initialIndex); - if (initialIndex < finalIndex) { - var normal1 = new Cartesian3(); - normal1 = Cartesian3.cross(direction, lastDirection, normal1); - var uniform1 = kDopFacetNormalName(initialIndex, finalIndex); - uniforms[uniform1] = returnNormal(normal1); - } else if (finalIndex === 0) { - var normal2 = new Cartesian3(); - normal2 = Cartesian3.cross(lastDirection, direction, normal2); - var uniform2 = kDopFacetNormalName(finalIndex, initialIndex); - uniforms[uniform2] = returnNormal(normal2); + if (!defined(uniforms[name])) { + var normal = new Cartesian3(); + normal = (initialIndex < finalIndex) ? Cartesian3.cross(direction, lastDirection, normal) : Cartesian3.cross(lastDirection, direction, normal); + uniforms[name] = returnNormal(normal); } } } @@ -385,7 +379,8 @@ define([ SphericalPolygon.implicitSurfaceFunction = function(hull, name, sign) { var glsl = '\n'; // Emit uniforms. - glsl += sphericalPolygonImplicitSurfaceFunctionUniforms(hull); + var uniforms = {}; + glsl += sphericalPolygonImplicitSurfaceFunctionUniforms(hull, uniforms); // Emit convex hull funtions. var functionName = 'convexHull'; var variableName = 'value'; From 1925361c19afd96849eaba04a857a2122192e4e1 Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Mon, 14 Apr 2014 11:07:10 -0400 Subject: [PATCH 07/49] Using spherical polygon float array. --- Apps/Sandcastle/gallery/Sensors.html | 2 +- Source/Scene/CustomSensorVolume.js | 43 ++++++++-------------------- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 724e26aab99a..5f09bb99c01a 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -200,7 +200,7 @@ customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5); - customSensor.debugShowProxyGeometry = false; + customSensor.debugShowProxyGeometry = true; return customSensor; } diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index b07f75b92a23..2f48d1a81a13 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -238,7 +238,6 @@ define([ this._sphericals = undefined; this._sphericalsDirty = false; - this._directionsNormalsAndBisectorsWithMagnitudeSquared = undefined; this.setDirections(options.directions); /** @@ -481,7 +480,6 @@ define([ var length = sphericals.length; var size = length * 3; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared = new Float32Array(3 * size + length); customSensorVolume._ellipsoidHorizonSurfaceColorCommands = new Array(length + 1); customSensorVolume._domeColorCommands = new Array(length + 1); @@ -504,27 +502,10 @@ define([ var primitiveType = customSensorVolume.debugShowProxyGeometry ? PrimitiveType.LINES : customSensorVolume._frontFaceColorCommand.primitiveType; - var last = Cartesian3.fromSpherical(sphericals[length - 1]); for (var index = 0; index < length; ++index) { var direction = Cartesian3.fromSpherical(sphericals[index]); - var bisector = Cartesian3.divideByScalar(Cartesian3.add(last, direction), 2.0); - var normal = Cartesian3.normalize(Cartesian3.cross(direction, last)); - last = direction; - directions.push(Cartesian3.clone(direction)); - var offset = index * 10; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset] = direction.x; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 1] = direction.y; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 2] = direction.z; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 3] = normal.x; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 4] = normal.y; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 5] = normal.z; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 6] = bisector.x; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 7] = bisector.y; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 8] = bisector.z; - customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 9] = Cartesian3.magnitudeSquared(bisector); - var horizonCommand = new DrawCommand(); horizonCommand.primitiveType = primitiveType; horizonCommand.owner = customSensorVolume; @@ -1112,11 +1093,11 @@ define([ var length = directions.length; var normals = []; var k = -1; - previous = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[length - 1] * stride, previous); + previous = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[length - 1] * stride, previous); var lastFront = frontSides[length - 1]; var lastBack = backSides[length - 1]; for (var index = 0; index < length; ++index) { - current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[index] * stride, current); + current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[index] * stride, current); var front = frontSides[index]; var back = backSides[index]; n = Cartesian3.normalize(Cartesian3.cross(current, previous, n), n); @@ -1198,14 +1179,14 @@ define([ var length = directions.length; d = Cartesian3.clone(Cartesian3.ZERO, d); for (var ii = 0; ii < length; ++ii) { - current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); + current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); d = Cartesian3.add(d, current, d); } d = Cartesian3.magnitudeSquared(d) > CesiumMath.EPSILON15 ? Cartesian3.normalize(d, d) : Cartesian3.clone(Cartesian3.UNIT_Z, d); var minDot = 1.0; for (var iii = 0; iii < length; ++iii) { - current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); + current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); minDot = Math.min(Cartesian3.dot(current, d), minDot); } @@ -1213,9 +1194,9 @@ define([ var backs = []; for ( var i = length - 2, j = length - 1, k = 0; k < length; i = j++, j = k++) { // PERFORMANCE_IDEA: We can avoid redundant operations for adjacent edges. - previous = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); - current = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); - next = Cartesian3.unpack(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); + previous = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); + current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); + next = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); // Extend position so the volume encompasses the sensor's radius. Use the shorter bisector in the scaling. var factor = 2.0 / Math.min(Cartesian3.magnitude(Cartesian3.add(previous, current)), Cartesian3.magnitude(Cartesian3.add(current, next))); @@ -1431,8 +1412,8 @@ define([ var length = customSensorVolume._sphericals.length; for (var index = 0; index < length; ++index) { var offset = index * 10; - direction = Cartesian3.fromArray(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, offset, direction); - normal = Cartesian3.fromArray(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, offset + 3, normal); + direction = Cartesian3.fromArray(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, offset, direction); + normal = Cartesian3.fromArray(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, offset + 3, normal); b = customSensorVolume.ellipsoid.transformPositionFromScaledSpace(Matrix3.multiplyByVector(modelToWorld, normal, b)); bUnit = Cartesian3.normalize(b, bUnit); var cosineSigma = Cartesian3.dot(q, bUnit); @@ -1456,8 +1437,8 @@ define([ s = customSensorVolume.ellipsoid.transformPositionFromScaledSpace(r, s); v = Matrix3.multiplyByVector(worldToModel, Cartesian3.subtract(s, p), v); d = Cartesian3.normalize(v, d); - bisector = Cartesian3.fromArray(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, offset + 6, bisector); - var bisectorMagnitudeSquared = customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 9]; + bisector = Cartesian3.fromArray(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, offset + 6, bisector); + var bisectorMagnitudeSquared = customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared[offset + 9]; if ((customSensorVolume.portionToDisplay !== SensorVolumePortionToDisplay.COMPLETE || Cartesian3.magnitudeSquared(v) <= radiusSquared) && Cartesian3.dot(d, bisector) > bisectorMagnitudeSquared) { if (!foundOffCrossing) { @@ -1520,7 +1501,7 @@ define([ if (foundOnCrossingFirst && foundOffCrossing) { for (var i = 0; i < firstOnCrossingIndex; ++i) { var offset2 = i * 10; - direction = Cartesian3.fromArray(customSensorVolume._directionsNormalsAndBisectorsWithMagnitudeSquared, offset2, direction); + direction = Cartesian3.fromArray(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, offset2, direction); directions.push(Cartesian3.clone(direction)); } directions.push(Cartesian3.clone(firstOnCrossingDirection)); From 9a18f3a538bec0ee3407b0d2eb7e7b24ba897304 Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Mon, 14 Apr 2014 12:00:31 -0400 Subject: [PATCH 08/49] Simplifying helper functions. --- Apps/Sandcastle/gallery/Sensors.html | 2 +- Source/Scene/CustomSensorVolume.js | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 5f09bb99c01a..724e26aab99a 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -200,7 +200,7 @@ customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5); - customSensor.debugShowProxyGeometry = true; + customSensor.debugShowProxyGeometry = false; return customSensor; } diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 2f48d1a81a13..3062d99d2b14 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -1088,16 +1088,16 @@ define([ var current = new Cartesian3(); var next = new Cartesian3(); - function computeBoundingPyramidalFrustumVertices(customSensorVolume, directions, frontCenter, frontSides, backCenter, backSides, vertices) { + function computeBoundingPyramidalFrustumVertices(directionsNormalsAndBisectorsWithMagnitudeSquared, directions, frontCenter, frontSides, backCenter, backSides, vertices) { var stride = 10; var length = directions.length; var normals = []; var k = -1; - previous = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[length - 1] * stride, previous); + previous = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[length - 1] * stride, previous); var lastFront = frontSides[length - 1]; var lastBack = backSides[length - 1]; for (var index = 0; index < length; ++index) { - current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[index] * stride, current); + current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[index] * stride, current); var front = frontSides[index]; var back = backSides[index]; n = Cartesian3.normalize(Cartesian3.cross(current, previous, n), n); @@ -1174,19 +1174,19 @@ define([ var centerFront = new Cartesian3(); var centerBack = new Cartesian3(); - function computeDomeVertices(customSensorVolume, directions, radius, vertices) { + function computeDomeVertices(directionsNormalsAndBisectorsWithMagnitudeSquared, directions, radius, vertices) { var stride = 10; var length = directions.length; d = Cartesian3.clone(Cartesian3.ZERO, d); for (var ii = 0; ii < length; ++ii) { - current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); + current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); d = Cartesian3.add(d, current, d); } d = Cartesian3.magnitudeSquared(d) > CesiumMath.EPSILON15 ? Cartesian3.normalize(d, d) : Cartesian3.clone(Cartesian3.UNIT_Z, d); var minDot = 1.0; for (var iii = 0; iii < length; ++iii) { - current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); + current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); minDot = Math.min(Cartesian3.dot(current, d), minDot); } @@ -1194,9 +1194,9 @@ define([ var backs = []; for ( var i = length - 2, j = length - 1, k = 0; k < length; i = j++, j = k++) { // PERFORMANCE_IDEA: We can avoid redundant operations for adjacent edges. - previous = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); - current = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); - next = Cartesian3.unpack(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); + previous = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); + current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); + next = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); // Extend position so the volume encompasses the sensor's radius. Use the shorter bisector in the scaling. var factor = 2.0 / Math.min(Cartesian3.magnitude(Cartesian3.add(previous, current)), Cartesian3.magnitude(Cartesian3.add(current, next))); @@ -1208,7 +1208,7 @@ define([ centerFront = Cartesian3.multiplyByScalar(d, radius * minDot, centerFront); centerBack = Cartesian3.multiplyByScalar(d, radius, centerBack); - return computeBoundingPyramidalFrustumVertices(customSensorVolume, directions, centerFront, fronts, centerBack, backs, vertices); + return computeBoundingPyramidalFrustumVertices(directionsNormalsAndBisectorsWithMagnitudeSquared, directions, centerFront, fronts, centerBack, backs, vertices); } function updateDomeCommand(command, index, customSensorVolume, context, directions, radius) { @@ -1217,7 +1217,7 @@ define([ var domeFloatOffset = customSensorVolume._domeVertexCount * numberOfFloatsPerVertex; var vertices = new Float32Array(customSensorVolume._domeCommandsVertices.buffer, Float32Array.BYTES_PER_ELEMENT * domeFloatOffset, numberOfFloats); - var normals = computeDomeVertices(customSensorVolume, customSensorVolume._hull, radius, vertices); + var normals = computeDomeVertices(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, customSensorVolume._hull, radius, vertices); // var uniforms = kDopUniforms(normals); var uniforms = customSensorVolume._sensorUniforms; @@ -1226,7 +1226,6 @@ define([ command.uniformMap = combine(combine(customSensorVolume._uniforms, customSensorVolume._domeSurfaceMaterial._uniforms), uniforms); command.boundingVolume = BoundingSphere.transform(boundingVolume, customSensorVolume.modelMatrix, command.boundingVolume); command.modelMatrix = customSensorVolume.modelMatrix; -// command.debugShowBoundingVolume = true; customSensorVolume._domeVertexCount += numberOfVertices; customSensorVolume._domeCommandsBuffer.copyFromArrayView(vertices, Float32Array.BYTES_PER_ELEMENT * domeFloatOffset); From f10c8547cb37e3cff70e83338cebab207f40c6f1 Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Mon, 14 Apr 2014 13:00:07 -0400 Subject: [PATCH 09/49] Using fromArray instead of unpack. --- Source/Scene/CustomSensorVolume.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 3062d99d2b14..4d64c240198c 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -1093,11 +1093,11 @@ define([ var length = directions.length; var normals = []; var k = -1; - previous = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[length - 1] * stride, previous); + previous = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[length - 1] * stride, previous); var lastFront = frontSides[length - 1]; var lastBack = backSides[length - 1]; for (var index = 0; index < length; ++index) { - current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[index] * stride, current); + current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[index] * stride, current); var front = frontSides[index]; var back = backSides[index]; n = Cartesian3.normalize(Cartesian3.cross(current, previous, n), n); @@ -1179,14 +1179,14 @@ define([ var length = directions.length; d = Cartesian3.clone(Cartesian3.ZERO, d); for (var ii = 0; ii < length; ++ii) { - current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); + current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); d = Cartesian3.add(d, current, d); } d = Cartesian3.magnitudeSquared(d) > CesiumMath.EPSILON15 ? Cartesian3.normalize(d, d) : Cartesian3.clone(Cartesian3.UNIT_Z, d); var minDot = 1.0; for (var iii = 0; iii < length; ++iii) { - current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); + current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); minDot = Math.min(Cartesian3.dot(current, d), minDot); } @@ -1194,9 +1194,9 @@ define([ var backs = []; for ( var i = length - 2, j = length - 1, k = 0; k < length; i = j++, j = k++) { // PERFORMANCE_IDEA: We can avoid redundant operations for adjacent edges. - previous = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); - current = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); - next = Cartesian3.unpack(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); + previous = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); + current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); + next = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); // Extend position so the volume encompasses the sensor's radius. Use the shorter bisector in the scaling. var factor = 2.0 / Math.min(Cartesian3.magnitude(Cartesian3.add(previous, current)), Cartesian3.magnitude(Cartesian3.add(current, next))); From b66a4bae0352a08677fb74c9c20502305392057f Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Mon, 14 Apr 2014 14:11:09 -0400 Subject: [PATCH 10/49] Fixing issue with index cycling. --- Source/Core/SphericalPolygon.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Source/Core/SphericalPolygon.js b/Source/Core/SphericalPolygon.js index c023908a9ca8..9ffe9f358493 100644 --- a/Source/Core/SphericalPolygon.js +++ b/Source/Core/SphericalPolygon.js @@ -21,8 +21,6 @@ define([ this._isConvex = undefined; this._vertices = undefined; this._directionsNormalsAndBisectorsWithMagnitudeSquared = undefined; - this._referenceDirection = new Cartesian3(); - this._referencePoint = new Cartesian3(); // cameraPosition fills in the above values if (defined(vertices)) { @@ -234,7 +232,8 @@ define([ for (var k = 0; k < hull.length - 1; ++k) { var current = hull[k]; var next = hull[k + 1]; - if (next - current > 1) { + var difference = (current < next) ? next - current : next + numberOfVertices - current; + if (difference > 1) { hole = []; SphericalPolygon.findConvexHull(floats, stride, directionsOffset, sign * -1.0, current, next, hole); hull.holes.push(hole); From 756df810dbbbbbdfa06ef783aa738eb03e2b7540 Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Mon, 14 Apr 2014 15:02:31 -0400 Subject: [PATCH 11/49] Using stored normals when possible. --- Source/Core/SphericalPolygon.js | 19 ++++++++++++------- Source/Scene/CustomSensorVolume.js | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Source/Core/SphericalPolygon.js b/Source/Core/SphericalPolygon.js index 9ffe9f358493..086ab2f0c56d 100644 --- a/Source/Core/SphericalPolygon.js +++ b/Source/Core/SphericalPolygon.js @@ -343,10 +343,12 @@ define([ }; } - function addUniforms(floats, stride, directionsOffset, hull, uniforms) { + function addUniforms(floats, stride, directionsOffset, normalsOffset, hull, uniforms) { + var numberOfVertices = floats.length / stride; + if (defined(hull.holes)) { for (var h = 0; h < hull.holes.length; ++h) { - addUniforms(floats, stride, directionsOffset, hull.holes[h], uniforms); + addUniforms(floats, stride, directionsOffset, normalsOffset, hull.holes[h], uniforms); } } var length = hull.length; @@ -362,16 +364,19 @@ define([ var name = (initialIndex < finalIndex) ? kDopFacetNormalName(initialIndex, finalIndex) : kDopFacetNormalName(finalIndex, initialIndex); if (!defined(uniforms[name])) { - var normal = new Cartesian3(); - normal = (initialIndex < finalIndex) ? Cartesian3.cross(direction, lastDirection, normal) : Cartesian3.cross(lastDirection, direction, normal); - uniforms[name] = returnNormal(normal); + var difference = (initialIndex < finalIndex) ? finalIndex - initialIndex : finalIndex + numberOfVertices - initialIndex; + if (difference === 1) { + uniforms[name] = returnNormal(Cartesian3.fromArray(floats, finalIndex * stride + normalsOffset)); + } else { + uniforms[name] = (initialIndex < finalIndex) ? returnNormal(Cartesian3.cross(direction, lastDirection)) : returnNormal(Cartesian3.cross(lastDirection, direction)); + } } } } - SphericalPolygon.uniforms = function(floats, stride, directionsOffset, hull) { + SphericalPolygon.prototype.uniforms = function(hull) { var uniforms = { }; - addUniforms(floats, stride, directionsOffset, hull, uniforms); + addUniforms(this._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 3, hull, uniforms); return uniforms; }; diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 4d64c240198c..1a14c58a6050 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -474,7 +474,7 @@ define([ SphericalPolygon.findConvexHull(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, 1.0, 0, customSensorVolume._sphericals.length - 1, customSensorVolume._hull); customSensorVolume._sensorGlsl = SphericalPolygon.implicitSurfaceFunction(customSensorVolume._hull, 'sensorSurfaceFunction', '+'); - customSensorVolume._sensorUniforms = SphericalPolygon.uniforms(customSensorVolume._sphericalPolygon._directionsNormalsAndBisectorsWithMagnitudeSquared, 10, 0, customSensorVolume._hull); + customSensorVolume._sensorUniforms = customSensorVolume._sphericalPolygon.uniforms(customSensorVolume._hull); var sphericals = customSensorVolume._sphericals; var length = sphericals.length; From 48b210e6d6871302a98a1ade4c333d930cad4a5a Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Tue, 15 Apr 2014 10:07:58 -0400 Subject: [PATCH 12/49] Use consistent uniform normal sense from indices. --- Source/Core/SphericalPolygon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/SphericalPolygon.js b/Source/Core/SphericalPolygon.js index 086ab2f0c56d..12b3d086508e 100644 --- a/Source/Core/SphericalPolygon.js +++ b/Source/Core/SphericalPolygon.js @@ -366,7 +366,7 @@ define([ if (!defined(uniforms[name])) { var difference = (initialIndex < finalIndex) ? finalIndex - initialIndex : finalIndex + numberOfVertices - initialIndex; if (difference === 1) { - uniforms[name] = returnNormal(Cartesian3.fromArray(floats, finalIndex * stride + normalsOffset)); + uniforms[name] = (initialIndex < finalIndex) ? returnNormal(Cartesian3.fromArray(floats, finalIndex * stride + normalsOffset)) : returnNormal(Cartesian3.negate(Cartesian3.fromArray(floats, finalIndex * stride + normalsOffset))); } else { uniforms[name] = (initialIndex < finalIndex) ? returnNormal(Cartesian3.cross(direction, lastDirection)) : returnNormal(Cartesian3.cross(lastDirection, direction)); } From 165a1b21bfb516cd8248e29caafb77592e299b1e Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Wed, 16 Apr 2014 08:40:33 -0400 Subject: [PATCH 13/49] Tweaks for debugging. --- Apps/Sandcastle/gallery/Sensors.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 724e26aab99a..562a053b1980 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -196,11 +196,11 @@ customSensor.material.uniforms.color = new Cesium.Color(0.0, 1.0, 1.0, 0.5); customSensor.ellipsoidHorizonSurfaceMaterial = Cesium.Material.fromType('Color'); - customSensor.ellipsoidHorizonSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 0.0, 1.0, 0.5); + customSensor.ellipsoidHorizonSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 0.0, 1.0, 0.0); customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5); - customSensor.debugShowProxyGeometry = false; + customSensor.debugShowProxyGeometry = true; return customSensor; } From fcb9d49538a3db99a3621db9276b08ab0dbe0f43 Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Wed, 16 Apr 2014 10:59:15 -0400 Subject: [PATCH 14/49] Optimized proxy geometry for dome. --- Apps/Sandcastle/gallery/Sensors.html | 7 ++++--- Source/Scene/CustomSensorVolume.js | 25 +++++++++++++++---------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 562a053b1980..392f9b4c7a87 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -74,8 +74,8 @@ "use strict"; var longitude = Cesium.Math.toRadians(0.0); - var latitude = Cesium.Math.toRadians(90.0); - var altitude = 15000000.0; + var latitude = Cesium.Math.toRadians(0.0); + var altitude = 11000000.0; var clock = 0.0; var cone = Cesium.Math.toRadians(0.0); var twist = 0.0; @@ -116,6 +116,7 @@ rectangularPyramidSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); rectangularPyramidSensor.domeSurfaceMaterial.uniforms.cellAlpha = 0.5; rectangularPyramidSensor.domeSurfaceMaterial.uniforms.lineCount = { x: 12, y: 12 }; + rectangularPyramidSensor.debugShowProxyGeometry = false; return rectangularPyramidSensor; } @@ -200,7 +201,7 @@ customSensor.domeSurfaceMaterial = Cesium.Material.fromType('Color'); customSensor.domeSurfaceMaterial.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.5); - customSensor.debugShowProxyGeometry = true; + customSensor.debugShowProxyGeometry = false; return customSensor; } diff --git a/Source/Scene/CustomSensorVolume.js b/Source/Scene/CustomSensorVolume.js index 1a14c58a6050..0a149cac07ed 100644 --- a/Source/Scene/CustomSensorVolume.js +++ b/Source/Scene/CustomSensorVolume.js @@ -1176,33 +1176,38 @@ define([ function computeDomeVertices(directionsNormalsAndBisectorsWithMagnitudeSquared, directions, radius, vertices) { var stride = 10; + var directionsOffset = 0; + var length = directions.length; d = Cartesian3.clone(Cartesian3.ZERO, d); for (var ii = 0; ii < length; ++ii) { - current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride, current); + current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[ii] * stride + directionsOffset, current); d = Cartesian3.add(d, current, d); } d = Cartesian3.magnitudeSquared(d) > CesiumMath.EPSILON15 ? Cartesian3.normalize(d, d) : Cartesian3.clone(Cartesian3.UNIT_Z, d); var minDot = 1.0; + var maxDot = -1.0; + var lastIndex = directions[length - 1]; for (var iii = 0; iii < length; ++iii) { - current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[iii] * stride, current); + var index = directions[iii]; + previous = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, lastIndex * stride + directionsOffset, previous); + current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, index * stride + directionsOffset, current); minDot = Math.min(Cartesian3.dot(current, d), minDot); + bisector = Cartesian3.normalize(Cartesian3.add(previous, current, bisector), bisector); + maxDot = Math.max(Cartesian3.dot(bisector, d), maxDot); + lastIndex = index; } var fronts = []; var backs = []; - for ( var i = length - 2, j = length - 1, k = 0; k < length; i = j++, j = k++) { - // PERFORMANCE_IDEA: We can avoid redundant operations for adjacent edges. - previous = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride, previous); - current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[j] * stride, current); - next = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[k] * stride, next); + for ( var i = 0; i < length; ++i) { + current = Cartesian3.fromArray(directionsNormalsAndBisectorsWithMagnitudeSquared, directions[i] * stride + directionsOffset, current); // Extend position so the volume encompasses the sensor's radius. Use the shorter bisector in the scaling. - var factor = 2.0 / Math.min(Cartesian3.magnitude(Cartesian3.add(previous, current)), Cartesian3.magnitude(Cartesian3.add(current, next))); var dot = Cartesian3.dot(current, d); - fronts.push(Cartesian3.add(Cartesian3.multiplyByScalar(current, radius * factor), Cartesian3.multiplyByScalar(d, radius * (minDot - factor * dot)))); - backs.push(Cartesian3.add(Cartesian3.multiplyByScalar(current, radius * factor), Cartesian3.multiplyByScalar(d, radius * (1.0 - factor * dot)))); + fronts.push(Cartesian3.subtract(Cartesian3.multiplyByScalar(current, radius * maxDot / dot), Cartesian3.multiplyByScalar(d, radius * (maxDot - minDot)))); + backs.push(Cartesian3.add(Cartesian3.multiplyByScalar(current, radius * maxDot / dot), Cartesian3.multiplyByScalar(d, radius * (1.0 - maxDot)))); } centerFront = Cartesian3.multiplyByScalar(d, radius * minDot, centerFront); From 88ccb21f7f4fc962d545310d676f17fef5f448bb Mon Sep 17 00:00:00 2001 From: Frank Stoner Date: Wed, 16 Apr 2014 15:26:58 -0400 Subject: [PATCH 15/49] Improving computation of reference axis & distance. --- Apps/Sandcastle/gallery/Sensors.html | 23 ++++- Source/Core/SphericalPolygon.js | 134 +++++++-------------------- Source/Scene/CustomSensorVolume.js | 11 ++- 3 files changed, 62 insertions(+), 106 deletions(-) diff --git a/Apps/Sandcastle/gallery/Sensors.html b/Apps/Sandcastle/gallery/Sensors.html index 392f9b4c7a87..9a49fc269058 100644 --- a/Apps/Sandcastle/gallery/Sensors.html +++ b/Apps/Sandcastle/gallery/Sensors.html @@ -62,14 +62,18 @@ + + Show Proxy Geometry + +