From 945f274dee2acf32ff061fd92685ee86fb737189 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Sat, 21 Jan 2017 12:13:42 -0500 Subject: [PATCH 001/115] Added some settings for VSCode. --- .vscode/settings.json | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000000..0958f052e424 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,31 @@ +// Cesium project settings for VSCode. +{ + "files.exclude": { + "**/.git": true, + ".idea": true, + ".metadata": true, + "Build": true, + "Instrumented": true, + "**/Cesium-*.zip": true, + "**/cesium-*.tgz": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + + "Apps/CesiumViewer/Gallery/gallery-index.js": true, + + "Apps/Sandcastle/jsHintOptions.js": true, + "Apps/Sandcastle/gallery/gallery-index.js": true, + + "Source/Cesium.js": true, + "Source/Shaders/**/*.js": true, + + "Specs/SpecList.js": true, + "node_modules": true, + "npm-debug.log": true + }, + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, + "editor.insertSpaces": true, + "editor.tabSize": 4, + "editor.detectIndentation": false +} From 3c172b6e7a8f1f4892d25a2cda6c1ce97ab040c7 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Sat, 21 Jan 2017 21:19:13 -0500 Subject: [PATCH 002/115] Add tasks file for VSCode, add new startPublic task. --- .vscode/tasks.json | 131 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 132 insertions(+) create mode 100644 .vscode/tasks.json diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000000..e8097e4bb634 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,131 @@ +{ + // To launch one of these tasks in Visual Studio Code, + // press CTRL+P and type "task ", then select a task + // from the auto-complete list. + // + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "0.1.0", + "command": "npm", + "isShellCommand": true, + "showOutput": "always", + "suppressTaskName": true, + "tasks": [ + { + "taskName": "start", + "args": ["run", "start"] + }, + { + "taskName": "startPublic", + "args": ["run", "startPublic"] + }, + { + "taskName": "build", + "args": ["run", "build"] + }, + { + "taskName": "build-watch", + "args": ["run", "build-watch"] + }, + { + "taskName": "buildApps", + "args": ["run", "buildApps"] + }, + { + "taskName": "clean", + "args": ["run", "clean"] + }, + { + "taskName": "cloc", + "args": ["run", "cloc"] + }, + { + "taskName": "combine", + "args": ["run", "combine"] + }, + { + "taskName": "combineRelease", + "args": ["run", "combineRelease"] + }, + { + "taskName": "requirejs", + "args": ["run", "requirejs"] + }, + { + "taskName": "generateDocumentation", + "args": ["run", "generateDocumentation"] + }, + { + "taskName": "instrumentForCoverage", + "args": ["run", "instrumentForCoverage"] + }, + { + "taskName": "jsHint", + "args": ["run", "jsHint"] + }, + { + "taskName": "jsHint-watch", + "args": ["run", "jsHint-watch"] + }, + { + "taskName": "makeZipFile", + "args": ["run", "makeZipFile"] + }, + { + "taskName": "minify", + "args": ["run", "minify"] + }, + { + "taskName": "minifyRelease", + "args": ["run", "minifyRelease"] + }, + { + "taskName": "release", + "args": ["run", "release"] + }, + { + "taskName": "test", + "args": ["run", "test"] + }, + { + "taskName": "test-all", + "args": ["run", "test-all"] + }, + { + "taskName": "test-webgl", + "args": ["run", "test-webgl"] + }, + { + "taskName": "test-non-webgl", + "args": ["run", "test-non-webgl"] + }, + { + "taskName": "test-webgl-validation", + "args": ["run", "test-webgl-validation"] + }, + { + "taskName": "test-release", + "args": ["run", "test-release"] + }, + { + "taskName": "generateStubs", + "args": ["run", "generateStubs"] + }, + { + "taskName": "sortRequires", + "args": ["run", "sortRequires"] + }, + { + "taskName": "deploy-s3", + "args": ["run", "deploy-s3"] + }, + { + "taskName": "deploy-status", + "args": ["run", "deploy-status"] + }, + { + "taskName": "deploy-set-version", + "args": ["run", "deploy-set-version"] + } + ] +} diff --git a/package.json b/package.json index c5df42eebcee..b2d1fa0a9b98 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ }, "scripts": { "start": "node server.js", + "startPublic": "node server.js --public", "build": "gulp build", "build-watch": "gulp build-watch", "buildApps": "gulp buildApps", From e01ff2715a6df4818ffece53f969de2b89b7f688 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Fri, 27 Jan 2017 17:28:00 -0500 Subject: [PATCH 003/115] VSCode has an issue where it can't ignore without a wildcard pattern. --- .vscode/settings.json | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 0958f052e424..8f66ab2f52cf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,17 +11,15 @@ "**/.DS_Store": true, "**/Thumbs.db": true, - "Apps/CesiumViewer/Gallery/gallery-index.js": true, + "Apps/Sandcastle/jsHintOption?.js": true, + "Apps/Sandcastle/gallery/gallery-inde?.js": true, - "Apps/Sandcastle/jsHintOptions.js": true, - "Apps/Sandcastle/gallery/gallery-index.js": true, - - "Source/Cesium.js": true, + "Source/Cesiu?.js": true, "Source/Shaders/**/*.js": true, - "Specs/SpecList.js": true, + "Specs/SpecLis?.js": true, "node_modules": true, - "npm-debug.log": true + "npm-debu?.log": true }, "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, From 9dbc4535c5b1a1635981bbe379e178b21cda481e Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Thu, 9 Feb 2017 14:53:43 -0500 Subject: [PATCH 004/115] Add contributor guide for VSCode. --- .../Contributors/VSCodeGuide/README.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Documentation/Contributors/VSCodeGuide/README.md diff --git a/Documentation/Contributors/VSCodeGuide/README.md b/Documentation/Contributors/VSCodeGuide/README.md new file mode 100644 index 000000000000..ff70035ace8a --- /dev/null +++ b/Documentation/Contributors/VSCodeGuide/README.md @@ -0,0 +1,55 @@ +# VSCode Guide + +1. Install [VSCode](https://code.visualstudio.com/). + +2. Click `File -> Open Folder...` and open the Cesium root folder. + +## Shell Integration (optional) + +VSCode has an integrated shell, exposed on Windows by pressing CTRL-\` (CTRL-backtick). +You may want to switch this to be a git bash shell by default. If so, click +File -> Preferences -> Settings... and enter `integrated.shell` into the search +box. Choose the appropriate key for your operating system, for example +`terminal.integrated.shell.windows` for Windows, and click the edit icon. +The default setting will be copied to your user settings. The default for +Windows is `"C:\\Windows\\system32\\cmd.exe"`. Change this to point to your +git bash install. For example: + +``` +{ + "terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe" +} +``` + +Note that on Windows, the git bash desktop icon points at a different exe file, +one that forces a separate (non-integrated) window to pop open outside of VSCode. +Make sure you are pointed at the correct exe as shown above, with Git 2.0.0 or +higher installed, to get the correct integrated shell behavior. + +## VSCode Plugins (mostly optional) + +Click on the extensions icon, or press CTRL-SHIFT-X to see the list of installed +VSCode extensions. While we don't officially endorse any particular 3rd-party +plugin, there are some that appear to be quite useful to Cesium. Just enter +the desired plugin name in the search box and click install. You will need to +restart VSCode after you are done installing plugins. + +* **jshint** by Dirk Baeumer -- This plugin picks up on Cesium's own jsHint settings, +and will warn of any violations. The Cesium main repository should pass jsHint +using the Cesium jsHint settings with no warnings and no errors. Proposed +contributions to Cesium that introduce jsHint warnings will need to be corrected +before they are accepted. + +* **Shader languages support for VS Code** by slevesque -- This plugin provides +syntax highlighting for Cesium's shader code. + +* **Prettify JSON** by Mohsen Azimi -- This seems generally useful. + +## VSCode Tasks and Files + +You can launch any of Cesium's npm tasks from within VSCode by pressing +CTRL-P and typing `task ` (with a trailing space). Autocomplete will +offer the list of npm tasks for you to run. + +You can also jump to any source file with the same CTRL-P keypress +followed by the name of the file. From 26f8dd1461fbd6e7f65bc6e4899b4c764164d133 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Thu, 9 Feb 2017 14:56:57 -0500 Subject: [PATCH 005/115] Add launch file for server.js --- .vscode/launch.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000000..85fb445c2db3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible Node.js debug attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "program": "${workspaceRoot}\\server.js", + "cwd": "${workspaceRoot}" + }, + { + "type": "node", + "request": "attach", + "name": "Attach to Process", + "port": 5858 + } + ] +} \ No newline at end of file From 249b9b039b6ea2aa2dced856142ecb145167092e Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Thu, 9 Feb 2017 15:06:23 -0500 Subject: [PATCH 006/115] Explicitly enable the jshint plugin, so users can disable it elsewhere. --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8f66ab2f52cf..f04ffafe314e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,5 +25,6 @@ "files.insertFinalNewline": true, "editor.insertSpaces": true, "editor.tabSize": 4, - "editor.detectIndentation": false + "editor.detectIndentation": false, + "jshint.enable": true } From e4d15575a026e69c227b92171fee1dbda22ccd90 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 9 Feb 2017 16:28:18 -0500 Subject: [PATCH 007/115] Add option to pick translucent geometry at a performance cost. --- Source/Renderer/PassState.js | 2 + Source/Renderer/RenderState.js | 13 ++++-- Source/Scene/Scene.js | 76 ++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/Source/Renderer/PassState.js b/Source/Renderer/PassState.js index 4a0e5515143a..7f386921f086 100644 --- a/Source/Renderer/PassState.js +++ b/Source/Renderer/PassState.js @@ -56,6 +56,8 @@ define([], function() { * @default undefined */ this.viewport = undefined; + + this.depthMask = undefined; } return PassState; diff --git a/Source/Renderer/RenderState.js b/Source/Renderer/RenderState.js index 93c074526257..4c55f4dcce1b 100644 --- a/Source/Renderer/RenderState.js +++ b/Source/Renderer/RenderState.js @@ -549,8 +549,9 @@ define([ gl.colorMask(colorMask.red, colorMask.green, colorMask.blue, colorMask.alpha); } - function applyDepthMask(gl, renderState) { - gl.depthMask(renderState.depthMask); + function applyDepthMask(gl, renderState, passState) { + var mask = defined(passState.depthMask) ? passState.depthMask : renderState.depthMask; + gl.depthMask(mask); } function applyStencilMask(gl, renderState) { @@ -641,10 +642,10 @@ define([ applyDepthRange(gl, renderState); applyDepthTest(gl, renderState); applyColorMask(gl, renderState); - applyDepthMask(gl, renderState); applyStencilMask(gl, renderState); applyStencilTest(gl, renderState); applySampleCoverage(gl, renderState); + applyDepthMask(gl, renderState, passState); applyScissorTest(gl, renderState, passState); applyBlending(gl, renderState, passState); applyViewport(gl, renderState, passState); @@ -686,9 +687,11 @@ define([ funcs.push(applyColorMask); } + /* if (previousState.depthMask !== nextState.depthMask) { funcs.push(applyDepthMask); } +*/ if (previousState.stencilMask !== nextState.stencilMask) { funcs.push(applyStencilMask); @@ -755,6 +758,10 @@ define([ if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { applyViewport(gl, renderState, passState); } + + if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { + applyDepthMask(gl, renderState, passState); + } }; RenderState.getState = function(renderState) { diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 261ccb8c2c43..be7ed5be77b8 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -28,6 +28,7 @@ define([ '../Core/Matrix4', '../Core/mergeSort', '../Core/Occluder', + '../Core/PixelFormat', '../Core/ShowGeometryInstanceAttribute', '../Core/Transforms', '../Renderer/ClearCommand', @@ -35,10 +36,13 @@ define([ '../Renderer/Context', '../Renderer/ContextLimits', '../Renderer/DrawCommand', + '../Renderer/Framebuffer', '../Renderer/Pass', '../Renderer/PassState', + '../Renderer/PixelDatatype', '../Renderer/ShaderProgram', '../Renderer/ShaderSource', + '../Renderer/Texture', './Camera', './CreditDisplay', './CullingVolume', @@ -96,6 +100,7 @@ define([ Matrix4, mergeSort, Occluder, + PixelFormat, ShowGeometryInstanceAttribute, Transforms, ClearCommand, @@ -103,10 +108,13 @@ define([ Context, ContextLimits, DrawCommand, + Framebuffer, Pass, PassState, + PixelDatatype, ShaderProgram, ShaderSource, + Texture, Camera, CreditDisplay, CullingVolume, @@ -548,6 +556,8 @@ define([ */ this.useDepthPicking = true; + this.pickTranslucentDepth = true; + /** * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. * @type {Number} @@ -2696,6 +2706,69 @@ define([ return object; }; + var scratchPickDepthPassState; + + function renderForPickDepth(scene, drawingBufferPosition) { + var context = scene._context; + var us = context.uniformState; + var frameState = scene._frameState; + + // Update with previous frame's number and time, assuming that render is called before picking. + updateFrameState(scene, frameState.frameNumber, frameState.time); + frameState.cullingVolume = getPickCullingVolume(scene, drawingBufferPosition, 1, 1); + frameState.passes.render = true; + + us.update(frameState); + + var passState = scratchPickDepthPassState; + if (!defined(passState)) { + passState = scratchPickDepthPassState = new PassState(context); + passState.scissorTest = { + enabled : true, + rectangle : new BoundingRectangle() + }; + passState.viewport = new BoundingRectangle(); + passState.depthMask = true; + } + + var width = context.drawingBufferWidth; + var height = context.drawingBufferHeight; + + var framebuffer = scene._pickDepthFramebuffer; + var pickDepthFBWidth = scene._pickDepthFramebufferWidth; + var pickDepthFBHeight = scene._pickDepthFramebufferHeight; + if (!defined(framebuffer) || pickDepthFBWidth !== width || pickDepthFBHeight !== height) { + scene._pickDepthFramebuffer = scene._pickDepthFramebuffer && scene._pickDepthFramebuffer.destroy(); + framebuffer = scene._pickDepthFramebuffer = new Framebuffer({ + context : context, + depthStencilTexture : new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.DEPTH_STENCIL, + pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 + }) + }); + + scene._pickDepthFramebufferWidth = width; + scene._pickDepthFramebufferHeight = height; + } + + + passState.framebuffer = framebuffer; + passState.viewport.width = width; + passState.viewport.height = height; + passState.scissorTest.rectangle.x = drawingBufferPosition.x; + passState.scissorTest.rectangle.y = height - drawingBufferPosition.y; + passState.scissorTest.rectangle.width = 1; + passState.scissorTest.rectangle.height = 1; + + updateAndExecuteCommands(scene, passState, scratchColorZero); + resolveFramebuffers(scene, passState); + + context.endFrame(); + } + var scratchPackedDepth = new Cartesian4(); var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0); @@ -2727,6 +2800,9 @@ define([ var uniformState = context.uniformState; var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); + if (this.pickTranslucentDepth) { + renderForPickDepth(this, drawingBufferPosition); + } drawingBufferPosition.y = this.drawingBufferHeight - drawingBufferPosition.y; var camera = this._camera; From 832b36c5e4821eb9aa2fc0725301d82273933fad Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 9 Feb 2017 16:44:40 -0500 Subject: [PATCH 008/115] Remove commented out code. --- Source/Renderer/RenderState.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Source/Renderer/RenderState.js b/Source/Renderer/RenderState.js index 4c55f4dcce1b..ef1fb165cb02 100644 --- a/Source/Renderer/RenderState.js +++ b/Source/Renderer/RenderState.js @@ -687,12 +687,6 @@ define([ funcs.push(applyColorMask); } - /* - if (previousState.depthMask !== nextState.depthMask) { - funcs.push(applyDepthMask); - } -*/ - if (previousState.stencilMask !== nextState.stencilMask) { funcs.push(applyStencilMask); } From 002e2d94bc9a5efbec5c5a17e2d73d291f0b84d5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Thu, 9 Feb 2017 16:55:18 -0500 Subject: [PATCH 009/115] Fix whitespace. --- Source/Renderer/PassState.js | 2 +- Source/Renderer/RenderState.js | 10 ++-- Source/Scene/Scene.js | 87 +++++++++++++++++----------------- 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/Source/Renderer/PassState.js b/Source/Renderer/PassState.js index 7f386921f086..4b383296407c 100644 --- a/Source/Renderer/PassState.js +++ b/Source/Renderer/PassState.js @@ -57,7 +57,7 @@ define([], function() { */ this.viewport = undefined; - this.depthMask = undefined; + this.depthMask = undefined; } return PassState; diff --git a/Source/Renderer/RenderState.js b/Source/Renderer/RenderState.js index ef1fb165cb02..379106cca0e6 100644 --- a/Source/Renderer/RenderState.js +++ b/Source/Renderer/RenderState.js @@ -550,7 +550,7 @@ define([ } function applyDepthMask(gl, renderState, passState) { - var mask = defined(passState.depthMask) ? passState.depthMask : renderState.depthMask; + var mask = defined(passState.depthMask) ? passState.depthMask : renderState.depthMask; gl.depthMask(mask); } @@ -645,7 +645,7 @@ define([ applyStencilMask(gl, renderState); applyStencilTest(gl, renderState); applySampleCoverage(gl, renderState); - applyDepthMask(gl, renderState, passState); + applyDepthMask(gl, renderState, passState); applyScissorTest(gl, renderState, passState); applyBlending(gl, renderState, passState); applyViewport(gl, renderState, passState); @@ -753,9 +753,9 @@ define([ applyViewport(gl, renderState, passState); } - if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { - applyDepthMask(gl, renderState, passState); - } + if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { + applyDepthMask(gl, renderState, passState); + } }; RenderState.getState = function(renderState) { diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index be7ed5be77b8..02f1ff11421e 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -100,7 +100,7 @@ define([ Matrix4, mergeSort, Occluder, - PixelFormat, + PixelFormat, ShowGeometryInstanceAttribute, Transforms, ClearCommand, @@ -108,13 +108,13 @@ define([ Context, ContextLimits, DrawCommand, - Framebuffer, + Framebuffer, Pass, PassState, - PixelDatatype, + PixelDatatype, ShaderProgram, ShaderSource, - Texture, + Texture, Camera, CreditDisplay, CullingVolume, @@ -556,7 +556,7 @@ define([ */ this.useDepthPicking = true; - this.pickTranslucentDepth = true; + this.pickTranslucentDepth = true; /** * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. @@ -2709,9 +2709,9 @@ define([ var scratchPickDepthPassState; function renderForPickDepth(scene, drawingBufferPosition) { - var context = scene._context; + var context = scene._context; var us = context.uniformState; - var frameState = scene._frameState; + var frameState = scene._frameState; // Update with previous frame's number and time, assuming that render is called before picking. updateFrameState(scene, frameState.frameNumber, frameState.time); @@ -2720,50 +2720,49 @@ define([ us.update(frameState); - var passState = scratchPickDepthPassState; - if (!defined(passState)) { - passState = scratchPickDepthPassState = new PassState(context); + var passState = scratchPickDepthPassState; + if (!defined(passState)) { + passState = scratchPickDepthPassState = new PassState(context); passState.scissorTest = { - enabled : true, - rectangle : new BoundingRectangle() + enabled : true, + rectangle : new BoundingRectangle() }; passState.viewport = new BoundingRectangle(); - passState.depthMask = true; - } + passState.depthMask = true; + } var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; - var framebuffer = scene._pickDepthFramebuffer; - var pickDepthFBWidth = scene._pickDepthFramebufferWidth; - var pickDepthFBHeight = scene._pickDepthFramebufferHeight; - if (!defined(framebuffer) || pickDepthFBWidth !== width || pickDepthFBHeight !== height) { - scene._pickDepthFramebuffer = scene._pickDepthFramebuffer && scene._pickDepthFramebuffer.destroy(); - framebuffer = scene._pickDepthFramebuffer = new Framebuffer({ - context : context, - depthStencilTexture : new Texture({ - context : context, - width : width, - height : height, - pixelFormat : PixelFormat.DEPTH_STENCIL, - pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 - }) - }); - - scene._pickDepthFramebufferWidth = width; - scene._pickDepthFramebufferHeight = height; - } - - - passState.framebuffer = framebuffer; + var framebuffer = scene._pickDepthFramebuffer; + var pickDepthFBWidth = scene._pickDepthFramebufferWidth; + var pickDepthFBHeight = scene._pickDepthFramebufferHeight; + if (!defined(framebuffer) || pickDepthFBWidth !== width || pickDepthFBHeight !== height) { + scene._pickDepthFramebuffer = scene._pickDepthFramebuffer && scene._pickDepthFramebuffer.destroy(); + framebuffer = scene._pickDepthFramebuffer = new Framebuffer({ + context : context, + depthStencilTexture : new Texture({ + context : context, + width : width, + height : height, + pixelFormat : PixelFormat.DEPTH_STENCIL, + pixelDatatype : PixelDatatype.UNSIGNED_INT_24_8 + }) + }); + + scene._pickDepthFramebufferWidth = width; + scene._pickDepthFramebufferHeight = height; + } + + passState.framebuffer = framebuffer; passState.viewport.width = width; passState.viewport.height = height; - passState.scissorTest.rectangle.x = drawingBufferPosition.x; - passState.scissorTest.rectangle.y = height - drawingBufferPosition.y; - passState.scissorTest.rectangle.width = 1; - passState.scissorTest.rectangle.height = 1; + passState.scissorTest.rectangle.x = drawingBufferPosition.x; + passState.scissorTest.rectangle.y = height - drawingBufferPosition.y; + passState.scissorTest.rectangle.width = 1; + passState.scissorTest.rectangle.height = 1; - updateAndExecuteCommands(scene, passState, scratchColorZero); + updateAndExecuteCommands(scene, passState, scratchColorZero); resolveFramebuffers(scene, passState); context.endFrame(); @@ -2800,9 +2799,9 @@ define([ var uniformState = context.uniformState; var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); - if (this.pickTranslucentDepth) { - renderForPickDepth(this, drawingBufferPosition); - } + if (this.pickTranslucentDepth) { + renderForPickDepth(this, drawingBufferPosition); + } drawingBufferPosition.y = this.drawingBufferHeight - drawingBufferPosition.y; var camera = this._camera; From 4e1c97db026a89097f7ca36d138ba70056e5d52c Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Thu, 9 Feb 2017 16:56:00 -0500 Subject: [PATCH 010/115] Added link to guide, and section on building Cesium. --- Documentation/Contributors/README.md | 1 + Documentation/Contributors/VSCodeGuide/README.md | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/Documentation/Contributors/README.md b/Documentation/Contributors/README.md index 11ba10f61036..d783cee68e4a 100644 --- a/Documentation/Contributors/README.md +++ b/Documentation/Contributors/README.md @@ -5,6 +5,7 @@ * **IDEs** - use any IDE you want for Cesium development. Most contributors use WebStorm (commercial) or Eclipse (open source). * [WebStorm Guide](WebStormGuide/README.md) - How to set up WebStorm. * [Eclipse Guide](EclipseGuide/README.md) - How to set up Eclipse. + * [VSCode Guide](VSCodeGuide/README.md) - How to set up VSCode. * [Coding Guide](CodingGuide/README.md) - JavaScript and GLSL coding conventions and best practices for design, maintainability, and performance. * [Testing Guide](TestingGuide/README.md) - How to run the Cesium tests and write awesome tests. * [Documentation Guide](DocumentationGuide/README.md) - How to write great reference documentation. diff --git a/Documentation/Contributors/VSCodeGuide/README.md b/Documentation/Contributors/VSCodeGuide/README.md index ff70035ace8a..679cf8c51b7d 100644 --- a/Documentation/Contributors/VSCodeGuide/README.md +++ b/Documentation/Contributors/VSCodeGuide/README.md @@ -53,3 +53,18 @@ offer the list of npm tasks for you to run. You can also jump to any source file with the same CTRL-P keypress followed by the name of the file. + +## Building Cesium + +Cesium has a number of GLSL shaders and auto-generated files that must be +built before Cesium can be used. The simplest way in VSCode is to type +`CTRL-P` `task build` to trigger a build. + +There is also a `task build-watch`, but this leaves a little spinner running +in the status bar at the bottom, so is not recommended. Instead, you can use +the integrated shell (CTRL-backtick) and type `npm run build-watch` to start +the build watcher task, then use CTRL-SHIFT-backtick to open up an additional +integrated shell that is available for separate commands while the build watcher +task is still running. Keep in mind that this will quietly terminate when +you quit VSCode, so should be restarted manually on next launch. + From 3c8543d611cac5799a0d29152b0a32a4ef1ede6f Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Thu, 9 Feb 2017 16:11:34 -0500 Subject: [PATCH 011/115] add support to check children bounds for visibility before selecting a tile --- Source/Scene/Cesium3DTile.js | 11 ++ Source/Scene/Cesium3DTileOptimizations.js | 125 ++++++++++++++++++++++ Source/Scene/Cesium3DTileset.js | 120 +++++++++++++++------ 3 files changed, 226 insertions(+), 30 deletions(-) create mode 100644 Source/Scene/Cesium3DTileOptimizations.js diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index dd2e7436aa94..26c6bb4ac4d7 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -5,6 +5,7 @@ define([ '../Core/Cartesian3', '../Core/Color', '../Core/ColorGeometryInstanceAttribute', + '../Core/clone', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', @@ -38,6 +39,7 @@ define([ Cartesian3, Color, ColorGeometryInstanceAttribute, + clone, defaultValue, defined, defineProperties, @@ -305,6 +307,13 @@ define([ * @private */ this.visibilityPlaneMask = true; + + /** + * Flag to mark children visibility + * + * @private + */ + this.childrenVisibility = 1; /** * The last frame number the tile was selected in. @@ -329,6 +338,8 @@ define([ this._debugViewerRequestVolume = undefined; this._debugColor = new Color.fromRandom({ alpha : 1.0 }); this._debugColorizeTiles = false; + + this._optimizations = clone(tileset._optimizations); } defineProperties(Cesium3DTile.prototype, { diff --git a/Source/Scene/Cesium3DTileOptimizations.js b/Source/Scene/Cesium3DTileOptimizations.js new file mode 100644 index 000000000000..d41a3ba532aa --- /dev/null +++ b/Source/Scene/Cesium3DTileOptimizations.js @@ -0,0 +1,125 @@ +/*global define*/ +define([ + '../Core/Cartesian3', + '../Core/defaultValue', + '../Core/freezeObject', + './TileOrientedBoundingBox', + './TileBoundingRegion' + ], function( + Cartesian3, + defaultValue, + freezeObject, + TileOrientedBoundingBox, + TileBoundingRegion) { + 'use strict'; + + /** + * @alias Cesium3DTileOptimizationFlag + * + * Flag denoting support for a 3D Tiles optimization + */ + var Cesium3DTileOptimizationFlag = { + UNSUPPORTED: 0, + SUPPORTED: 1, + INDETERMINATE: -1 + }; + + /** + * Defines optional optimization flags for a {@link Cesium3DTileset}. + * Optimizations marked as Cesium3DTileOptimizations.Flags.SUPPORTED or Cesium3DTileOptimizations.Flags.UNSUPPORTED + * will not be evaluated at runtime + * + * @alias Cesium3DTileOptimizations + * @constructor + * + * @example + * var tileset = new Cesium.Cesium3DTileset({ + * url: ..., + * optimizations: new Cesium.Cesium3DTileOptimizations({ + * childrenWithinParent: Cesium.Cesium3DTileOptimizations.Flags.SUPPORTED + * }) + * }); + */ + function Cesium3DTileOptimizations(options) { + options = defaultValue(options, defaultValue.EMPTY_OBJECT); + + /** + * Denotes support for if the childrenWithinParent optimization is supported. This is used to more tightly cull tilesets if children bounds are + * fully contained within the parent. + * + * @type {Cesium3DTileOptimizationFlag} + */ + this.childrenWithinParent = defaultValue(options.childrenWithinParent, Cesium3DTileOptimizations.Flags.INDETERMINATE); + } + + var scratchAxis = new Cartesian3(); + + /** + * Checks and optinonally evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if children bounds are + * fully contained within the parent. + * + * @param {Cesium3DTile} tile The tile to check. + * @param {Boolean} [evaluate=false] Whether to evaluate support if support for the childrenWithinParent optimization is Cesium3DTileOptimizations.INDETERMINATE + * @param {Boolean} [force=false] Whether to always evaluate support for the childrenWithinParent optimization + * @returns {Boolean} Whether the childrenWithinParent optimization is supported. + */ + Cesium3DTileOptimizations.prototype.checkChildrenWithinParent = function(tile, evaluate, force) { + evaluate = defaultValue(evaluate, false); + force = defaultValue(force, false); + + if ((this.childrenWithinParent === Cesium3DTileOptimizations.Flags.INDETERMINATE && evaluate) || force) { + var children = tile.children; + var length = children.length; + var boundingVolume = tile._boundingVolume; + if (boundingVolume instanceof TileOrientedBoundingBox || boundingVolume instanceof TileBoundingRegion) { + var orientedBoundingBox = boundingVolume._orientedBoundingBox; + this.childrenWithinParent = Cesium3DTileOptimizations.Flags.SUPPORTED; + for (var i = 0; i < length; ++i) { + var child = children[i]; + var childBoundingVolume = child._boundingVolume; + if (childBoundingVolume instanceof TileOrientedBoundingBox || childBoundingVolume instanceof TileBoundingRegion) { + var childOrientedBoundingBox = childBoundingVolume._orientedBoundingBox; + var axis = Cartesian3.subtract(childOrientedBoundingBox.center, orientedBoundingBox.center, scratchAxis); + var axisLength = Cartesian3.magnitude(axis); + Cartesian3.divideByScalar(axis, axisLength, axis); + + var proj1 = Math.abs(orientedBoundingBox.halfAxes[0] * axis.x) + + Math.abs(orientedBoundingBox.halfAxes[1] * axis.y) + + Math.abs(orientedBoundingBox.halfAxes[2] * axis.z) + + Math.abs(orientedBoundingBox.halfAxes[3] * axis.x) + + Math.abs(orientedBoundingBox.halfAxes[4] * axis.y) + + Math.abs(orientedBoundingBox.halfAxes[5] * axis.z) + + Math.abs(orientedBoundingBox.halfAxes[6] * axis.x) + + Math.abs(orientedBoundingBox.halfAxes[7] * axis.y) + + Math.abs(orientedBoundingBox.halfAxes[8] * axis.z); + + var proj2 = Math.abs(childOrientedBoundingBox.halfAxes[0] * axis.x) + + Math.abs(childOrientedBoundingBox.halfAxes[1] * axis.y) + + Math.abs(childOrientedBoundingBox.halfAxes[2] * axis.z) + + Math.abs(childOrientedBoundingBox.halfAxes[3] * axis.x) + + Math.abs(childOrientedBoundingBox.halfAxes[4] * axis.y) + + Math.abs(childOrientedBoundingBox.halfAxes[5] * axis.z) + + Math.abs(childOrientedBoundingBox.halfAxes[6] * axis.x) + + Math.abs(childOrientedBoundingBox.halfAxes[7] * axis.y) + + Math.abs(childOrientedBoundingBox.halfAxes[8] * axis.z); + + if (proj1 <= proj2 + axisLength) { + this.childrenWithinParent = Cesium3DTileOptimizations.Flags.UNSUPPORTED; + break; + } + + } else { + this.childrenWithinParent = Cesium3DTileOptimizations.Flags.UNSUPPORTED; + break; + } + } + } + } + + return this.childrenWithinParent === Cesium3DTileOptimizations.Flags.SUPPORTED ? true : false; + } + + Cesium3DTileOptimizations.Flags = freezeObject(Cesium3DTileOptimizationFlag) + + return Cesium3DTileOptimizations; +}); diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 21543fccd1dd..3858f519327d 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -3,6 +3,7 @@ define([ '../Core/Cartesian3', '../Core/Cartographic', '../Core/Color', + '../Core/clone', '../Core/defaultValue', '../Core/defined', '../Core/defineProperties', @@ -26,6 +27,7 @@ define([ '../ThirdParty/when', './Cesium3DTile', './Cesium3DTileColorBlendMode', + './Cesium3DTileOptimizations', './Cesium3DTileRefine', './Cesium3DTileStyleEngine', './CullingVolume', @@ -39,6 +41,7 @@ define([ Cartesian3, Cartographic, Color, + clone, defaultValue, defined, defineProperties, @@ -62,6 +65,7 @@ define([ when, Cesium3DTile, Cesium3DTileColorBlendMode, + Cesium3DTileOptimizations, Cesium3DTileRefine, Cesium3DTileStyleEngine, CullingVolume, @@ -270,7 +274,8 @@ define([ lastColor : new Cesium3DTilesetStatistics(), lastPick : new Cesium3DTilesetStatistics() }; - + + this._optimizations = defaultValue(options.optimizations, new Cesium3DTileOptimizations()); this._tilesLoaded = false; /** @@ -822,6 +827,12 @@ define([ get : function() { return this._statistics; } + }, + + optimizations : { + get : function() { + return this._optimizations; + } } }); @@ -1154,6 +1165,46 @@ define([ var scratchStack = []; var scratchRefiningTiles = []; + var ChildrenVisibilityFlags = { + NONE: 0x0, + VISIBLE: 0x1, + IN_REQUEST_VOLUME: 0x2, + VISIBLE_IN_REQUEST_VOLUME: 0x4 + }; + + function computeChildrenVisibility(tile, frameState, checkViewerRequestVolume) { + var flag = ChildrenVisibilityFlags.NONE; + var children = tile.children; + var childrenLength = children.length; + var visibilityPlaneMask = tile.visibilityPlaneMask; + for (var k = 0; k < childrenLength; ++k) { + var child = children[k]; + + var visibilityMask = child.visibility(frameState, visibilityPlaneMask); + + if (isVisible(visibilityMask)) { + flag |= ChildrenVisibilityFlags.VISIBLE; + } + + if (checkViewerRequestVolume) { + if (!child.insideViewerRequestVolume(frameState)) { + visibilityMask = CullingVolume.MASK_OUTSIDE; + } else { + flag |= ChildrenVisibilityFlags.IN_REQUEST_VOLUME; + if (isVisible(visibilityMask)) { + flag |= ChildrenVisibilityFlags.VISIBLE_IN_REQUEST_VOLUME; + } + } + } + + child.visibilityPlaneMask = visibilityMask + } + + tile.childrenVisibility = flag; + + return flag; + } + function selectTiles(tileset, frameState, outOfCore) { if (tileset.debugFreezeFrame) { return; @@ -1285,11 +1336,21 @@ define([ // With replacement refinement, if the tile's SSE // is not sufficient, its children (or ancestors) are // rendered instead + var useChildrenBoundUnion = t._optimizations.checkChildrenWithinParent(t, true); + var childrenVisibility; + if ((sse <= maximumScreenSpaceError) || (childrenLength === 0)) { // This tile meets the SSE so add its commands. // Select tile if it's a leaf (childrenLength === 0) - selectTile(tileset, t, fullyVisible, frameState); + if (useChildrenBoundUnion) { + childrenVisibility = computeChildrenVisibility(t, frameState, false); + if ((childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || childrenLength === 0) { + selectTile(tileset, t, fullyVisible, frameState); + } + } else { + selectTile(tileset, t, fullyVisible, frameState); + } } else if (!tileset._refineToVisible) { // Tile does not meet SSE. // Refine when all children (visible or not) are loaded. @@ -1311,37 +1372,34 @@ define([ } if (!allChildrenLoaded) { - // Tile does not meet SSE. Add its commands since it is the best we have and request its children. - selectTile(tileset, t, fullyVisible, frameState); + childrenVisibility = computeChildrenVisibility(t, frameState, false); + if (!useChildrenBoundUnion || (childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || childrenLength === 0) { + // Tile does not meet SSE. Add its commands since it is the best we have and request its children. + selectTile(tileset, t, fullyVisible, frameState); - if (outOfCore) { - for (k = 0; (k < childrenLength) && t.canRequestContent(); ++k) { - child = children[k]; - // PERFORMANCE_IDEA: we could spin a bit less CPU here by keeping separate lists for unloaded/ready children. - if (child.contentUnloaded) { - requestContent(tileset, child, outOfCore); - } else { - // Touch loaded child even though it is not selected this frame since - // we want to keep it in the cache for when all children are loaded - // and this tile can refine to them. - touch(tileset, child, outOfCore); + if (outOfCore) { + for (k = 0; (k < childrenLength) && t.canRequestContent(); ++k) { + child = children[k]; + // PERFORMANCE_IDEA: we could spin a bit less CPU here by keeping separate lists for unloaded/ready children. + if (child.contentUnloaded) { + requestContent(tileset, child, outOfCore); + } else { + // Touch loaded child even though it is not selected this frame since + // we want to keep it in the cache for when all children are loaded + // and this tile can refine to them. + touch(tileset, child, outOfCore); + } } } } } else { // Tile does not meet SSE and its children are loaded. Refine to them in front-to-back order. - var anyChildrenVisible = false; + childrenVisibility = computeChildrenVisibility(t, frameState, true); for (k = 0; k < childrenLength; ++k) { child = children[k]; - if (child.insideViewerRequestVolume(frameState)) { - child.visibilityPlaneMask = child.visibility(frameState, visibilityPlaneMask); - } else { - child.visibilityPlaneMask = CullingVolume.MASK_OUTSIDE; - } if (isVisible(child.visibilityPlaneMask)) { stack.push(child); - anyChildrenVisible = true; } else { // Touch the child tile even if it is not visible. Since replacement refinement // requires all child tiles to be loaded to refine to them, we want to keep it in the cache. @@ -1349,12 +1407,12 @@ define([ } } - if (anyChildrenVisible) { + if (childrenVisibility & ChildrenVisibilityFlags.VISIBLE_IN_REQUEST_VOLUME) { t.replaced = true; if (defined(t.descendantsWithContent)) { scratchRefiningTiles.push(t); } - } else { + } else if (!useChildrenBoundUnion || (childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || childrenLength === 0) { // Even though the children are all loaded they may not be visible if the camera // is not inside their request volumes. selectTile(tileset, t, fullyVisible, frameState); @@ -1366,16 +1424,17 @@ define([ // Get visibility for all children. Check if any visible children are not loaded. // PERFORMANCE_IDEA: exploit temporal coherence to avoid checking visibility every frame + updateTransforms(children, t.computedTransform); + childrenVisibility = computeChildrenVisibility(t, frameState, true); + + if (useChildrenBoundUnion && childrenVisibility === ChildrenVisibilityFlags.NONE && childrenLength !== 0) { + continue; + } + var allVisibleChildrenLoaded = true; var someVisibleChildrenLoaded = false; for (k = 0; k < childrenLength; ++k) { child = children[k]; - child.updateTransform(t.computedTransform); - if (child.insideViewerRequestVolume(frameState)) { - child.visibilityPlaneMask = child.visibility(frameState, visibilityPlaneMask); - } else { - child.visibilityPlaneMask = CullingVolume.MASK_OUTSIDE; - } if (isVisible(child.visibilityPlaneMask)) { if (child.contentReady) { someVisibleChildrenLoaded = true; @@ -1461,6 +1520,7 @@ define([ for (j = 0; j < descendantsLength; ++j) { descendant = refiningTile.descendantsWithContent[j]; if (!descendant.selected && !descendant.replaced && + ((descendant.childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || descendant.children.length === 0) && (frameState.cullingVolume.computeVisibility(descendant.contentBoundingVolume) !== Intersect.OUTSIDE)) { refinable = false; break; From e81d8c5b849d4babd529df7aee5dd015f3b82cc7 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 10 Feb 2017 13:03:57 -0500 Subject: [PATCH 012/115] Add support for picking depth in CV. --- Apps/Sandcastle/gallery/Picking.html | 5 ++- Source/Scene/Scene.js | 40 ++++++++++++++------- Source/Scene/ScreenSpaceCameraController.js | 2 +- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/Apps/Sandcastle/gallery/Picking.html b/Apps/Sandcastle/gallery/Picking.html index 00e82620e44f..10017c3f0721 100644 --- a/Apps/Sandcastle/gallery/Picking.html +++ b/Apps/Sandcastle/gallery/Picking.html @@ -184,7 +184,7 @@ var scene = viewer.scene; var pickedObject = scene.pick(movement.endPosition); if (scene.pickPositionSupported && Cesium.defined(pickedObject) && pickedObject.id === modelEntity) { - if (scene.mode === Cesium.SceneMode.SCENE3D) { + if (scene.mode !== Cesium.SceneMode.SCENE2D || scene.mode !== Cesium.SceneMode.MORPHING) { var cartesian = viewer.scene.pickPosition(movement.endPosition); if (Cesium.defined(cartesian)) { @@ -200,8 +200,7 @@ '\nLat: ' + (' ' + latitudeString).slice(-7) + '\u00B0' + '\nAlt: ' + (' ' + heightString).slice(-7) + 'm'; - var camera = scene.camera; - labelEntity.label.eyeOffset = new Cesium.Cartesian3(0.0, 0.0, camera.frustum.near * 1.5 - Cesium.Cartesian3.distance(cartesian, camera.position)); + labelEntity.label.eyeOffset = new Cesium.Cartesian3(0.0, 0.0, -cartographic.height); foundPosition = true; } diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 261ccb8c2c43..03ca606432f5 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -2243,7 +2243,7 @@ define([ if (defined(scene._debugFrustumPlanes)) { scene._debugFrustumPlanes.update(frameState); - } + } } function updateShadowMaps(scene) { @@ -2699,17 +2699,7 @@ define([ var scratchPackedDepth = new Cartesian4(); var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0); - /** - * Returns the cartesian position reconstructed from the depth buffer and window position. - * - * @param {Cartesian2} windowPosition Window coordinates to perform picking on. - * @param {Cartesian3} [result] The object on which to restore the result. - * @returns {Cartesian3} The cartesian position. - * - * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. - * @exception {DeveloperError} 2D is not supported. An orthographic projection matrix is not invertible. - */ - Scene.prototype.pickPosition = function(windowPosition, result) { + Scene.prototype._pickPosition = function(windowPosition, result) { if (!this.useDepthPicking) { return undefined; } @@ -2771,6 +2761,32 @@ define([ return undefined; }; + var scratchPickPositionCartographic = new Cartographic(); + + /** + * Returns the cartesian position reconstructed from the depth buffer and window position. + * + * @param {Cartesian2} windowPosition Window coordinates to perform picking on. + * @param {Cartesian3} [result] The object on which to restore the result. + * @returns {Cartesian3} The cartesian position. + * + * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. + * @exception {DeveloperError} 2D is not supported. An orthographic projection matrix is not invertible. + */ + Scene.prototype.pickPosition = function(windowPosition, result) { + result = this._pickPosition(windowPosition, result); + if (defined(result) && this.mode !== SceneMode.SCENE3D) { + Cartesian3.fromElements(result.y, result.z, result.x, result); + + var projection = this.mapProjection; + var ellipsoid = projection.ellipsoid; + + var cart = projection.unproject(result, scratchPickPositionCartographic); + ellipsoid.cartographicToCartesian(cart, result); + } + return result; + }; + /** * Returns a list of objects, each containing a `primitive` property, for all primitives at * a particular window coordinate position. Other properties may also be set depending on the diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index 3e3a7346103e..b8212295359b 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -806,7 +806,7 @@ define([ var depthIntersection; if (scene.pickPositionSupported) { - depthIntersection = scene.pickPosition(mousePosition, scratchDepthIntersection); + depthIntersection = scene._pickPosition(mousePosition, scratchDepthIntersection); } var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay); From 9ba9db3ac4a0fa7035a607e0ccb292bcfbbb51b3 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 10 Feb 2017 14:35:31 -0500 Subject: [PATCH 013/115] Add support for picking depth in 2D. --- Apps/Sandcastle/gallery/Picking.html | 14 +++++--------- Source/Scene/Scene.js | 6 ++---- Source/Scene/SceneTransforms.js | 23 ++++++++++++++++++----- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Apps/Sandcastle/gallery/Picking.html b/Apps/Sandcastle/gallery/Picking.html index 10017c3f0721..a976f27363ac 100644 --- a/Apps/Sandcastle/gallery/Picking.html +++ b/Apps/Sandcastle/gallery/Picking.html @@ -174,17 +174,16 @@ } }); - var sceneModeWarningPosted = false; - // Mouse over the globe to see the cartographic position handler = new Cesium.ScreenSpaceEventHandler(scene.canvas); handler.setInputAction(function(movement) { + var foundPosition = false; var scene = viewer.scene; - var pickedObject = scene.pick(movement.endPosition); - if (scene.pickPositionSupported && Cesium.defined(pickedObject) && pickedObject.id === modelEntity) { - if (scene.mode !== Cesium.SceneMode.SCENE2D || scene.mode !== Cesium.SceneMode.MORPHING) { + if (scene.mode !== Cesium.SceneMode.MORPHING) { + var pickedObject = scene.pick(movement.endPosition); + if (scene.pickPositionSupported && Cesium.defined(pickedObject) && pickedObject.id === modelEntity) { var cartesian = viewer.scene.pickPosition(movement.endPosition); if (Cesium.defined(cartesian)) { @@ -200,13 +199,10 @@ '\nLat: ' + (' ' + latitudeString).slice(-7) + '\u00B0' + '\nAlt: ' + (' ' + heightString).slice(-7) + 'm'; - labelEntity.label.eyeOffset = new Cesium.Cartesian3(0.0, 0.0, -cartographic.height); + labelEntity.label.eyeOffset = new Cesium.Cartesian3(0.0, 0.0, -cartographic.height * (scene.mode === Cesium.SceneMode.SCENE2D ? 1.5 : 1.0)); foundPosition = true; } - } else if (!sceneModeWarningPosted) { - sceneModeWarningPosted = true; - console.log("pickPosition is currently only supported in 3D mode."); } } diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 03ca606432f5..4a9f39546d1f 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -2728,9 +2728,7 @@ define([ } else if (defined(camera.frustum.infiniteProjectionMatrix)){ frustum = camera.frustum.clone(scratchPerspectiveOffCenterFrustum); } else { - //>>includeStart('debug', pragmas.debug); - throw new DeveloperError('2D is not supported. An orthographic projection matrix is not invertible.'); - //>>includeEnd('debug'); + frustum = camera.frustum.clone(scratchOrthographicFrustum); } var numFrustums = this.numberOfFrustums; @@ -2750,7 +2748,7 @@ define([ if (depth > 0.0 && depth < 1.0) { var renderedFrustum = this._frustumCommandsList[i]; - frustum.near = renderedFrustum.near * (i !== 0 ? OPAQUE_FRUSTUM_NEAR_OFFSET : 1.0); + frustum.near = renderedFrustum.near * (i !== 0 && this._mode !== SceneMode.SCENE2D ? OPAQUE_FRUSTUM_NEAR_OFFSET : 1.0); frustum.far = renderedFrustum.far; uniformState.updateFrustum(frustum); diff --git a/Source/Scene/SceneTransforms.js b/Source/Scene/SceneTransforms.js index 8da7f9fbb523..afe452a05399 100644 --- a/Source/Scene/SceneTransforms.js +++ b/Source/Scene/SceneTransforms.js @@ -320,11 +320,24 @@ define([ ndc.z = (depth * 2.0) - 1.0; ndc.w = 1.0; - var worldCoords = Matrix4.multiplyByVector(uniformState.inverseViewProjection, ndc, scratchWorldCoords); - - // Reverse perspective divide - var w = 1.0 / worldCoords.w; - Cartesian3.multiplyByScalar(worldCoords, w, worldCoords); + var worldCoords; + var frustum = scene.camera.frustum; + if (!defined(frustum.fovy)) { + var currentFrustum = uniformState.currentFrustum; + worldCoords = scratchWorldCoords; + worldCoords.x = (ndc.x * (frustum.right - frustum.left) + frustum.left + frustum.right) * 0.5; + worldCoords.y = (ndc.y * (frustum.top - frustum.bottom) + frustum.bottom + frustum.top) * 0.5; + worldCoords.z = (ndc.z * (currentFrustum.x - currentFrustum.y) - currentFrustum.x - currentFrustum.y) * 0.5; + worldCoords.w = 1.0; + + worldCoords = Matrix4.multiplyByVector(uniformState.inverseView, worldCoords, worldCoords); + } else { + worldCoords = Matrix4.multiplyByVector(uniformState.inverseViewProjection, ndc, scratchWorldCoords); + + // Reverse perspective divide + var w = 1.0 / worldCoords.w; + Cartesian3.multiplyByScalar(worldCoords, w, worldCoords); + } return Cartesian3.fromCartesian4(worldCoords, result); }; From 721ca186e27956e8870248bae0cad1b21e505500 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Fri, 10 Feb 2017 15:25:02 -0500 Subject: [PATCH 014/115] check useChildrenBoundUnion before computing visibility --- Source/Scene/Cesium3DTileset.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 3858f519327d..355d767acb4a 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -1372,7 +1372,9 @@ define([ } if (!allChildrenLoaded) { - childrenVisibility = computeChildrenVisibility(t, frameState, false); + if (useChildrenBoundUnion) { + childrenVisibility = computeChildrenVisibility(t, frameState, false); + } if (!useChildrenBoundUnion || (childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || childrenLength === 0) { // Tile does not meet SSE. Add its commands since it is the best we have and request its children. selectTile(tileset, t, fullyVisible, frameState); From 89f09e2bef89b29e182e984851ceda12fa6e1b95 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 10 Feb 2017 15:49:33 -0500 Subject: [PATCH 015/115] Fix depth picking in 2d for certain views. --- Source/Scene/Scene.js | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 4a9f39546d1f..840c842c8a89 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -2748,11 +2748,28 @@ define([ if (depth > 0.0 && depth < 1.0) { var renderedFrustum = this._frustumCommandsList[i]; - frustum.near = renderedFrustum.near * (i !== 0 && this._mode !== SceneMode.SCENE2D ? OPAQUE_FRUSTUM_NEAR_OFFSET : 1.0); - frustum.far = renderedFrustum.far; - uniformState.updateFrustum(frustum); + var height2D; + if (this.mode === SceneMode.SCENE2D) { + height2D = camera.position.z; + camera.position.z = height2D - renderedFrustum.near + 1.0; + frustum.far = Math.max(1.0, renderedFrustum.far - renderedFrustum.near); + frustum.near = 1.0; + uniformState.update(this.frameState); + uniformState.updateFrustum(frustum); + } else { + frustum.near = renderedFrustum.near * (i !== 0 ? OPAQUE_FRUSTUM_NEAR_OFFSET : 1.0); + frustum.far = renderedFrustum.far; + uniformState.updateFrustum(frustum); + } + + result = SceneTransforms.drawingBufferToWgs84Coordinates(this, drawingBufferPosition, depth, result); + + if (this.mode === SceneMode.SCENE2D) { + camera.position.z = height2D; + uniformState.update(this.frameState); + } - return SceneTransforms.drawingBufferToWgs84Coordinates(this, drawingBufferPosition, depth, result); + return result; } } From 5e93340406556a70d0b9fd4fe489ad17f2e1b461 Mon Sep 17 00:00:00 2001 From: Sarah Chow Date: Sat, 11 Feb 2017 13:28:09 -0800 Subject: [PATCH 016/115] Scrub old demos --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index d75994100c97..fde514db7b8a 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,6 @@ We appreciate attribution by including the Cesium logo and link in your app.       -        @@ -134,7 +133,6 @@ We appreciate attribution by including the Cesium logo and link in your app.       -        @@ -143,7 +141,6 @@ We appreciate attribution by including the Cesium logo and link in your app.       -        From 40d67378d8045f76350c8c4f12aaf91266b03567 Mon Sep 17 00:00:00 2001 From: Sarah Chow Date: Sat, 11 Feb 2017 13:35:01 -0800 Subject: [PATCH 017/115] New demos --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fde514db7b8a..7b1531411335 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,10 @@ We appreciate attribution by including the Cesium logo and link in your app. ### Demos ###

+  +  +  +        From bd9892a3eee25481fa148f547a0db9ca0dc77c17 Mon Sep 17 00:00:00 2001 From: Scott Hunter Date: Mon, 13 Feb 2017 10:49:59 -0500 Subject: [PATCH 018/115] Replace npm tasks with gulp tasks. Mark build-watch as a background task. --- .vscode/tasks.json | 131 ++++++--------------------------------------- 1 file changed, 16 insertions(+), 115 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e8097e4bb634..d36220289c4e 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,131 +1,32 @@ { - // To launch one of these tasks in Visual Studio Code, - // press CTRL+P and type "task ", then select a task - // from the auto-complete list. - // // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "0.1.0", - "command": "npm", + "command": "gulp", "isShellCommand": true, - "showOutput": "always", - "suppressTaskName": true, + "args": [ + "--no-color" + ], "tasks": [ - { - "taskName": "start", - "args": ["run", "start"] - }, - { - "taskName": "startPublic", - "args": ["run", "startPublic"] - }, { "taskName": "build", - "args": ["run", "build"] - }, - { - "taskName": "build-watch", - "args": ["run", "build-watch"] - }, - { - "taskName": "buildApps", - "args": ["run", "buildApps"] - }, - { - "taskName": "clean", - "args": ["run", "clean"] - }, - { - "taskName": "cloc", - "args": ["run", "cloc"] - }, - { - "taskName": "combine", - "args": ["run", "combine"] - }, - { - "taskName": "combineRelease", - "args": ["run", "combineRelease"] - }, - { - "taskName": "requirejs", - "args": ["run", "requirejs"] - }, - { - "taskName": "generateDocumentation", - "args": ["run", "generateDocumentation"] - }, - { - "taskName": "instrumentForCoverage", - "args": ["run", "instrumentForCoverage"] - }, - { - "taskName": "jsHint", - "args": ["run", "jsHint"] - }, - { - "taskName": "jsHint-watch", - "args": ["run", "jsHint-watch"] - }, - { - "taskName": "makeZipFile", - "args": ["run", "makeZipFile"] - }, - { - "taskName": "minify", - "args": ["run", "minify"] - }, - { - "taskName": "minifyRelease", - "args": ["run", "minifyRelease"] - }, - { - "taskName": "release", - "args": ["run", "release"] + "args": [], + "isBuildCommand": true, + "isWatching": false, + "problemMatcher": [ + "$lessCompile", + "$tsc", + "$jshint" + ] }, { "taskName": "test", - "args": ["run", "test"] - }, - { - "taskName": "test-all", - "args": ["run", "test-all"] - }, - { - "taskName": "test-webgl", - "args": ["run", "test-webgl"] - }, - { - "taskName": "test-non-webgl", - "args": ["run", "test-non-webgl"] + "args": [], + "isTestCommand": true }, { - "taskName": "test-webgl-validation", - "args": ["run", "test-webgl-validation"] - }, - { - "taskName": "test-release", - "args": ["run", "test-release"] - }, - { - "taskName": "generateStubs", - "args": ["run", "generateStubs"] - }, - { - "taskName": "sortRequires", - "args": ["run", "sortRequires"] - }, - { - "taskName": "deploy-s3", - "args": ["run", "deploy-s3"] - }, - { - "taskName": "deploy-status", - "args": ["run", "deploy-status"] - }, - { - "taskName": "deploy-set-version", - "args": ["run", "deploy-set-version"] + "taskName": "build-watch", + "isWatching": true } ] } From 7b1b6b9d08bc8720a3c226c57cea5619ae48c5f7 Mon Sep 17 00:00:00 2001 From: glee2244 Date: Mon, 13 Feb 2017 11:37:23 -0500 Subject: [PATCH 019/115] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0dbcdcd5c77b..def86799ba00 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -128,3 +128,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu * [Jane Minghui Guo](https://github.com/Jane-Of-Art) * [Prasanna Natarajan](https://github.com/PrasannaNatarajan) * [Joseph Klinger](https://github.com/klingerj) +* [Grace Lee](https://github.com/glee2244) From 816a6463434fe4f35e3ee3588b816ab1f68fc851 Mon Sep 17 00:00:00 2001 From: Ed Mackey Date: Mon, 13 Feb 2017 12:11:54 -0500 Subject: [PATCH 020/115] Update `isWatching` to `isBackground`, update setup guide. --- .vscode/tasks.json | 4 +-- .../Contributors/VSCodeGuide/README.md | 28 +++++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d36220289c4e..4befb021f0ca 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -12,7 +12,7 @@ "taskName": "build", "args": [], "isBuildCommand": true, - "isWatching": false, + "isBackground": false, "problemMatcher": [ "$lessCompile", "$tsc", @@ -26,7 +26,7 @@ }, { "taskName": "build-watch", - "isWatching": true + "isBackground": true } ] } diff --git a/Documentation/Contributors/VSCodeGuide/README.md b/Documentation/Contributors/VSCodeGuide/README.md index 679cf8c51b7d..61cedd85f973 100644 --- a/Documentation/Contributors/VSCodeGuide/README.md +++ b/Documentation/Contributors/VSCodeGuide/README.md @@ -2,7 +2,13 @@ 1. Install [VSCode](https://code.visualstudio.com/). -2. Click `File -> Open Folder...` and open the Cesium root folder. +2. If you haven't already, install `gulp-cli` globally, with +`npm install -g gulp-cli` from a bash prompt. This does not require +administrative rights, and places a `gulp` shim into your path that will +invoke a copy of gulp from the local project folder. This is needed for +VSCode's build tasks to work with Cesium. + +3. Click `File -> Open Folder...` and open the Cesium root folder. ## Shell Integration (optional) @@ -49,7 +55,8 @@ syntax highlighting for Cesium's shader code. You can launch any of Cesium's npm tasks from within VSCode by pressing CTRL-P and typing `task ` (with a trailing space). Autocomplete will -offer the list of npm tasks for you to run. +offer the list of npm tasks for you to run. The first time you do this, +allow a moment for it to read the available tasks from the gulpfile. You can also jump to any source file with the same CTRL-P keypress followed by the name of the file. @@ -58,13 +65,12 @@ followed by the name of the file. Cesium has a number of GLSL shaders and auto-generated files that must be built before Cesium can be used. The simplest way in VSCode is to type -`CTRL-P` `task build` to trigger a build. - -There is also a `task build-watch`, but this leaves a little spinner running -in the status bar at the bottom, so is not recommended. Instead, you can use -the integrated shell (CTRL-backtick) and type `npm run build-watch` to start -the build watcher task, then use CTRL-SHIFT-backtick to open up an additional -integrated shell that is available for separate commands while the build watcher -task is still running. Keep in mind that this will quietly terminate when -you quit VSCode, so should be restarted manually on next launch. +`CTRL-P` `task build` to trigger a single build. +You can also start the build watcher with `CTRL-P` `task build-watch`. This +leaves a watcher running until you exit VSCode, that will automatically +update any shaders or auto-generated files to reflect changes to Cesium as +you save them. + +Keep in mind that `build-watch` will quietly terminate when +you quit VSCode, so should be restarted manually on next launch. From c956707b486113225fb883b46eda3512de7a5827 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 13 Feb 2017 14:58:07 -0500 Subject: [PATCH 021/115] Updates from review. --- Source/Scene/Scene.js | 23 ++++++++++++++++++--- Source/Scene/ScreenSpaceCameraController.js | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 840c842c8a89..d5a2121b088c 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -2699,7 +2699,20 @@ define([ var scratchPackedDepth = new Cartesian4(); var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0); - Scene.prototype._pickPosition = function(windowPosition, result) { + /** + * Returns the cartesian position reconstructed from the depth buffer and window position. + * The returned position is in world coordinates. Used internally by camera functions to + * prevent conversion to projected 2D coordinates and then back. + * + * @private + * + * @param {Cartesian2} windowPosition Window coordinates to perform picking on. + * @param {Cartesian3} [result] The object on which to restore the result. + * @returns {Cartesian3} The cartesian position in world coordinates. + * + * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. + */ + Scene.prototype.pickPositionWorldCoordinates = function(windowPosition, result) { if (!this.useDepthPicking) { return undefined; } @@ -2780,16 +2793,20 @@ define([ /** * Returns the cartesian position reconstructed from the depth buffer and window position. + *

+ * The position reconstructed from the depth buffer in 2D may be slightly different from those + * reconstructed in 3D and Columbus view. This is caused by the difference in the distribution + * of depth values of perspective and orthographic projection. + *

* * @param {Cartesian2} windowPosition Window coordinates to perform picking on. * @param {Cartesian3} [result] The object on which to restore the result. * @returns {Cartesian3} The cartesian position. * * @exception {DeveloperError} Picking from the depth buffer is not supported. Check pickPositionSupported. - * @exception {DeveloperError} 2D is not supported. An orthographic projection matrix is not invertible. */ Scene.prototype.pickPosition = function(windowPosition, result) { - result = this._pickPosition(windowPosition, result); + result = this.pickPositionWorldCoordinates(windowPosition, result); if (defined(result) && this.mode !== SceneMode.SCENE3D) { Cartesian3.fromElements(result.y, result.z, result.x, result); diff --git a/Source/Scene/ScreenSpaceCameraController.js b/Source/Scene/ScreenSpaceCameraController.js index b8212295359b..3d6e974b3ebc 100644 --- a/Source/Scene/ScreenSpaceCameraController.js +++ b/Source/Scene/ScreenSpaceCameraController.js @@ -806,7 +806,7 @@ define([ var depthIntersection; if (scene.pickPositionSupported) { - depthIntersection = scene._pickPosition(mousePosition, scratchDepthIntersection); + depthIntersection = scene.pickPositionWorldCoordinates(mousePosition, scratchDepthIntersection); } var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay); From 7575f7795511c2883a37ee8d804ec6f60f8930d5 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 13 Feb 2017 15:09:42 -0500 Subject: [PATCH 022/115] Add tests for pickPosition in 2D/CV. --- Specs/Scene/SceneSpec.js | 69 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index 5ae060f103aa..a21f6c712325 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -8,6 +8,7 @@ defineSuite([ 'Core/Ellipsoid', 'Core/GeographicProjection', 'Core/GeometryInstance', + 'Core/Math', 'Core/PixelFormat', 'Core/Rectangle', 'Core/RectangleGeometry', @@ -43,6 +44,7 @@ defineSuite([ Ellipsoid, GeographicProjection, GeometryInstance, + CesiumMath, PixelFormat, Rectangle, RectangleGeometry, @@ -82,7 +84,7 @@ defineSuite([ scene.debugCommandFilter = undefined; scene.fxaa = false; scene.primitives.removeAll(); - scene.morphTo3D(); + scene.morphTo3D(0.0); }); afterAll(function() { @@ -628,6 +630,9 @@ defineSuite([ scene.destroyForSpecs(); }); + var pickedPosition3D = new Cartesian3(-455845.46867895435, -5210337.548977215, 3637549.8562320103); + var pickedPosition2D = new Cartesian3(-455861.7055871038, -5210523.137686572, 3637866.6638769475); + it('pickPosition', function() { if (!scene.pickPositionSupported) { return; @@ -652,7 +657,67 @@ defineSuite([ expect(scene).toRenderAndCall(function() { var position = scene.pickPosition(windowPosition); - expect(position).toBeDefined(); + expect(position).toEqualEpsilon(pickedPosition3D, CesiumMath.EPSILON7); + }); + }); + + it('pickPosition in CV', function() { + if (!scene.pickPositionSupported) { + return; + } + + scene.morphToColumbusView(0.0); + + var rectangle = Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0); + scene.camera.setView({ destination : rectangle }); + + var canvas = scene.canvas; + var windowPosition = new Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2); + + expect(scene).toRenderAndCall(function() { + var position = scene.pickPosition(windowPosition); + expect(position).not.toBeDefined(); + + var rectanglePrimitive = createRectangle(rectangle); + rectanglePrimitive.appearance.material.uniforms.color = new Color(1.0, 0.0, 0.0, 1.0); + + var primitives = scene.primitives; + primitives.add(rectanglePrimitive); + }); + + expect(scene).toRenderAndCall(function() { + var position = scene.pickPosition(windowPosition); + expect(position).toEqualEpsilon(pickedPosition2D, CesiumMath.EPSILON7); + }); + }); + + it('pickPosition in 2D', function() { + if (!scene.pickPositionSupported) { + return; + } + + scene.morphTo2D(0.0); + + var rectangle = Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0); + scene.camera.setView({ destination : rectangle }); + + var canvas = scene.canvas; + var windowPosition = new Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2); + + expect(scene).toRenderAndCall(function() { + var position = scene.pickPosition(windowPosition); + expect(position).not.toBeDefined(); + + var rectanglePrimitive = createRectangle(rectangle); + rectanglePrimitive.appearance.material.uniforms.color = new Color(1.0, 0.0, 0.0, 1.0); + + var primitives = scene.primitives; + primitives.add(rectanglePrimitive); + }); + + expect(scene).toRenderAndCall(function() { + var position = scene.pickPosition(windowPosition); + expect(position).toEqualEpsilon(pickedPosition2D, CesiumMath.EPSILON7); }); }); From aa475c598e7a1eeda7276f9977238966e6d45733 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 13 Feb 2017 15:11:13 -0500 Subject: [PATCH 023/115] Update CHANGES.md. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index f8a4db7ca6f1..5d5df90b1e73 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ Change Log * Improved `RectangleGeometry` by skipping unecessary logic in the code [#4948](https://github.com/AnalyticalGraphicsInc/cesium/pull/4948) * Added `Transforms.localFrameToFixedFrameGenerator` to generate a function that computes a 4x4 transformation matrix from a local reference frame to fixed reference frame. * Fixed an issue where the camera would zoom past an object and flip to the other side of the globe. [#4967](https://github.com/AnalyticalGraphicsInc/cesium/pull/4967) and [#4982](https://github.com/AnalyticalGraphicsInc/cesium/pull/4982) +* Add support for `Scene.pickPosition` in Columbus view and 2D. [#4990](https://github.com/AnalyticalGraphicsInc/cesium/pull/4990) ### 1.30 - 2017-02-01 From ac2ec9bebdfab1d3463f19fc82434b07c8c00335 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Mon, 13 Feb 2017 15:29:46 -0500 Subject: [PATCH 024/115] update comments, documentation, and code style --- Source/Scene/Cesium3DTile.js | 10 ++- .../Scene/Cesium3DTileChildrenVisibility.js | 19 +++++ Source/Scene/Cesium3DTileOptimizationHint.js | 22 ++++++ Source/Scene/Cesium3DTileOptimizations.js | 69 +++++++++---------- Source/Scene/Cesium3DTileset.js | 37 +++++----- 5 files changed, 99 insertions(+), 58 deletions(-) create mode 100644 Source/Scene/Cesium3DTileChildrenVisibility.js create mode 100644 Source/Scene/Cesium3DTileOptimizationHint.js diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index 26c6bb4ac4d7..65e0d016927a 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -23,8 +23,10 @@ define([ '../Core/RequestScheduler', '../Core/SphereOutlineGeometry', '../ThirdParty/Uri', + './Cesium3DTileChildrenVisibility', './Cesium3DTileContentFactory', './Cesium3DTileContentState', + './Cesium3DTileOptimizations', './Cesium3DTileRefine', './Empty3DTileContent', './PerInstanceColorAppearance', @@ -57,8 +59,10 @@ define([ RequestScheduler, SphereOutlineGeometry, Uri, + Cesium3DTileChildrenVisibility, Cesium3DTileContentFactory, Cesium3DTileContentState, + Cesium3DTileOptimizations, Cesium3DTileRefine, Empty3DTileContent, PerInstanceColorAppearance, @@ -311,9 +315,11 @@ define([ /** * Flag to mark children visibility * + * @type {Cesium3DTileChildrenVisibility} + * * @private */ - this.childrenVisibility = 1; + this.childrenVisibility = Cesium3DTileChildrenVisibility.VISIBLE; /** * The last frame number the tile was selected in. @@ -339,7 +345,7 @@ define([ this._debugColor = new Color.fromRandom({ alpha : 1.0 }); this._debugColorizeTiles = false; - this._optimizations = clone(tileset._optimizations); + this._optimizations = new Cesium3DTileOptimizations(); } defineProperties(Cesium3DTile.prototype, { diff --git a/Source/Scene/Cesium3DTileChildrenVisibility.js b/Source/Scene/Cesium3DTileChildrenVisibility.js new file mode 100644 index 000000000000..913532b210b4 --- /dev/null +++ b/Source/Scene/Cesium3DTileChildrenVisibility.js @@ -0,0 +1,19 @@ +/*global define*/ +define([ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * @private + */ + var Cesium3DTileChildrenVisibility = { + NONE : 0, // No children visbile + VISIBLE : 1, // At least one child visible + IN_REQUEST_VOLUME : 2, // At least one child in viewer request volume + VISIBLE_IN_REQUEST_VOLUME : 4 // At least one child both visible and in viewer request volume + }; + + return freezeObject(Cesium3DTileChildrenVisibility); +}); \ No newline at end of file diff --git a/Source/Scene/Cesium3DTileOptimizationHint.js b/Source/Scene/Cesium3DTileOptimizationHint.js new file mode 100644 index 000000000000..e44697e0ca1e --- /dev/null +++ b/Source/Scene/Cesium3DTileOptimizationHint.js @@ -0,0 +1,22 @@ +/*global define*/ +define([ + '../Core/freezeObject' + ], function( + freezeObject) { + 'use strict'; + + /** + * @private + * + * @alias Cesium3DTileOptimizationHint + * + * Hint defining optimization support for a 3D tile + */ + var Cesium3DTileOptimizationHint = { + NOT_COMPUTED: -1, + USE_OPTIMIZATION: 1, + SKIP_OPTIMIZATION: 0 + }; + + return freezeObject(Cesium3DTileOptimizationHint); +}); \ No newline at end of file diff --git a/Source/Scene/Cesium3DTileOptimizations.js b/Source/Scene/Cesium3DTileOptimizations.js index d41a3ba532aa..f79ac6e0372e 100644 --- a/Source/Scene/Cesium3DTileOptimizations.js +++ b/Source/Scene/Cesium3DTileOptimizations.js @@ -2,43 +2,30 @@ define([ '../Core/Cartesian3', '../Core/defaultValue', + '../Core/defineProperties', '../Core/freezeObject', + './Cesium3DTileOptimizationHint', './TileOrientedBoundingBox', './TileBoundingRegion' ], function( Cartesian3, defaultValue, + defineProperties, freezeObject, + Cesium3DTileOptimizationHint, TileOrientedBoundingBox, TileBoundingRegion) { 'use strict'; /** - * @alias Cesium3DTileOptimizationFlag - * - * Flag denoting support for a 3D Tiles optimization - */ - var Cesium3DTileOptimizationFlag = { - UNSUPPORTED: 0, - SUPPORTED: 1, - INDETERMINATE: -1 - }; - - /** - * Defines optional optimization flags for a {@link Cesium3DTileset}. - * Optimizations marked as Cesium3DTileOptimizations.Flags.SUPPORTED or Cesium3DTileOptimizations.Flags.UNSUPPORTED + * Defines optional optimization hints for a {@link Cesium3DTileset}. + * Optimizations marked as {@link Cesium3DTileOptimizationHint.USE_OPTIMIZATION} or {@link Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION} * will not be evaluated at runtime * + * @private + * * @alias Cesium3DTileOptimizations * @constructor - * - * @example - * var tileset = new Cesium.Cesium3DTileset({ - * url: ..., - * optimizations: new Cesium.Cesium3DTileOptimizations({ - * childrenWithinParent: Cesium.Cesium3DTileOptimizations.Flags.SUPPORTED - * }) - * }); */ function Cesium3DTileOptimizations(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); @@ -47,19 +34,21 @@ define([ * Denotes support for if the childrenWithinParent optimization is supported. This is used to more tightly cull tilesets if children bounds are * fully contained within the parent. * - * @type {Cesium3DTileOptimizationFlag} + * @type {Cesium3DTileOptimizationHint} */ - this.childrenWithinParent = defaultValue(options.childrenWithinParent, Cesium3DTileOptimizations.Flags.INDETERMINATE); + this.childrenWithinParent = defaultValue(options.childrenWithinParent, Cesium3DTileOptimizationHint.NOT_COMPUTED); } var scratchAxis = new Cartesian3(); /** - * Checks and optinonally evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if children bounds are - * fully contained within the parent. + * Checks and optionnally evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if children bounds are + * fully contained within the parent. Currently, support for the optimization only works for oriented bounding boxes, so both the child and parent tile + * must be either a {@link TileOrientedBoundingBox} or {@link TileBoundingRegion}. The purpose of this check is to prevent use of a culling optimization + * when the child bounds exceed those of the parent. * * @param {Cesium3DTile} tile The tile to check. - * @param {Boolean} [evaluate=false] Whether to evaluate support if support for the childrenWithinParent optimization is Cesium3DTileOptimizations.INDETERMINATE + * @param {Boolean} [evaluate=false] Whether to evaluate support if support for the childrenWithinParent optimization is Cesium3DTileOptimizations.Hints.NOT_COMPUTED * @param {Boolean} [force=false] Whether to always evaluate support for the childrenWithinParent optimization * @returns {Boolean} Whether the childrenWithinParent optimization is supported. */ @@ -67,22 +56,30 @@ define([ evaluate = defaultValue(evaluate, false); force = defaultValue(force, false); - if ((this.childrenWithinParent === Cesium3DTileOptimizations.Flags.INDETERMINATE && evaluate) || force) { + if ((this.childrenWithinParent === Cesium3DTileOptimizationHint.NOT_COMPUTED && evaluate) || force) { var children = tile.children; var length = children.length; + + // Check if the parent has an oriented bounding box. var boundingVolume = tile._boundingVolume; if (boundingVolume instanceof TileOrientedBoundingBox || boundingVolume instanceof TileBoundingRegion) { var orientedBoundingBox = boundingVolume._orientedBoundingBox; - this.childrenWithinParent = Cesium3DTileOptimizations.Flags.SUPPORTED; + this.childrenWithinParent = Cesium3DTileOptimizationHint.USE_OPTIMIZATION; for (var i = 0; i < length; ++i) { var child = children[i]; + + // Check if the child has an oriented bounding box. var childBoundingVolume = child._boundingVolume; if (childBoundingVolume instanceof TileOrientedBoundingBox || childBoundingVolume instanceof TileBoundingRegion) { var childOrientedBoundingBox = childBoundingVolume._orientedBoundingBox; + + // Compute the axis from the parent to the child. var axis = Cartesian3.subtract(childOrientedBoundingBox.center, orientedBoundingBox.center, scratchAxis); var axisLength = Cartesian3.magnitude(axis); Cartesian3.divideByScalar(axis, axisLength, axis); + // Project the bounding box of the parent onto the axis. Because the axis is a ray from the parent to the child, + // the projection parameterized along the ray will be (+/- proj1). var proj1 = Math.abs(orientedBoundingBox.halfAxes[0] * axis.x) + Math.abs(orientedBoundingBox.halfAxes[1] * axis.y) + Math.abs(orientedBoundingBox.halfAxes[2] * axis.z) + @@ -92,7 +89,9 @@ define([ Math.abs(orientedBoundingBox.halfAxes[6] * axis.x) + Math.abs(orientedBoundingBox.halfAxes[7] * axis.y) + Math.abs(orientedBoundingBox.halfAxes[8] * axis.z); - + + // Project the bounding box of the child onto the axis. Because the axis is a ray from the parent to the child, + // the projection parameterized along the ray will be (+/- proj2) + axis.length. var proj2 = Math.abs(childOrientedBoundingBox.halfAxes[0] * axis.x) + Math.abs(childOrientedBoundingBox.halfAxes[1] * axis.y) + Math.abs(childOrientedBoundingBox.halfAxes[2] * axis.z) + @@ -102,24 +101,24 @@ define([ Math.abs(childOrientedBoundingBox.halfAxes[6] * axis.x) + Math.abs(childOrientedBoundingBox.halfAxes[7] * axis.y) + Math.abs(childOrientedBoundingBox.halfAxes[8] * axis.z); - + + // If the child extends the parent's bounds, the optimization is not valid and we skip it. if (proj1 <= proj2 + axisLength) { - this.childrenWithinParent = Cesium3DTileOptimizations.Flags.UNSUPPORTED; + this.childrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; break; } } else { - this.childrenWithinParent = Cesium3DTileOptimizations.Flags.UNSUPPORTED; + // Do not support if the parent and child both do not have oriented bounding boxes. + this.childrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; break; } } } } - return this.childrenWithinParent === Cesium3DTileOptimizations.Flags.SUPPORTED ? true : false; + return this.childrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION ? true : false; } - Cesium3DTileOptimizations.Flags = freezeObject(Cesium3DTileOptimizationFlag) - return Cesium3DTileOptimizations; }); diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 355d767acb4a..1c9b7f325462 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -26,8 +26,9 @@ define([ '../ThirdParty/Uri', '../ThirdParty/when', './Cesium3DTile', + './Cesium3DTileChildrenVisibility', './Cesium3DTileColorBlendMode', - './Cesium3DTileOptimizations', + './Cesium3DTileOptimizationHint', './Cesium3DTileRefine', './Cesium3DTileStyleEngine', './CullingVolume', @@ -64,8 +65,9 @@ define([ Uri, when, Cesium3DTile, + Cesium3DTileChildrenVisibility, Cesium3DTileColorBlendMode, - Cesium3DTileOptimizations, + Cesium3DTileOptimizationHint, Cesium3DTileRefine, Cesium3DTileStyleEngine, CullingVolume, @@ -275,7 +277,6 @@ define([ lastPick : new Cesium3DTilesetStatistics() }; - this._optimizations = defaultValue(options.optimizations, new Cesium3DTileOptimizations()); this._tilesLoaded = false; /** @@ -919,6 +920,7 @@ define([ } } } + tile3D._optimizations.checkChildrenWithinParent(tile3D, true); if (tile3D.hasContent && hasEmptyChild && (tile3D.refine === Cesium3DTileRefine.REPLACE)) { // Tiles that use replacement refinement and have empty child tiles need to keep track of // descendants with content in order to refine correctly. @@ -1165,15 +1167,8 @@ define([ var scratchStack = []; var scratchRefiningTiles = []; - var ChildrenVisibilityFlags = { - NONE: 0x0, - VISIBLE: 0x1, - IN_REQUEST_VOLUME: 0x2, - VISIBLE_IN_REQUEST_VOLUME: 0x4 - }; - function computeChildrenVisibility(tile, frameState, checkViewerRequestVolume) { - var flag = ChildrenVisibilityFlags.NONE; + var flag = Cesium3DTileChildrenVisibility.NONE; var children = tile.children; var childrenLength = children.length; var visibilityPlaneMask = tile.visibilityPlaneMask; @@ -1183,16 +1178,16 @@ define([ var visibilityMask = child.visibility(frameState, visibilityPlaneMask); if (isVisible(visibilityMask)) { - flag |= ChildrenVisibilityFlags.VISIBLE; + flag |= Cesium3DTileChildrenVisibility.VISIBLE; } if (checkViewerRequestVolume) { if (!child.insideViewerRequestVolume(frameState)) { visibilityMask = CullingVolume.MASK_OUTSIDE; } else { - flag |= ChildrenVisibilityFlags.IN_REQUEST_VOLUME; + flag |= Cesium3DTileChildrenVisibility.IN_REQUEST_VOLUME; if (isVisible(visibilityMask)) { - flag |= ChildrenVisibilityFlags.VISIBLE_IN_REQUEST_VOLUME; + flag |= Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME; } } } @@ -1336,7 +1331,7 @@ define([ // With replacement refinement, if the tile's SSE // is not sufficient, its children (or ancestors) are // rendered instead - var useChildrenBoundUnion = t._optimizations.checkChildrenWithinParent(t, true); + var useChildrenBoundUnion = t._optimizations.childrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION; var childrenVisibility; @@ -1345,7 +1340,7 @@ define([ // Select tile if it's a leaf (childrenLength === 0) if (useChildrenBoundUnion) { childrenVisibility = computeChildrenVisibility(t, frameState, false); - if ((childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || childrenLength === 0) { + if ((childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE) || childrenLength === 0) { selectTile(tileset, t, fullyVisible, frameState); } } else { @@ -1375,7 +1370,7 @@ define([ if (useChildrenBoundUnion) { childrenVisibility = computeChildrenVisibility(t, frameState, false); } - if (!useChildrenBoundUnion || (childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || childrenLength === 0) { + if (!useChildrenBoundUnion || (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE) || childrenLength === 0) { // Tile does not meet SSE. Add its commands since it is the best we have and request its children. selectTile(tileset, t, fullyVisible, frameState); @@ -1409,12 +1404,12 @@ define([ } } - if (childrenVisibility & ChildrenVisibilityFlags.VISIBLE_IN_REQUEST_VOLUME) { + if (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE_IN_REQUEST_VOLUME) { t.replaced = true; if (defined(t.descendantsWithContent)) { scratchRefiningTiles.push(t); } - } else if (!useChildrenBoundUnion || (childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || childrenLength === 0) { + } else if (!useChildrenBoundUnion || (childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE) || childrenLength === 0) { // Even though the children are all loaded they may not be visible if the camera // is not inside their request volumes. selectTile(tileset, t, fullyVisible, frameState); @@ -1429,7 +1424,7 @@ define([ updateTransforms(children, t.computedTransform); childrenVisibility = computeChildrenVisibility(t, frameState, true); - if (useChildrenBoundUnion && childrenVisibility === ChildrenVisibilityFlags.NONE && childrenLength !== 0) { + if (useChildrenBoundUnion && childrenVisibility === Cesium3DTileChildrenVisibility.NONE && childrenLength !== 0) { continue; } @@ -1522,7 +1517,7 @@ define([ for (j = 0; j < descendantsLength; ++j) { descendant = refiningTile.descendantsWithContent[j]; if (!descendant.selected && !descendant.replaced && - ((descendant.childrenVisibility & ChildrenVisibilityFlags.VISIBLE) || descendant.children.length === 0) && + ((descendant.childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE) || descendant.children.length === 0) && (frameState.cullingVolume.computeVisibility(descendant.contentBoundingVolume) !== Intersect.OUTSIDE)) { refinable = false; break; From 7fce7f140886d38029a2327705a8e0c8fa55e08a Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Mon, 13 Feb 2017 15:30:14 -0500 Subject: [PATCH 025/115] add tests --- .../ll.b3dm | Bin 0 -> 10453 bytes .../lr.b3dm | Bin 0 -> 10458 bytes .../parent.b3dm | Bin 0 -> 10460 bytes .../tileset.json | 174 +++++++++++++++ .../ul.b3dm | Bin 0 -> 10447 bytes .../ur.b3dm | Bin 0 -> 10453 bytes Specs/Scene/Cesium3DTilesetSpec.js | 204 ++++++++++++++++++ 7 files changed, 378 insertions(+) create mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ll.b3dm create mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/lr.b3dm create mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/parent.b3dm create mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/tileset.json create mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ul.b3dm create mode 100644 Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ur.b3dm diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ll.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ll.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..6e5e1599da0f62763b5e271dc727eb7c6ef41657 GIT binary patch literal 10453 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 LX3?@4KJ0%0HKe{Q literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/lr.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/lr.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..c6c194e74e944aadeb89348873827fd1890f3399 GIT binary patch literal 10458 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 TOwAnVH8P?FXcjG-@nil6j^83^ literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/parent.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/parent.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..e5721889b1ca819ddec87ffc165252db69e053df GIT binary patch literal 10460 zcmeHNdw5jknST*QKvHdWy)Jf~A|^15=YEM?GA9IyhFcP#G{xa$=1g*QE^#g~AqE7r zAa)T}i>;z)EnW(CYXPgS2y<{%M5Mc=-fF2Xi1o5|)#tHRx9+~*H|NZJlVp6%^XxzS zJe%_*Ip_O+@9({Q@B4m}@1$LfCPo0j8`S`Z$PIpt#qU199rf3?aRELc1jK+8kON9U z4QK&~1TU2>n)%l_hRZ}&d(=?ISN_@P+X&le1x+kge$Ru$1OOm}Y zMbLF!yoYsil!-QQBaf7Rzda#G)2}06d^{q7+IGTMMWEA zjjY3L%kJpR;v#5VK-B`8Kz~Z)M#G=(&C>pkcJ7Fhj!gE?s=L8PZO;!|% z$K2x7peD<>#GE?RAsG(jg_gfy8--3qgO;^DS`;eZ~ zwV+{VJ?HoU&l6*c-Vg_Psmwf~+&pzy=Ar)s%%hf6&I-mnlGO#nxROC$ru1W~B<%#& zY${2TmON)@7WVl&tfZATv#B)ZYa|tqn^9Bfh-YJUm@{2zE0K$5?XI|OMMLqfPSanT zP3J5!lZx4K%u+0XE*nJ`TkV%Op-8ut&Y%_?;e%X|hNEnV#HUmvw1P^Hq)Li4MC!** zn(5v!sX{k{o2+Cf7B`N~LWf?Q6BrKR*2-7iF#i6h3rttK;_HhT*$42Z5G>3qPS zOOu6-npv|p;3te$Pu5D3)up8M4K0le=Y*SE>q%@Q*taaqA?y%5*0UPKTowdf!d^N> zQbk4N)u7I+B8QV&K*G&M*2N&15hO{FmzMJ{%vfX-^)osG{wrrUhuMr+N}3WXwaqv+ zXpZ|Z#ljXG!9?iuC(Q)rsNb7GH?vlxGihI&Bg4ge(jU9cc+R3cW}@9jZ%{uMAQz8{ zqIN8n%b-vj?s6iwKV8?bV@aC3rG1SdLSrTDOrbm&?o6khw3E1_V9&?o%XC?hT-+qF zNx21&z6=N}XUh|w#Q`xYL!}I60G`2R*n_D(P8?v2@+PEi{P4Fn;tq)Fk zYv8R8PNvAlC-u{{PvQfOKDi0ga*A}?@o3s2TSsB3(>C3L=%Ubt8S0Ke-59lDb7NwJ zGj2YRCPeknB4hLvMmhh``Z(3HKz6bt z6YerGPFZeN3kqSo&00N`L5o_bWf`nkQUp;eW@3+Tp^un-A;HFDUVvu6=uuL(2jQZbI%wq&eF=no@ zz5TSLPc)I)wZ;-Gt~I(ec-3n$zJr&))?ds7)QiiFjSX8LRaWd*UT4Q(;}(Fs zg3FG<$XE$8nYAMrMz83-PgUe|CW4C{ZXipkXAPVo1so?Ib+NW-ZIst z0$JSJ=vrGzvz>hGY7=xp58&rnX(>wOk~Zl$6p;%T^TF@kAtGE{-{MM>(bD3U_9iku zXlZG;W*3{F3ajS@#$8PJk<1Sc9&xKYo&?8)%3r#tGsVrY6g5(NKA#U@1e^pT;bb@k zM!~5t8phxs;HSYjsDf|6>2L;o6aQNK7NSPNnTQ$%XCZ0~{2ijk!P$s99nL}2xo{qw z4;R4S!+5w5z70OO2>kFJm;e{UM7RX1p$0LN5Oo1eM%0B6K-5Jr1yK_qh^R~8QbcjU zg8(8(AcF!bXrMzaTn1BN8cc^7PzNEz7>E*~9#IO+M3fE|FPd>>H@U@4+n;VMKehA^U*feGyp zfhbrIgAV8f8?J_HAPxygLJGRzTEwIg6@d(*Vvt3Y4LL-`p&L;txDHW0&?LQ8&T{M6HEe5w#IE!9T)n za69}6Hp3n8WB3W&33tI3xEt<)t#B{ghnSxt>NdC^QJdjsi24a^L(~>{08v}vK}0u@Jo0Ueg!*W7wm?|;MedtJb{=e5w#uu8BxE0rx5ih>_OBncp6c^ zhP{Z|2YGN{KRg5f0?)#8@H`xV7vLbg2#4S$I1Imme?`o{A!Z5TV)P1?8)>-n(I%8^V{XXv1ReL*DzB%pEreJ7v+qKSL=gl>$ zSG*k(9+*Hedq4Vo-!r}|LnrQD8)9Xz{|y-a{x*vL@cPA}OPe-P3@giW&VFlc=)Ze5 z)Dc~*EX&VgSlcRbR^nmpsl>@*Sih=HT9ChCqCX@&Kf3<9r(ejQcXFpOXXow4v9qf4 zT{AD4e&US38kf9&LEUGLNii==f6PmttTpxsj~J}%H=o;Dm&n{$NATmWos~a);#P`b zWm!(`#_@UO{p+YMR+i;wF|2KsI4kk6_Eh3zF|1z)&N7{IoAZ z_p;AIeIr|(%eKyOzPR&2WBMznIV;}-irMkht&aKj@*SiepU?+ooy|Byescbjp| zoqXuaBWptYqkW-qs}F}>NMGzccVLaNZHHpKy6O>%S^dz*bw^i!6na-Z$zWxxpPp%a zdPfz-XMgr-Xz7+S41!^0S@*Sii2iA+R*=Qr1XY+UrqBhJmu+e1~Wml?*2-HyF!ymQ_&uNhBlxyxzac#vX_9D2?9 z?m1tC*6dqnu(H9Go1K+EucG+9FFon>rK=2rVP#oP>CxRzo9`gi#mch$EQYnM5@#hI z)}Bh7EQa;#{q|#_8)oI5#chF*{+(RtgF3}Ag{U*V^YhUD-LE(s*VOH^Q>u|@eVk(c z>)gvjkF}3+>du_vu(F?hWEh+GzeMrE=s$=2fBP^`Fsv-g>5Lj_y!rhJR2M7D^0OG$ zwo06pcvyQXak3cJuQTlB#<|glu~)`I_dY(;fEz|QzOH%Bl;+jOxeNC=+wMKBZi~3Z zNOj#uF^l?Z4Q1-i{Ks7vI;^a;;65W|?xy$^eLcpe#BCJA%Cel%wpB(Oe=JXQv9c^b zi(zf6#94`lwWks%i(&mb{5vCm{>u1M)5eahul<&jU)DO+_;P>F_{PSu`A_d?%O8y% zH*OA{sB77DPaVP3$w%`yP0kphONb6zy6FWl}dd;aK*2@mZuE`MvhquLuC<(?zP zPj5Qtygh$Y{?Ln`8=JYU6!Y%l9Y%J-lljNQ1r95_Xv2v5@ju>6@#|iG-S|AQo?=*8 zmh-)d$Bc_djiS0(S(cy0u(nm=ti;3GQ;CzsuzuZjf?S`7Ccdh z%#(5Q{Qvm>Tk#?9UWfBF0{`+K&UF%=CJg5qiRTK#xlYD2h~ZqP;JLA@w3F53 zuEy7gL&Sl?k(qCrdt)!Rsy&}-h!}AOU&E%-2q6#ETrl7(eG^Q<6xXdreC>wsJXPUJ52b_;77bw{M5WyGM9)r72R@hhiYJXY>f%w0H$MrDlySym#;MXF zB#wKObliKuaa8Zc4nr38Lfx8b=(QT^5nYHY3FnmVus7XMPh1%yQjz6}Fup5pLId$_ z$;`sby=pR=$t7pnn2F@Xx1m1Z@)8=)8aARXPm6m>`4tR9SnZJq*tDwgO|BY?r<>#p z-=E9ANxq?!BvPrN?EKnV&>xy*!JgjbzRA;k?n;rzfm3eyC~}gwki{SjM0-(k;of6K zyq5^9W?W91`UMNq9qkwd&k8e8x+Sa95f9J8_hR*K$xsm-?ynk4JWOV?g+Ai0;~ek5 z8Ay3yxp4RoQ4+_?s-$ruPZARq3%-oqk(`^#e$Ps$s_8&?P1V>wvMy;Wn@cB&c|vt{ zcd*Ado$}Q9X80!KKRozqefZy8T)>BOy+h9tqtQBK5PhjgHk?g`X+euZk62J6KM)P`VYA~*4 zt|F{J@>ii?Cs^qIvHM61f?1e`0-;>>^sS{yG)6nb6pl^M!-Z9idV zMJ$|xOyQkF`7GHK2E4`?3>f%2Vz5!AUP9)E?CO#aK^Wgb`Y^s24yn2njsPwJ2_@U3 zP!i?c0`N8i94tk@+)ZR1lsH~cC%N$`<~hv^ERy-|i)3o%K(CPzEkLtq*;I}F9|#^& AxBvhE literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/tileset.json b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/tileset.json new file mode 100644 index 000000000000..af31f2233257 --- /dev/null +++ b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/tileset.json @@ -0,0 +1,174 @@ +{ + "asset": { + "version": "0.0", + "tilesetVersion": "1.2.3" + }, + "properties": { + "id": { + "minimum": 0, + "maximum": 9 + }, + "Longitude": { + "minimum": -1.3197190069941716, + "maximum": -1.3196399825465384 + }, + "Latitude": { + "minimum": 0.6988468038519597, + "maximum": 0.6989046685398855 + }, + "Height": { + "minimum": 6, + "maximum": 84 + } + }, + "geometricError": 240, + "root": { + "boundingVolume": { + "region": [ + -1.3197209591796106, + 0.6988424218, + -1.3196390408203893, + 0.6989055782, + 0, + 88 + ] + }, + "geometricError": 240, + "refine": "replace", + "children": [ + { + "boundingVolume": { + "region": [ + -1.3197209591796106, + 0.6988424218, + -1.3196390408203893, + 0.6989055782, + 0, + 88 + ] + }, + "geometricError": 70, + "refine": "replace", + "content": { + "url": "parent.b3dm", + "boundingVolume": { + "region": [ + -1.3197004795898053, + 0.6988582109, + -1.3196595204101946, + 0.6988897891, + 0, + 88 + ] + } + }, + "children": [ + { + "boundingVolume": { + "region": [ + -1.3197209591796106, + 0.6988424218, + -1.31968, + 0.698874, + 0, + 20 + ] + }, + "viewerRequestVolume": { + "region": [ + -1.3197004795898053, + 0.6988582109, + -1.3196595204101946, + 0.6988897891, + 0, + 50 + ] + }, + "geometricError": 0, + "content": { + "url": "ll.b3dm" + } + }, + { + "boundingVolume": { + "region": [ + -1.31968, + 0.6988424218, + -1.3196390408203893, + 0.698874, + 0, + 20 + ] + }, + "viewerRequestVolume": { + "region": [ + -1.3197004795898053, + 0.6988582109, + -1.3196595204101946, + 0.6988897891, + 0, + 50 + ] + }, + "geometricError": 0, + "content": { + "url": "lr.b3dm" + } + }, + { + "boundingVolume": { + "region": [ + -1.31968, + 0.698874, + -1.3196390408203893, + 0.6989055782, + 0, + 20 + ] + }, + "viewerRequestVolume": { + "region": [ + -1.3197004795898053, + 0.6988582109, + -1.3196595204101946, + 0.6988897891, + 0, + 50 + ] + }, + "geometricError": 0, + "content": { + "url": "ur.b3dm" + } + }, + { + "boundingVolume": { + "region": [ + -1.3197209591796106, + 0.698874, + -1.31968, + 0.6989055782, + 0, + 20 + ] + }, + "viewerRequestVolume": { + "region": [ + -1.3197004795898053, + 0.6988582109, + -1.3196595204101946, + 0.6988897891, + 0, + 50 + ] + }, + "geometricError": 0, + "content": { + "url": "ul.b3dm" + } + } + ] + } + ] + } +} diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ul.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ul.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..4fd75a2453b6d3b37a210a3d487d63a6799a8865 GIT binary patch literal 10447 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 PBO_XXX3?^lHsyZ+5kClG literal 0 HcmV?d00001 diff --git a/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ur.b3dm b/Specs/Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume/ur.b3dm new file mode 100644 index 0000000000000000000000000000000000000000..bd80912f82b7344e062d0242f385e3c2ea6ea7dc GIT binary patch literal 10453 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 R?C&))q6KIcEt~Nre+6LnZo2>g literal 0 HcmV?d00001 diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index dbd21cfa11e1..9fed49703401 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -13,6 +13,7 @@ defineSuite([ 'Scene/Cesium3DTile', 'Scene/Cesium3DTileColorBlendMode', 'Scene/Cesium3DTileContentState', + 'Scene/Cesium3DTileOptimizations', 'Scene/Cesium3DTileRefine', 'Scene/Cesium3DTileStyle', 'Scene/CullingVolume', @@ -34,6 +35,7 @@ defineSuite([ Cesium3DTile, Cesium3DTileColorBlendMode, Cesium3DTileContentState, + Cesium3DTileOptimizations, Cesium3DTileRefine, Cesium3DTileStyle, CullingVolume, @@ -97,6 +99,9 @@ defineSuite([ // Root tile with 4 b3dm children and 1 pnts child with a viewer request volume var tilesetWithViewerRequestVolumeUrl = './Data/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume'; + // Parent tile with content and four child tiles with content with viewer request volume for each child + var tilesetReplacementWithViewerRequestVolumeUrl = './Data/Cesium3DTiles/Tilesets/TilesetReplacementWithViewerRequestVolume'; + var styleUrl = './Data/Cesium3DTiles/Style/style.json'; var originalMaximumRequests; @@ -840,6 +845,205 @@ defineSuite([ }); }); + describe('children bound union', function() { + var tilesetUnoptLoaded, tilesetOptLoaded; + + // tileset containing a tileset. root is replace, tile wrapping child tileset is additive. + // child tileset is replacement. camera is positioned so that no children of the child tileset are visible. + beforeEach(function() { + loadTiles(); + return when.all([tilesetUnoptLoaded, tilesetOptLoaded]); + }) + + function loadTiles() { + tilesetUnoptLoaded = Cesium3DTilesTester.waitForTilesLoaded(scene, scene.primitives.add(new Cesium3DTileset({ + url: tilesetReplacement3Url, + optimizations: new Cesium3DTileOptimizations({ + childrenWithinParent: Cesium3DTileOptimizations.Flags.UNSUPPORTED + }) + }))); + + tilesetOptLoaded = Cesium3DTilesTester.waitForTilesLoaded(scene, scene.primitives.add(new Cesium3DTileset({ + url: tilesetReplacement3Url + }))); + }; + + it ('does not select visible tiles with invisible children', function() { + + var stats, root, wrapperTile, child_root; + + function checkVisibility() { + expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); + } + + return tilesetUnoptLoaded.then(function(tileset) { + stats = tileset._statistics; + root = tileset._root; + wrapperTile = root.children[0]; + child_root = wrapperTile.children[0]; + + scene.camera.setView({ + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 22), // just above the child tiles + orientation: { + heading: 0, + pitch: 1.57, + roll: 0 + } + }); + + scene.renderForSpecs(); + + checkVisibility(); + expect(stats.visited).toEqual(3); + expect(child_root.selected).toBe(true); + + // we should visit the root, the tile containing the child tileset, and the root of the child tileset + // nothing should be drawn because all children of the child tileset are below the camera. + // root of the child tileset should not be selected even though it is visible + + return tilesetOptLoaded.then(function(tileset) { + stats = tileset._statistics; + root = tileset._root; + wrapperTile = root.children[0]; + child_root = wrapperTile.children[0]; + + scene.renderForSpecs(); + + checkVisibility(); + expect(stats.visited).toEqual(3); + expect(child_root.selected).toBe(false); + }); + }); + }); + + it ('does not select visible tiles not meeting SSE with visible children', function() { + return tilesetOptLoaded.then(function(tileset) { + var stats = tileset._statistics; + var root = tileset._root; + var wrapperTile = root.children[0]; + var child_root = wrapperTile.children[0]; + + scene.camera.setView({ + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 50), + orientation: { + heading: 0, + pitch: -1.57, + roll: 0 + } + }); + + scene.renderForSpecs(); + + expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + + expect(stats.visited).toEqual(7); + expect(child_root.selected).toBe(false); + expect(child_root.replaced).toBe(true); + }); + }); + + it ('does select visible tiles meeting SSE with visible children', function() { + return tilesetOptLoaded.then(function(tileset) { + var stats = tileset._statistics; + var root = tileset._root; + var wrapperTile = root.children[0]; + var child_root = wrapperTile.children[0]; + + scene.camera.setView({ + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 50), + orientation: { + heading: 0, + pitch: -1.57, + roll: 0 + } + }); + + child_root.geometricError = 0; + scene.renderForSpecs(); + + expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + + expect(stats.visited).toEqual(3); + expect(child_root.selected).toBe(true); + expect(child_root.replaced).toBe(false); + }); + }); + + it('does not select visibile tiles with visible children failing request volumes', function() { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { + scene.camera.setView({ + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 100), + orientation: { + heading: 0, + pitch: -1.57, + roll: 0 + } + }); + + scene.renderForSpecs(); + + var stats = tileset._statistics; + expect(stats.visited).toEqual(2); + expect(tileset._selectedTiles.length).toEqual(1); + }); + }); + + it('does select visibile tiles with visible children passing request volumes', function() { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { + scene.camera.setView({ + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 40), + orientation: { + heading: 0, + pitch: -1.57, + roll: 0 + } + }); + + scene.renderForSpecs(); + + var stats = tileset._statistics; + expect(stats.visited).toEqual(6); + expect(tileset._selectedTiles.length).toEqual(4); + }); + }); + }); + it('loads tileset with external tileset.json', function() { // Set view so that no tiles are loaded initially viewNothing(); From fda059da1012af2f419af01b7ebd1120ad45cfa5 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Mon, 13 Feb 2017 15:34:01 -0500 Subject: [PATCH 026/115] remove extra require --- Source/Scene/Cesium3DTileOptimizations.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Scene/Cesium3DTileOptimizations.js b/Source/Scene/Cesium3DTileOptimizations.js index f79ac6e0372e..b5b9b08cc6e7 100644 --- a/Source/Scene/Cesium3DTileOptimizations.js +++ b/Source/Scene/Cesium3DTileOptimizations.js @@ -2,7 +2,6 @@ define([ '../Core/Cartesian3', '../Core/defaultValue', - '../Core/defineProperties', '../Core/freezeObject', './Cesium3DTileOptimizationHint', './TileOrientedBoundingBox', @@ -10,7 +9,6 @@ define([ ], function( Cartesian3, defaultValue, - defineProperties, freezeObject, Cesium3DTileOptimizationHint, TileOrientedBoundingBox, From cd0ff9023d74b46e3ef0be911d42b13746bda8cb Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Mon, 13 Feb 2017 15:41:49 -0500 Subject: [PATCH 027/115] update tests --- Specs/Scene/Cesium3DTilesetSpec.js | 84 +++++++----------------------- 1 file changed, 20 insertions(+), 64 deletions(-) diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 9fed49703401..835d08b8dca6 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -845,34 +845,25 @@ defineSuite([ }); }); - describe('children bound union', function() { - var tilesetUnoptLoaded, tilesetOptLoaded; - - // tileset containing a tileset. root is replace, tile wrapping child tileset is additive. - // child tileset is replacement. camera is positioned so that no children of the child tileset are visible. - beforeEach(function() { - loadTiles(); - return when.all([tilesetUnoptLoaded, tilesetOptLoaded]); - }) - - function loadTiles() { - tilesetUnoptLoaded = Cesium3DTilesTester.waitForTilesLoaded(scene, scene.primitives.add(new Cesium3DTileset({ - url: tilesetReplacement3Url, - optimizations: new Cesium3DTileOptimizations({ - childrenWithinParent: Cesium3DTileOptimizations.Flags.UNSUPPORTED - }) - }))); - - tilesetOptLoaded = Cesium3DTilesTester.waitForTilesLoaded(scene, scene.primitives.add(new Cesium3DTileset({ - url: tilesetReplacement3Url - }))); - }; - + describe('children bound union optimization', function() { it ('does not select visible tiles with invisible children', function() { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacement3Url).then(function(tileset) { + scene.camera.setView({ + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 22), // just above the child tiles + orientation: { + heading: 0, + pitch: 1.57, + roll: 0 + } + }); - var stats, root, wrapperTile, child_root; + var stats = tileset._statistics; + var root = tileset._root; + var wrapperTile = root.children[0]; + var child_root = wrapperTile.children[0]; + + scene.renderForSpecs(); - function checkVisibility() { expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); @@ -886,50 +877,15 @@ defineSuite([ expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); - } - return tilesetUnoptLoaded.then(function(tileset) { - stats = tileset._statistics; - root = tileset._root; - wrapperTile = root.children[0]; - child_root = wrapperTile.children[0]; - - scene.camera.setView({ - destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 22), // just above the child tiles - orientation: { - heading: 0, - pitch: 1.57, - roll: 0 - } - }); - - scene.renderForSpecs(); - - checkVisibility(); expect(stats.visited).toEqual(3); - expect(child_root.selected).toBe(true); - - // we should visit the root, the tile containing the child tileset, and the root of the child tileset - // nothing should be drawn because all children of the child tileset are below the camera. - // root of the child tileset should not be selected even though it is visible - - return tilesetOptLoaded.then(function(tileset) { - stats = tileset._statistics; - root = tileset._root; - wrapperTile = root.children[0]; - child_root = wrapperTile.children[0]; - - scene.renderForSpecs(); - - checkVisibility(); - expect(stats.visited).toEqual(3); - expect(child_root.selected).toBe(false); - }); + expect(tileset._selectedTiles.length).toEqual(0); + expect(child_root.selected).toBe(false); }); }); it ('does not select visible tiles not meeting SSE with visible children', function() { - return tilesetOptLoaded.then(function(tileset) { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacement3Url).then(function(tileset) { var stats = tileset._statistics; var root = tileset._root; var wrapperTile = root.children[0]; @@ -967,7 +923,7 @@ defineSuite([ }); it ('does select visible tiles meeting SSE with visible children', function() { - return tilesetOptLoaded.then(function(tileset) { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacement3Url).then(function(tileset) { var stats = tileset._statistics; var root = tileset._root; var wrapperTile = root.children[0]; From 408c9ae711f0607d800f69e84b1ef393287eb364 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Mon, 13 Feb 2017 16:17:53 -0500 Subject: [PATCH 028/115] update tests --- Specs/Scene/Cesium3DTilesetSpec.js | 62 +++++++++++++++++------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 835d08b8dca6..2e126ca6064f 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -864,12 +864,6 @@ defineSuite([ scene.renderForSpecs(); - expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); - - expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); - expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); @@ -878,7 +872,6 @@ defineSuite([ expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); - expect(stats.visited).toEqual(3); expect(tileset._selectedTiles.length).toEqual(0); expect(child_root.selected).toBe(false); }); @@ -890,6 +883,7 @@ defineSuite([ var root = tileset._root; var wrapperTile = root.children[0]; var child_root = wrapperTile.children[0]; + child_root.geometricError = 240; scene.camera.setView({ destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 50), @@ -902,12 +896,6 @@ defineSuite([ scene.renderForSpecs(); - expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); - - expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); - expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); @@ -916,7 +904,6 @@ defineSuite([ expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(stats.visited).toEqual(7); expect(child_root.selected).toBe(false); expect(child_root.replaced).toBe(true); }); @@ -940,12 +927,6 @@ defineSuite([ child_root.geometricError = 0; scene.renderForSpecs(); - - expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); - - expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(wrapperTile.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); @@ -955,13 +936,12 @@ defineSuite([ expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(stats.visited).toEqual(3); expect(child_root.selected).toBe(true); expect(child_root.replaced).toBe(false); }); }); - it('does not select visibile tiles with visible children failing request volumes', function() { + it('does select visibile tiles with visible children failing request volumes', function() { return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { scene.camera.setView({ destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 100), @@ -972,11 +952,23 @@ defineSuite([ } }); + var stats = tileset._statistics; + var root = tileset._root; + var child_root = root.children[0]; + child_root.geometricError = 0; + scene.renderForSpecs(); - var stats = tileset._statistics; - expect(stats.visited).toEqual(2); + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(tileset._selectedTiles.length).toEqual(1); + expect(child_root.selected).toBe(true); }); }); @@ -991,11 +983,29 @@ defineSuite([ } }); + var stats = tileset._statistics; + var root = tileset._root; + var child_root = root.children[0]; + child_root.geometricError = 0; + scene.renderForSpecs(); - var stats = tileset._statistics; - expect(stats.visited).toEqual(6); + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); + + expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[2].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + expect(child_root.children[3].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); + + expect(tileset._selectedTiles.length).toEqual(1); + expect(child_root.selected).toBe(true); + + child_root.geometricError = 200; + scene.renderForSpecs(); expect(tileset._selectedTiles.length).toEqual(4); + expect(child_root.selected).toBe(false); + expect(child_root.replaced).toBe(true); }); }); }); From e4ed730d43127eef0c93242831583b05810ba355 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Mon, 13 Feb 2017 17:31:53 -0500 Subject: [PATCH 029/115] Updates from review. --- Source/Scene/Scene.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 9bdd70966f5c..912be4b4f815 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -302,6 +302,9 @@ define([ this._pickDepths = []; this._debugGlobeDepths = []; + this._pickDepthPassState = undefined; + this._pickDepthFramebuffer = undefined; + this._transitioner = new SceneTransitioner(this); this._renderError = new Event(); @@ -2706,9 +2709,8 @@ define([ return object; }; - var scratchPickDepthPassState; - - function renderForPickDepth(scene, drawingBufferPosition) { + function renderTranslucentDepthForPick(scene, drawingBufferPosition) { + // PERFORMANCE_IDEA: render translucent only and merge with the previous frame var context = scene._context; var us = context.uniformState; var frameState = scene._frameState; @@ -2720,9 +2722,9 @@ define([ us.update(frameState); - var passState = scratchPickDepthPassState; + var passState = scene._pickDepthPassState; if (!defined(passState)) { - passState = scratchPickDepthPassState = new PassState(context); + passState = scene._pickDepthPassState = new PassState(context); passState.scissorTest = { enabled : true, rectangle : new BoundingRectangle() @@ -2733,7 +2735,7 @@ define([ var width = context.drawingBufferWidth; var height = context.drawingBufferHeight; - + var framebuffer = scene._pickDepthFramebuffer; var pickDepthFBWidth = scene._pickDepthFramebufferWidth; var pickDepthFBHeight = scene._pickDepthFramebufferHeight; @@ -2761,13 +2763,13 @@ define([ passState.scissorTest.rectangle.y = height - drawingBufferPosition.y; passState.scissorTest.rectangle.width = 1; passState.scissorTest.rectangle.height = 1; - + updateAndExecuteCommands(scene, passState, scratchColorZero); resolveFramebuffers(scene, passState); context.endFrame(); } - + var scratchPackedDepth = new Cartesian4(); var packedDepthScale = new Cartesian4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 16581375.0); @@ -2800,7 +2802,7 @@ define([ var drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(this, windowPosition, scratchPosition); if (this.pickTranslucentDepth) { - renderForPickDepth(this, drawingBufferPosition); + renderTranslucentDepthForPick(this, drawingBufferPosition); } drawingBufferPosition.y = this.drawingBufferHeight - drawingBufferPosition.y; From 8a465a5a05eda8425300c9ea3024f0ff24c6c71b Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Tue, 14 Feb 2017 08:42:04 -0500 Subject: [PATCH 030/115] update tileset for specs --- Specs/Scene/Cesium3DTilesetSpec.js | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 2e126ca6064f..8478daac86f4 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -847,9 +847,9 @@ defineSuite([ describe('children bound union optimization', function() { it ('does not select visible tiles with invisible children', function() { - return Cesium3DTilesTester.loadTileset(scene, tilesetReplacement3Url).then(function(tileset) { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { scene.camera.setView({ - destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 22), // just above the child tiles + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 22), orientation: { heading: 0, pitch: 1.57, @@ -859,13 +859,11 @@ defineSuite([ var stats = tileset._statistics; var root = tileset._root; - var wrapperTile = root.children[0]; - var child_root = wrapperTile.children[0]; - + var child_root = root.children[0]; + scene.renderForSpecs(); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).toEqual(CullingVolume.MASK_OUTSIDE); @@ -878,15 +876,14 @@ defineSuite([ }); it ('does not select visible tiles not meeting SSE with visible children', function() { - return Cesium3DTilesTester.loadTileset(scene, tilesetReplacement3Url).then(function(tileset) { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { var stats = tileset._statistics; var root = tileset._root; - var wrapperTile = root.children[0]; - var child_root = wrapperTile.children[0]; + var child_root = root.children[0]; child_root.geometricError = 240; scene.camera.setView({ - destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 50), + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 49), orientation: { heading: 0, pitch: -1.57, @@ -897,7 +894,6 @@ defineSuite([ scene.renderForSpecs(); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); @@ -910,14 +906,13 @@ defineSuite([ }); it ('does select visible tiles meeting SSE with visible children', function() { - return Cesium3DTilesTester.loadTileset(scene, tilesetReplacement3Url).then(function(tileset) { + return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { var stats = tileset._statistics; var root = tileset._root; - var wrapperTile = root.children[0]; - var child_root = wrapperTile.children[0]; + var child_root = root.children[0]; scene.camera.setView({ - destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 50), + destination: Cartesian3.fromRadians(centerLongitude, centerLatitude, 49), orientation: { heading: 0, pitch: -1.57, @@ -929,7 +924,6 @@ defineSuite([ scene.renderForSpecs(); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); @@ -960,7 +954,6 @@ defineSuite([ scene.renderForSpecs(); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); @@ -991,7 +984,6 @@ defineSuite([ scene.renderForSpecs(); expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); - expect(child_root.visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_INSIDE); expect(child_root.children[0].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); expect(child_root.children[1].visibility(scene.frameState, CullingVolume.MASK_INDETERMINATE)).not.toEqual(CullingVolume.MASK_OUTSIDE); From 12efaecc78c71f6fc8aea3d80cd9a5b98f39ad6f Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Tue, 14 Feb 2017 13:35:11 -0500 Subject: [PATCH 031/115] Safer attribute checking --- Source/Scene/Model.js | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 263a151e827d..9e84579703b4 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -1848,7 +1848,7 @@ define([ // the normal attribute. for (i = 1; i < length; ++i) { var attribute = attributes[i]; - if (/position/i.test(attribute)) { + if (/pos/i.test(attribute)) { attributes[i] = attributes[0]; attributes[0] = attribute; break; @@ -2332,6 +2332,7 @@ define([ // Retrieve the compiled shader program to assign index values to attributes var attributeLocations = {}; + var location; var index; var technique = techniques[materials[primitive.material].technique]; var parameters = technique.parameters; @@ -2340,23 +2341,27 @@ define([ var programVertexAttributes = program.vertexAttributes; var programAttributeLocations = program._attributeLocations; - // Note: WebGL shader compiler may have optimized and removed some attributes from programAttributeLocations - for (var location in programAttributeLocations){ - if (programAttributeLocations.hasOwnProperty(location)) { + // Note: WebGL shader compiler may have optimized and removed some attributes from programVertexAttributes + for (location in programVertexAttributes){ + if (programVertexAttributes.hasOwnProperty(location)) { var attribute = attributes[location]; + index = programVertexAttributes[location].index; if (defined(attribute)) { - var vertexAttribute = programVertexAttributes[location]; - if (defined(vertexAttribute)) { - index = vertexAttribute.index; - var parameter = parameters[attribute]; - attributeLocations[parameter.semantic] = index; - } - } else { - // Pre-created attributes. - // Some pre-created attributes, like per-instance pickIds, may be compiled out of the draw program - // but should be included in the list of attribute locations for the pick program. - // This is safe to do since programVertexAttributes and programAttributeLocations are equivalent except - // that programVertexAttributes optimizes out unused attributes. + var parameter = parameters[attribute]; + attributeLocations[parameter.semantic] = index; + } + } + } + + // Always add pre-created attributes. + // Some pre-created attributes, like per-instance pickIds, may be compiled out of the draw program + // but should be included in the list of attribute locations for the pick program. + // This is safe to do since programVertexAttributes and programAttributeLocations are equivalent except + // that programVertexAttributes optimizes out unused attributes. + var precreatedAttributes = model._precreatedAttributes; + if (defined(precreatedAttributes)) { + for (location in precreatedAttributes) { + if (precreatedAttributes.hasOwnProperty(location)) { index = programAttributeLocations[location]; attributeLocations[location] = index; } From 4d29924b0b53b82b2dbe3ecd0e3e2507f3cf0709 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 14 Feb 2017 15:49:51 -0500 Subject: [PATCH 032/115] Update pickPosition test epsilons. --- Specs/Scene/SceneSpec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index a21f6c712325..2d98e1a6302b 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -657,7 +657,7 @@ defineSuite([ expect(scene).toRenderAndCall(function() { var position = scene.pickPosition(windowPosition); - expect(position).toEqualEpsilon(pickedPosition3D, CesiumMath.EPSILON7); + expect(position).toEqualEpsilon(pickedPosition3D, CesiumMath.EPSILON6); }); }); @@ -687,7 +687,7 @@ defineSuite([ expect(scene).toRenderAndCall(function() { var position = scene.pickPosition(windowPosition); - expect(position).toEqualEpsilon(pickedPosition2D, CesiumMath.EPSILON7); + expect(position).toEqualEpsilon(pickedPosition2D, CesiumMath.EPSILON6); }); }); @@ -717,7 +717,7 @@ defineSuite([ expect(scene).toRenderAndCall(function() { var position = scene.pickPosition(windowPosition); - expect(position).toEqualEpsilon(pickedPosition2D, CesiumMath.EPSILON7); + expect(position).toEqualEpsilon(pickedPosition2D, CesiumMath.EPSILON6); }); }); From 791d37030f2882690253888ff25835354fab3a2e Mon Sep 17 00:00:00 2001 From: greenkeeperio-bot Date: Tue, 14 Feb 2017 15:50:49 -0500 Subject: [PATCH 033/115] chore(package): update aws-sdk to version 2.13.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fd02a0330478..dc7ef5d514cc 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "almond": "^0.3.3", - "aws-sdk": "^2.7.9", + "aws-sdk": "^2.13.0", "bluebird": "^3.4.6", "compressible": "^2.0.9", "compression": "^1.6.2", From e522ffebba0baaf2d11117b9b04a7e72cf31972d Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 14 Feb 2017 18:41:38 -0500 Subject: [PATCH 034/115] Add depth pass. --- Source/Scene/FrameState.js | 9 ++++++- Source/Scene/Scene.js | 49 +++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Source/Scene/FrameState.js b/Source/Scene/FrameState.js index 0d4278dc64a6..1431589182a0 100644 --- a/Source/Scene/FrameState.js +++ b/Source/Scene/FrameState.js @@ -117,7 +117,14 @@ define([ * @type {Boolean} * @default false */ - pick : false + pick : false, + + /** + * true if the primitive should update for a depth only pass, false otherwise. + * @type {Boolean} + * @default false + */ + depth : false }; /** diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 912be4b4f815..d078e02af40e 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -1717,7 +1717,7 @@ define([ var scratchPerspectiveOffCenterFrustum = new PerspectiveOffCenterFrustum(); var scratchOrthographicFrustum = new OrthographicFrustum(); - function executeCommands(scene, passState, picking) { + function executeCommands(scene, passState) { var camera = scene._camera; var context = scene.context; var us = context.uniformState; @@ -1742,6 +1742,7 @@ define([ us.updatePass(Pass.ENVIRONMENT); var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; + var picking = scene._frameState.passes.pick; var environmentState = scene._environmentState; // Do not render environment primitives during a pick pass since they do not generate picking commands. @@ -2012,7 +2013,7 @@ define([ } } - function updateAndExecuteCommands(scene, passState, backgroundColor, picking) { + function updateAndExecuteCommands(scene, passState, backgroundColor) { var context = scene._context; var viewport = passState.viewport; @@ -2024,7 +2025,7 @@ define([ if (scene._useWebVR && mode !== SceneMode.SCENE2D) { updatePrimitives(scene); createPotentiallyVisibleSet(scene); - updateAndClearFramebuffers(scene, passState, backgroundColor, picking); + updateAndClearFramebuffers(scene, passState, backgroundColor); executeComputeCommands(scene); executeShadowMapCastCommands(scene); @@ -2050,14 +2051,14 @@ define([ Cartesian3.add(savedCamera.position, eyeTranslation, camera.position); camera.frustum.xOffset = offset; - executeCommands(scene, passState, picking); + executeCommands(scene, passState); viewport.x = passState.viewport.width; Cartesian3.subtract(savedCamera.position, eyeTranslation, camera.position); camera.frustum.xOffset = -offset; - executeCommands(scene, passState, picking); + executeCommands(scene, passState); Camera.clone(savedCamera, camera); } else { @@ -2067,9 +2068,9 @@ define([ viewport.height = context.drawingBufferHeight; if (mode !== SceneMode.SCENE2D || scene._mapMode2D === MapMode2D.ROTATE) { - executeCommandsInViewport(true, scene, passState, backgroundColor, picking); + executeCommandsInViewport(true, scene, passState, backgroundColor); } else { - execute2DViewportCommands(scene, passState, backgroundColor, picking); + execute2DViewportCommands(scene, passState, backgroundColor); } } } @@ -2082,7 +2083,7 @@ define([ var scratch2DViewportEyePoint = new Cartesian3(); var scratch2DViewportWindowCoords = new Cartesian3(); - function execute2DViewportCommands(scene, passState, backgroundColor, picking) { + function execute2DViewportCommands(scene, passState, backgroundColor) { var context = scene.context; var frameState = scene.frameState; var camera = scene.camera; @@ -2113,7 +2114,7 @@ define([ var viewportWidth = viewport.width; if (x === 0.0 || windowCoordinates.x <= 0.0 || windowCoordinates.x >= context.drawingBufferWidth) { - executeCommandsInViewport(true, scene, passState, backgroundColor, picking); + executeCommandsInViewport(true, scene, passState, backgroundColor); } else if (Math.abs(context.drawingBufferWidth * 0.5 - windowCoordinates.x) < 1.0) { viewport.width = windowCoordinates.x; @@ -2124,7 +2125,7 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(true, scene, passState, backgroundColor, picking); + executeCommandsInViewport(true, scene, passState, backgroundColor); viewport.x = viewport.width; @@ -2136,7 +2137,7 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(false, scene, passState, backgroundColor, picking); + executeCommandsInViewport(false, scene, passState, backgroundColor); } else if (windowCoordinates.x > context.drawingBufferWidth * 0.5) { viewport.width = windowCoordinates.x; @@ -2146,7 +2147,7 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(true, scene, passState, backgroundColor, picking); + executeCommandsInViewport(true, scene, passState, backgroundColor); viewport.x += windowCoordinates.x; viewport.width = context.drawingBufferWidth - windowCoordinates.x; @@ -2159,7 +2160,7 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(false, scene, passState, backgroundColor, picking); + executeCommandsInViewport(false, scene, passState, backgroundColor); } else { viewport.x = windowCoordinates.x; viewport.width = context.drawingBufferWidth - windowCoordinates.x; @@ -2170,7 +2171,7 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(true, scene, passState, backgroundColor, picking); + executeCommandsInViewport(true, scene, passState, backgroundColor); viewport.x = 0; viewport.width = windowCoordinates.x; @@ -2183,7 +2184,7 @@ define([ frameState.cullingVolume = camera.frustum.computeCullingVolume(camera.positionWC, camera.directionWC, camera.upWC); context.uniformState.update(frameState); - executeCommandsInViewport(false, scene, passState, backgroundColor, picking); + executeCommandsInViewport(false, scene, passState, backgroundColor); } camera._setTransform(transform); @@ -2194,7 +2195,7 @@ define([ viewport.width = viewportWidth; } - function executeCommandsInViewport(firstViewport, scene, passState, backgroundColor, picking) { + function executeCommandsInViewport(firstViewport, scene, passState, backgroundColor) { if (!firstViewport) { scene.frameState.commandList.length = 0; } @@ -2203,12 +2204,12 @@ define([ createPotentiallyVisibleSet(scene); if (firstViewport) { - updateAndClearFramebuffers(scene, passState, backgroundColor, picking); + updateAndClearFramebuffers(scene, passState, backgroundColor); executeComputeCommands(scene); executeShadowMapCastCommands(scene); } - executeCommands(scene, passState, picking); + executeCommands(scene, passState); } function updateEnvironment(scene) { @@ -2318,10 +2319,13 @@ define([ } } - function updateAndClearFramebuffers(scene, passState, clearColor, picking) { + function updateAndClearFramebuffers(scene, passState, clearColor) { var context = scene._context; var environmentState = scene._environmentState; + var passes = scene._frameState.passes; + var picking = passes.pick; + var pickDepth = passes.depth; var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; // Preserve the reference to the original framebuffer. @@ -2347,7 +2351,7 @@ define([ clear.execute(context, passState); // Update globe depth rendering based on the current context and clear the globe depth framebuffer. - var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = !picking && defined(scene._globeDepth); + var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = (!picking || pickDepth) && defined(scene._globeDepth); if (useGlobeDepthFramebuffer) { scene._globeDepth.update(context); scene._globeDepth.clear(context, passState, clearColor); @@ -2700,7 +2704,7 @@ define([ var passState = this._pickFramebuffer.begin(scratchRectangle); - updateAndExecuteCommands(this, passState, scratchColorZero, true); + updateAndExecuteCommands(this, passState, scratchColorZero); resolveFramebuffers(this, passState); var object = this._pickFramebuffer.end(scratchRectangle); @@ -2718,7 +2722,8 @@ define([ // Update with previous frame's number and time, assuming that render is called before picking. updateFrameState(scene, frameState.frameNumber, frameState.time); frameState.cullingVolume = getPickCullingVolume(scene, drawingBufferPosition, 1, 1); - frameState.passes.render = true; + frameState.passes.pick = true; + frameState.passes.depth = true; us.update(frameState); From 6d94f35f7ff150b9e2454e72876f31691b62a8f4 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 14 Feb 2017 18:53:24 -0500 Subject: [PATCH 035/115] Add doc. --- Source/Renderer/PassState.js | 11 +++++++++++ Source/Scene/Scene.js | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/Source/Renderer/PassState.js b/Source/Renderer/PassState.js index 4b383296407c..92c935ad98fd 100644 --- a/Source/Renderer/PassState.js +++ b/Source/Renderer/PassState.js @@ -57,6 +57,17 @@ define([], function() { */ this.viewport = undefined; + /** + * When defined, this overrides the depth mask property of a {@link DrawCommand}'s render state. + * This is used to, for example, to allow the renderer to enable depth writes for picking translucent + * geometry. + *

+ * When this is undefined, the {@link DrawCommand}'s property is used. + *

+ * + * @type {Boolean} + * @default undefined + */ this.depthMask = undefined; } diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index d078e02af40e..81e4c35bce6e 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -559,6 +559,16 @@ define([ */ this.useDepthPicking = true; + /** + * When true, enables picking translucent geometry using the depth buffer. + * useDepthPicking must also be true to enable picking the depth buffer. + *

+ * There is a decrease in performance when enabled. There are extra draw calls to write depth for + * translucent geometry. + *

+ * @type {Boolean} + * @default false + */ this.pickTranslucentDepth = true; /** From 963e631fe5df96f702880f1ff2a1976b44b05d79 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 14 Feb 2017 18:59:26 -0500 Subject: [PATCH 036/115] Add pick translucent test. --- Source/Scene/Scene.js | 2 +- Specs/Scene/SceneSpec.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 81e4c35bce6e..946ff18b2f5c 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -569,7 +569,7 @@ define([ * @type {Boolean} * @default false */ - this.pickTranslucentDepth = true; + this.pickTranslucentDepth = false; /** * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index 5ae060f103aa..f75296227875 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -688,6 +688,38 @@ defineSuite([ }); }); + it('pickPosition picks translucent geometry when pickTranslucentDepth is true', function() { + if (!scene.pickPositionSupported) { + return; + } + + var rectangle = Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0); + scene.camera.setView({ + destination : rectangle + }); + + var canvas = scene.canvas; + var windowPosition = new Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2); + + var rectanglePrimitive = createRectangle(rectangle); + rectanglePrimitive.appearance.material.uniforms.color = new Color(1.0, 0.0, 0.0, 0.5); + + var primitives = scene.primitives; + primitives.add(rectanglePrimitive); + + scene.useDepthPicking = true; + expect(scene).toRenderAndCall(function() { + var position = scene.pickPosition(windowPosition); + expect(position).not.toBeDefined(); + }); + + scene.pickTranslucentDepth = true; + expect(scene).toRenderAndCall(function() { + var position = scene.pickPosition(windowPosition); + expect(position).toBeDefined(); + }); + }); + it('pickPosition throws without windowPosition', function() { expect(function() { scene.pickPosition(); From 0e2fb9c6562a9cf7aee5e03063f21d19e55f845b Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Tue, 14 Feb 2017 19:01:19 -0500 Subject: [PATCH 037/115] Update CHANGES.md. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 6b01ad5ab2df..624123d0f617 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,7 @@ Change Log * Fixed an issue where the camera would zoom past an object and flip to the other side of the globe. [#4967](https://github.com/AnalyticalGraphicsInc/cesium/pull/4967) and [#4982](https://github.com/AnalyticalGraphicsInc/cesium/pull/4982) * Fixed exception in 2D in certain cases with polylines when rotating the map. [#4619](https://github.com/AnalyticalGraphicsInc/cesium/issues/4619) * Fixed an issue with constant `VertexArray` attributes not being set correctly. [#4995](https://github.com/AnalyticalGraphicsInc/cesium/pull/4995) +* Add support for depth picking translucent primitives when `Scene.pickTranslucentDepth` is `true`. [#4979](https://github.com/AnalyticalGraphicsInc/cesium/pull/4979) ### 1.30 - 2017-02-01 From be613f9bcf4a2d49dce7e505fd4f21bb3419841e Mon Sep 17 00:00:00 2001 From: Patrick Cozzi Date: Tue, 14 Feb 2017 21:39:02 -0500 Subject: [PATCH 038/115] Update reference doc --- Source/Scene/Scene.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 946ff18b2f5c..186f4a155060 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -561,7 +561,7 @@ define([ /** * When true, enables picking translucent geometry using the depth buffer. - * useDepthPicking must also be true to enable picking the depth buffer. + * {@link Scene#useDepthPicking} must also be true to enable picking the depth buffer. *

* There is a decrease in performance when enabled. There are extra draw calls to write depth for * translucent geometry. @@ -2790,6 +2790,10 @@ define([ /** * Returns the cartesian position reconstructed from the depth buffer and window position. + *

+ * Set {@link Scene#pickTranslucentDepth} to true to include the depth of + * translucent primitives; otherwise, this essentially picks through translucent primitives. + *

* * @param {Cartesian2} windowPosition Window coordinates to perform picking on. * @param {Cartesian3} [result] The object on which to restore the result. From acd6b9028daa717a61d009f0601009d6d6cc9996 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Wed, 15 Feb 2017 09:39:44 -0500 Subject: [PATCH 039/115] add culling stats --- Source/Scene/Cesium3DTileset.js | 22 +++++++++++++++---- .../Cesium3DTilesInspectorViewModel.js | 5 +++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 1c9b7f325462..915fe2cb0266 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -272,6 +272,8 @@ define([ // Styling stats numberOfTilesStyled : 0, numberOfFeaturesStyled : 0, + // Optimization stats + numberOfTilesCulledWithChildrenUnion : 0, lastColor : new Cesium3DTilesetStatistics(), lastPick : new Cesium3DTilesetStatistics() @@ -471,6 +473,7 @@ define([ this.numberTotal = 0; this.numberOfTilesStyled = 0; this.numberOfFeaturesStyled = 0; + this.numberOfTilesCulledWithChildrenUnion = 0; } defineProperties(Cesium3DTileset.prototype, { @@ -1342,6 +1345,8 @@ define([ childrenVisibility = computeChildrenVisibility(t, frameState, false); if ((childrenVisibility & Cesium3DTileChildrenVisibility.VISIBLE) || childrenLength === 0) { selectTile(tileset, t, fullyVisible, frameState); + } else { + ++stats.numberOfTilesCulledWithChildrenUnion; } } else { selectTile(tileset, t, fullyVisible, frameState); @@ -1388,6 +1393,8 @@ define([ } } } + } else if (useChildrenBoundUnion) { + ++stats.numberOfTilesCulledWithChildrenUnion; } } else { // Tile does not meet SSE and its children are loaded. Refine to them in front-to-back order. @@ -1413,6 +1420,8 @@ define([ // Even though the children are all loaded they may not be visible if the camera // is not inside their request volumes. selectTile(tileset, t, fullyVisible, frameState); + } else if (useChildrenBoundUnion) { + ++stats.numberOfTilesCulledWithChildrenUnion; } } } else { @@ -1424,10 +1433,6 @@ define([ updateTransforms(children, t.computedTransform); childrenVisibility = computeChildrenVisibility(t, frameState, true); - if (useChildrenBoundUnion && childrenVisibility === Cesium3DTileChildrenVisibility.NONE && childrenLength !== 0) { - continue; - } - var allVisibleChildrenLoaded = true; var someVisibleChildrenLoaded = false; for (k = 0; k < childrenLength; ++k) { @@ -1441,6 +1446,13 @@ define([ } } + if (useChildrenBoundUnion && childrenVisibility === Cesium3DTileChildrenVisibility.NONE && childrenLength !== 0) { + if (allVisibleChildrenLoaded && !someVisibleChildrenLoaded) { + ++stats.numberOfTilesCulledWithChildrenUnion; + } + continue; + } + if (allVisibleChildrenLoaded && !someVisibleChildrenLoaded) { // No children are visible, select this tile selectTile(tileset, t, fullyVisible, frameState); @@ -1585,6 +1597,7 @@ define([ stats.numberOfAttemptedRequests = 0; stats.numberOfTilesStyled = 0; stats.numberOfFeaturesStyled = 0; + stats.numberOfTilesCulledWithChildrenUnion = 0; } function updateLastStats(tileset, isPick) { @@ -1601,6 +1614,7 @@ define([ last.numberTotal = stats.numberTotal; last.numberOfTilesStyled = stats.numberOfTilesStyled; last.numberOfFeaturesStyled = stats.numberOfFeaturesStyled; + last.numberOfTilesCulledWithChildrenUnion = stats.numberOfTilesCulledWithChildrenUnion; } function updateTiles(tileset, frameState) { diff --git a/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js b/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js index 90017a1089eb..48b222278d2c 100644 --- a/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js +++ b/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js @@ -637,6 +637,11 @@ define([ '
  • Tiles styled: ' + stats.numberOfTilesStyled + '
  • ' + '
  • Features styled: ' + stats.numberOfFeaturesStyled + '
  • '; s += ''; + s += '
      '; + s += + // --- Optimization stats + '
    • Children Union Culled: ' + stats.numberOfTilesCulledWithChildrenUnion + '
    • '; + s += '
    '; } if (isPick) { From 504f5e791953be1cbd7ab4108a5fa8fe8880c96c Mon Sep 17 00:00:00 2001 From: Sean Lilley Date: Wed, 15 Feb 2017 10:24:05 -0500 Subject: [PATCH 040/115] Prevent tiles from being unloaded --- Source/Scene/Cesium3DTileset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 21543fccd1dd..3ac6a4159aff 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -1315,7 +1315,7 @@ define([ selectTile(tileset, t, fullyVisible, frameState); if (outOfCore) { - for (k = 0; (k < childrenLength) && t.canRequestContent(); ++k) { + for (k = 0; k < childrenLength; ++k) { child = children[k]; // PERFORMANCE_IDEA: we could spin a bit less CPU here by keeping separate lists for unloaded/ready children. if (child.contentUnloaded) { From 5b1f3871940208e192bd5dfbf8f7981dca98a746 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Wed, 15 Feb 2017 11:32:04 -0500 Subject: [PATCH 041/115] update documentation --- Source/Scene/Cesium3DTileOptimizations.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Cesium3DTileOptimizations.js b/Source/Scene/Cesium3DTileOptimizations.js index b5b9b08cc6e7..219c7ecc30d3 100644 --- a/Source/Scene/Cesium3DTileOptimizations.js +++ b/Source/Scene/Cesium3DTileOptimizations.js @@ -43,7 +43,8 @@ define([ * Checks and optionnally evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if children bounds are * fully contained within the parent. Currently, support for the optimization only works for oriented bounding boxes, so both the child and parent tile * must be either a {@link TileOrientedBoundingBox} or {@link TileBoundingRegion}. The purpose of this check is to prevent use of a culling optimization - * when the child bounds exceed those of the parent. + * when the child bounds exceed those of the parent. If the child bounds are greater, it is more likely that the optimization will waste CPU cycles. Bounding + * spheres are not supported for the reason that the child bounds can very often be partially outside of the parent bounds. * * @param {Cesium3DTile} tile The tile to check. * @param {Boolean} [evaluate=false] Whether to evaluate support if support for the childrenWithinParent optimization is Cesium3DTileOptimizations.Hints.NOT_COMPUTED From 12b9112d8c11fdd5a98f9744e60f8a5f56532969 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Wed, 15 Feb 2017 12:21:43 -0500 Subject: [PATCH 042/115] simplify storage of optimization hints --- Source/Scene/Axis.js | 2 +- Source/Scene/Cesium3DTile.js | 9 ++++- Source/Scene/Cesium3DTileOptimizationHint.js | 2 +- Source/Scene/Cesium3DTileOptimizations.js | 35 ++++++-------------- Source/Scene/Cesium3DTileset.js | 8 +++-- 5 files changed, 26 insertions(+), 30 deletions(-) diff --git a/Source/Scene/Axis.js b/Source/Scene/Axis.js index e98bf2f81466..a4942b6f5290 100644 --- a/Source/Scene/Axis.js +++ b/Source/Scene/Axis.js @@ -50,7 +50,7 @@ define([ * @type {Matrix4} * @constant */ - Y_UP_TO_Z_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)), + Y_UP_TO_Z_UP : Matrix4.IDENTITY, // Matrix4.fromRotationTranslation(Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)), /** * Matrix used to convert from z-up to y-up diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index 65e0d016927a..5f6b9441f3f6 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -27,6 +27,7 @@ define([ './Cesium3DTileContentFactory', './Cesium3DTileContentState', './Cesium3DTileOptimizations', + './Cesium3DTileOptimizationHint', './Cesium3DTileRefine', './Empty3DTileContent', './PerInstanceColorAppearance', @@ -63,6 +64,7 @@ define([ Cesium3DTileContentFactory, Cesium3DTileContentState, Cesium3DTileOptimizations, + Cesium3DTileOptimizationHint, Cesium3DTileRefine, Empty3DTileContent, PerInstanceColorAppearance, @@ -345,7 +347,12 @@ define([ this._debugColor = new Color.fromRandom({ alpha : 1.0 }); this._debugColorizeTiles = false; - this._optimizations = new Cesium3DTileOptimizations(); + /** + * Marks whether the tile's children bounds are fully contained within the tile's bounds + * + * @type {Cesium3DTileOptimizationHint} + */ + this._optimChildrenWithinParent = Cesium3DTileOptimizationHint.NOT_COMPUTED; } defineProperties(Cesium3DTile.prototype, { diff --git a/Source/Scene/Cesium3DTileOptimizationHint.js b/Source/Scene/Cesium3DTileOptimizationHint.js index e44697e0ca1e..337717ba8e67 100644 --- a/Source/Scene/Cesium3DTileOptimizationHint.js +++ b/Source/Scene/Cesium3DTileOptimizationHint.js @@ -8,7 +8,7 @@ define([ /** * @private * - * @alias Cesium3DTileOptimizationHint + * @exports Cesium3DTileOptimizationHint * * Hint defining optimization support for a 3D tile */ diff --git a/Source/Scene/Cesium3DTileOptimizations.js b/Source/Scene/Cesium3DTileOptimizations.js index 219c7ecc30d3..e4afc67005de 100644 --- a/Source/Scene/Cesium3DTileOptimizations.js +++ b/Source/Scene/Cesium3DTileOptimizations.js @@ -16,31 +16,18 @@ define([ 'use strict'; /** - * Defines optional optimization hints for a {@link Cesium3DTileset}. - * Optimizations marked as {@link Cesium3DTileOptimizationHint.USE_OPTIMIZATION} or {@link Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION} - * will not be evaluated at runtime - * + * Utiility functions for computing optimization hints for a {@link Cesium3DTileset}. + * * @private * - * @alias Cesium3DTileOptimizations - * @constructor + * @exports Cesium3DTileOptimizations */ - function Cesium3DTileOptimizations(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); - - /** - * Denotes support for if the childrenWithinParent optimization is supported. This is used to more tightly cull tilesets if children bounds are - * fully contained within the parent. - * - * @type {Cesium3DTileOptimizationHint} - */ - this.childrenWithinParent = defaultValue(options.childrenWithinParent, Cesium3DTileOptimizationHint.NOT_COMPUTED); - } + var Cesium3DTileOptimizations = {}; var scratchAxis = new Cartesian3(); /** - * Checks and optionnally evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if children bounds are + * Checks and optionally evaluates support for the childrenWithinParent optimization. This is used to more tightly cull tilesets if children bounds are * fully contained within the parent. Currently, support for the optimization only works for oriented bounding boxes, so both the child and parent tile * must be either a {@link TileOrientedBoundingBox} or {@link TileBoundingRegion}. The purpose of this check is to prevent use of a culling optimization * when the child bounds exceed those of the parent. If the child bounds are greater, it is more likely that the optimization will waste CPU cycles. Bounding @@ -51,11 +38,11 @@ define([ * @param {Boolean} [force=false] Whether to always evaluate support for the childrenWithinParent optimization * @returns {Boolean} Whether the childrenWithinParent optimization is supported. */ - Cesium3DTileOptimizations.prototype.checkChildrenWithinParent = function(tile, evaluate, force) { + Cesium3DTileOptimizations.checkChildrenWithinParent = function(tile, evaluate, force) { evaluate = defaultValue(evaluate, false); force = defaultValue(force, false); - if ((this.childrenWithinParent === Cesium3DTileOptimizationHint.NOT_COMPUTED && evaluate) || force) { + if ((tile._optimChildrenWithinParent === Cesium3DTileOptimizationHint.NOT_COMPUTED && evaluate) || force) { var children = tile.children; var length = children.length; @@ -63,7 +50,7 @@ define([ var boundingVolume = tile._boundingVolume; if (boundingVolume instanceof TileOrientedBoundingBox || boundingVolume instanceof TileBoundingRegion) { var orientedBoundingBox = boundingVolume._orientedBoundingBox; - this.childrenWithinParent = Cesium3DTileOptimizationHint.USE_OPTIMIZATION; + tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.USE_OPTIMIZATION; for (var i = 0; i < length; ++i) { var child = children[i]; @@ -103,20 +90,20 @@ define([ // If the child extends the parent's bounds, the optimization is not valid and we skip it. if (proj1 <= proj2 + axisLength) { - this.childrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; + tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; break; } } else { // Do not support if the parent and child both do not have oriented bounding boxes. - this.childrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; + tile._optimChildrenWithinParent = Cesium3DTileOptimizationHint.SKIP_OPTIMIZATION; break; } } } } - return this.childrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION ? true : false; + return tile._optimChildrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION ? true : false; } return Cesium3DTileOptimizations; diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 915fe2cb0266..bad58231c437 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -28,6 +28,7 @@ define([ './Cesium3DTile', './Cesium3DTileChildrenVisibility', './Cesium3DTileColorBlendMode', + './Cesium3DTileOptimizations', './Cesium3DTileOptimizationHint', './Cesium3DTileRefine', './Cesium3DTileStyleEngine', @@ -67,6 +68,7 @@ define([ Cesium3DTile, Cesium3DTileChildrenVisibility, Cesium3DTileColorBlendMode, + Cesium3DTileOptimizations, Cesium3DTileOptimizationHint, Cesium3DTileRefine, Cesium3DTileStyleEngine, @@ -278,7 +280,7 @@ define([ lastColor : new Cesium3DTilesetStatistics(), lastPick : new Cesium3DTilesetStatistics() }; - + this._tilesLoaded = false; /** @@ -923,7 +925,7 @@ define([ } } } - tile3D._optimizations.checkChildrenWithinParent(tile3D, true); + Cesium3DTileOptimizations.checkChildrenWithinParent(tile3D, true); if (tile3D.hasContent && hasEmptyChild && (tile3D.refine === Cesium3DTileRefine.REPLACE)) { // Tiles that use replacement refinement and have empty child tiles need to keep track of // descendants with content in order to refine correctly. @@ -1334,7 +1336,7 @@ define([ // With replacement refinement, if the tile's SSE // is not sufficient, its children (or ancestors) are // rendered instead - var useChildrenBoundUnion = t._optimizations.childrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION; + var useChildrenBoundUnion = t._optimChildrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION; var childrenVisibility; From 907293894c87b11cba8bf5cbb70065e40486042c Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Wed, 15 Feb 2017 12:28:06 -0500 Subject: [PATCH 043/115] syntax --- Source/Scene/Axis.js | 2 +- Source/Scene/Cesium3DTileChildrenVisibility.js | 2 +- Source/Scene/Cesium3DTileOptimizationHint.js | 2 +- Source/Scene/Cesium3DTileOptimizations.js | 2 +- Source/Scene/Cesium3DTileset.js | 2 +- Specs/Scene/Cesium3DTilesetSpec.js | 5 ----- 6 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Source/Scene/Axis.js b/Source/Scene/Axis.js index a4942b6f5290..e98bf2f81466 100644 --- a/Source/Scene/Axis.js +++ b/Source/Scene/Axis.js @@ -50,7 +50,7 @@ define([ * @type {Matrix4} * @constant */ - Y_UP_TO_Z_UP : Matrix4.IDENTITY, // Matrix4.fromRotationTranslation(Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)), + Y_UP_TO_Z_UP : Matrix4.fromRotationTranslation(Matrix3.fromRotationX(CesiumMath.PI_OVER_TWO)), /** * Matrix used to convert from z-up to y-up diff --git a/Source/Scene/Cesium3DTileChildrenVisibility.js b/Source/Scene/Cesium3DTileChildrenVisibility.js index 913532b210b4..5715f0375818 100644 --- a/Source/Scene/Cesium3DTileChildrenVisibility.js +++ b/Source/Scene/Cesium3DTileChildrenVisibility.js @@ -16,4 +16,4 @@ define([ }; return freezeObject(Cesium3DTileChildrenVisibility); -}); \ No newline at end of file +}); diff --git a/Source/Scene/Cesium3DTileOptimizationHint.js b/Source/Scene/Cesium3DTileOptimizationHint.js index 337717ba8e67..9665c56a7da0 100644 --- a/Source/Scene/Cesium3DTileOptimizationHint.js +++ b/Source/Scene/Cesium3DTileOptimizationHint.js @@ -19,4 +19,4 @@ define([ }; return freezeObject(Cesium3DTileOptimizationHint); -}); \ No newline at end of file +}); diff --git a/Source/Scene/Cesium3DTileOptimizations.js b/Source/Scene/Cesium3DTileOptimizations.js index e4afc67005de..37de166405d4 100644 --- a/Source/Scene/Cesium3DTileOptimizations.js +++ b/Source/Scene/Cesium3DTileOptimizations.js @@ -104,7 +104,7 @@ define([ } return tile._optimChildrenWithinParent === Cesium3DTileOptimizationHint.USE_OPTIMIZATION ? true : false; - } + }; return Cesium3DTileOptimizations; }); diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index bad58231c437..014ef052ca82 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -1197,7 +1197,7 @@ define([ } } - child.visibilityPlaneMask = visibilityMask + child.visibilityPlaneMask = visibilityMask; } tile.childrenVisibility = flag; diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index c8f0ea87517a..2d186563bd78 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -857,7 +857,6 @@ defineSuite([ } }); - var stats = tileset._statistics; var root = tileset._root; var child_root = root.children[0]; @@ -877,7 +876,6 @@ defineSuite([ it ('does not select visible tiles not meeting SSE with visible children', function() { return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { - var stats = tileset._statistics; var root = tileset._root; var child_root = root.children[0]; child_root.geometricError = 240; @@ -907,7 +905,6 @@ defineSuite([ it ('does select visible tiles meeting SSE with visible children', function() { return Cesium3DTilesTester.loadTileset(scene, tilesetReplacementWithViewerRequestVolumeUrl).then(function(tileset) { - var stats = tileset._statistics; var root = tileset._root; var child_root = root.children[0]; @@ -946,7 +943,6 @@ defineSuite([ } }); - var stats = tileset._statistics; var root = tileset._root; var child_root = root.children[0]; child_root.geometricError = 0; @@ -976,7 +972,6 @@ defineSuite([ } }); - var stats = tileset._statistics; var root = tileset._root; var child_root = root.children[0]; child_root.geometricError = 0; From 3bb0a9efe25d67c5281d9b973311b9907f6c136a Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 15 Feb 2017 14:26:11 -0500 Subject: [PATCH 044/115] Update doc after merge. --- Source/Scene/Scene.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index b7e9919bea4e..1beb8e48f1bb 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -2894,6 +2894,10 @@ define([ * reconstructed in 3D and Columbus view. This is caused by the difference in the distribution * of depth values of perspective and orthographic projection. *

    + *

    + * Set {@link Scene#pickTranslucentDepth} to true to include the depth of + * translucent primitives; otherwise, this essentially picks through translucent primitives. + *

    * * @param {Cartesian2} windowPosition Window coordinates to perform picking on. * @param {Cartesian3} [result] The object on which to restore the result. From c253d06a519f75c3ad5dbeac55dc4ff1f6db8d5b Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Wed, 15 Feb 2017 15:09:53 -0500 Subject: [PATCH 045/115] Report feature and point counts in inspector --- Source/Scene/Batched3DModel3DTileContent.js | 3 +++ Source/Scene/Cesium3DTileset.js | 13 +++++++++++++ Source/Scene/Instanced3DModel3DTileContent.js | 3 +++ Source/Scene/PointCloud3DTileContent.js | 4 ++++ .../Cesium3DTilesInspectorViewModel.js | 8 ++++++++ 5 files changed, 31 insertions(+) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 1fd6ce2dddc2..b254a4c1f4e3 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -329,6 +329,7 @@ define([ model.readyPromise.then(function(model) { that.state = Cesium3DTileContentState.READY; + that._tileset._statistics.numberOfFeaturesLoaded += that.featuresLength; that._readyPromise.resolve(that); }).otherwise(function(error) { that.state = Cesium3DTileContentState.FAILED; @@ -368,6 +369,7 @@ define([ this._model.shadows = this._tileset.shadows; this._model.debugWireframe = this._tileset.debugWireframe; this._model.update(frameState); + tileset._statistics.numberOfFeaturesSelected += this.featuresLength; frameState.addCommand = oldAddCommand; }; @@ -383,6 +385,7 @@ define([ * Part of the {@link Cesium3DTileContent} interface. */ Batched3DModel3DTileContent.prototype.destroy = function() { + this._tileset._statistics.numberOfFeaturesLoaded -= this.featuresLength; this._model = this._model && this._model.destroy(); this.batchTable = this.batchTable && this.batchTable.destroy(); return destroyObject(this); diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 21543fccd1dd..a055172e55c4 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -263,6 +263,11 @@ define([ numberProcessing : 0, numberContentReady : 0, // Number of tiles with content loaded, does not include empty tiles numberTotal : 0, // Number of tiles in tileset.json (and other tileset.json files as they are loaded) + // Features stats + numberOfFeaturesSelected : 0, // number of features rendered + numberOfFeaturesLoaded : 0, // number of features in memory + numberOfPointFeaturesSelected: 0, + numberOfPointFeaturesLoaded: 0, // Styling stats numberOfTilesStyled : 0, numberOfFeaturesStyled : 0, @@ -463,6 +468,8 @@ define([ this.numberProcessing = 0; this.numberContentReady = 0; this.numberTotal = 0; + this.numberOfFeaturesSelected = 0; + this.numberOfFeaturesLoaded = 0; this.numberOfTilesStyled = 0; this.numberOfFeaturesStyled = 0; } @@ -1528,6 +1535,8 @@ define([ stats.numberOfAttemptedRequests = 0; stats.numberOfTilesStyled = 0; stats.numberOfFeaturesStyled = 0; + stats.numberOfFeaturesSelected = 0; + stats.numberOfPointFeaturesSelected = 0; } function updateLastStats(tileset, isPick) { @@ -1542,6 +1551,10 @@ define([ last.numberProcessing = stats.numberProcessing; last.numberContentReady = stats.numberContentReady; last.numberTotal = stats.numberTotal; + last.numberOfFeaturesSelected = stats.numberOfFeaturesSelected; + last.numberOfFeaturesLoaded = stats.numberOfFeaturesLoaded; + last.numberOfPointFeaturesSelected = stats.numberOfPointFeaturesSelected; + last.numberOfPointFeaturesLoaded = stats.numberOfPointFeaturesLoaded; last.numberOfTilesStyled = stats.numberOfTilesStyled; last.numberOfFeaturesStyled = stats.numberOfFeaturesStyled; } diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 22434d54f993..a4d0deaf7719 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -446,6 +446,7 @@ define([ modelInstanceCollection.readyPromise.then(function(modelInstanceCollection) { that.state = Cesium3DTileContentState.READY; + that._tileset._statistics.numberOfFeaturesLoaded += that.featuresLength; that._readyPromise.resolve(that); }).otherwise(function(error) { that.state = Cesium3DTileContentState.FAILED; @@ -485,6 +486,7 @@ define([ this._modelInstanceCollection.shadows = this._tileset.shadows; this._modelInstanceCollection.debugWireframe = this._tileset.debugWireframe; this._modelInstanceCollection.update(frameState); + tileset._statistics.numberOfFeaturesSelected += this.featuresLength; frameState.addCommand = oldAddCommand; }; @@ -500,6 +502,7 @@ define([ * Part of the {@link Cesium3DTileContent} interface. */ Instanced3DModel3DTileContent.prototype.destroy = function() { + this._tileset._statistics.numberOfFeaturesLoaded -= this.featuresLength; this._modelInstanceCollection = this._modelInstanceCollection && this._modelInstanceCollection.destroy(); this.batchTable = this.batchTable && this.batchTable.destroy(); diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index 91749ec79b18..5d14c88c6c71 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -1168,6 +1168,7 @@ define([ // Set state to ready this.state = Cesium3DTileContentState.READY; + tileset._statistics.numberOfPointFeaturesLoaded += this.featuresLength; this._readyPromise.resolve(this); this._parsedContent = undefined; // Unload } @@ -1228,6 +1229,8 @@ define([ if (passes.pick) { frameState.addCommand(this._pickCommand); } + + tileset._statistics.numberOfPointFeaturesSelected += this.featuresLength; }; /** @@ -1241,6 +1244,7 @@ define([ * Part of the {@link Cesium3DTileContent} interface. */ PointCloud3DTileContent.prototype.destroy = function() { + this._tileset._statistics.numberOfPointFeaturesLoaded -= this.featuresLength; var command = this._drawCommand; var pickCommand = this._pickCommand; if (defined(command)) { diff --git a/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js b/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js index 90017a1089eb..340371813e29 100644 --- a/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js +++ b/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js @@ -632,6 +632,14 @@ define([ '
  • Total: ' + stats.numberTotal + '
  • '; s += ''; s += '
      '; + s += + // --- Features stats + '
    • Features Selected: ' + stats.numberOfFeaturesSelected + '
    • ' + + '
    • Features Loaded: ' + stats.numberOfFeaturesLoaded + '
    • ' + + '
    • Points Selected: ' + stats.numberOfPointFeaturesSelected + '
    • ' + + '
    • Points Loaded: ' + stats.numberOfPointFeaturesLoaded + '
    • '; + s += '
    '; + s += '
      '; s += // --- Styling stats '
    • Tiles styled: ' + stats.numberOfTilesStyled + '
    • ' + From a49219bb1b41c1e1d10ce03e47b286b68c7ab818 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 15 Feb 2017 15:27:02 -0500 Subject: [PATCH 046/115] Use previous frame's commands. Disable compute and shadow commands from executing on depth only pass. --- Source/Scene/Scene.js | 51 +++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 1beb8e48f1bb..768924a29e11 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -569,7 +569,7 @@ define([ * @type {Boolean} * @default false */ - this.pickTranslucentDepth = false; + this.pickTranslucentDepth = true;//false; /** * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. @@ -1226,6 +1226,7 @@ define([ function clearPasses(passes) { passes.render = false; passes.pick = false; + passes.depth = false; } function updateFrameState(scene, frameNumber, time) { @@ -1752,7 +1753,9 @@ define([ us.updatePass(Pass.ENVIRONMENT); var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; - var picking = scene._frameState.passes.pick; + var passes = scene._frameState.passes; + var picking = passes.pick; + var depthOnly = passes.depth; var environmentState = scene._environmentState; // Do not render environment primitives during a pick pass since they do not generate picking commands. @@ -1901,10 +1904,11 @@ define([ commands.length = frustumCommands.indices[Pass.TRANSLUCENT]; executeTranslucentCommands(scene, executeCommand, passState, commands); - if (defined(globeDepth) && environmentState.useGlobeDepthFramebuffer && scene.useDepthPicking) { + if (defined(globeDepth) && (environmentState.useGlobeDepthFramebuffer || depthOnly) && scene.useDepthPicking) { // PERFORMANCE_IDEA: Use MRT to avoid the extra copy. + var depthStencilTexture = depthOnly ? passState.framebuffer.depthStencilTexture : globeDepth.framebuffer.depthStencilTexture; var pickDepth = getPickDepth(scene, index); - pickDepth.update(context, globeDepth.framebuffer.depthStencilTexture); + pickDepth.update(context, depthStencilTexture); pickDepth.executeCopyDepth(context, passState); } } @@ -2031,13 +2035,20 @@ define([ var frameState = scene._frameState; var camera = frameState.camera; var mode = frameState.mode; + var depthOnly = frameState.passes.depth; if (scene._useWebVR && mode !== SceneMode.SCENE2D) { - updatePrimitives(scene); + if (!depthOnly) { + updatePrimitives(scene); + } + createPotentiallyVisibleSet(scene); updateAndClearFramebuffers(scene, passState, backgroundColor); - executeComputeCommands(scene); - executeShadowMapCastCommands(scene); + + if (!depthOnly) { + executeComputeCommands(scene); + executeShadowMapCastCommands(scene); + } // Based on Calculating Stereo pairs by Paul Bourke // http://paulbourke.net/stereographics/stereorender/ @@ -2206,17 +2217,24 @@ define([ } function executeCommandsInViewport(firstViewport, scene, passState, backgroundColor) { - if (!firstViewport) { + var depthOnly = scene.frameState.passes.depth; + + if (!firstViewport && !depthOnly) { scene.frameState.commandList.length = 0; } - updatePrimitives(scene); + if (!depthOnly) { + updatePrimitives(scene); + } + createPotentiallyVisibleSet(scene); if (firstViewport) { updateAndClearFramebuffers(scene, passState, backgroundColor); - executeComputeCommands(scene); - executeShadowMapCastCommands(scene); + if (!depthOnly) { + executeComputeCommands(scene); + executeShadowMapCastCommands(scene); + } } executeCommands(scene, passState); @@ -2335,7 +2353,6 @@ define([ var passes = scene._frameState.passes; var picking = passes.pick; - var pickDepth = passes.depth; var useWebVR = scene._useWebVR && scene.mode !== SceneMode.SCENE2D; // Preserve the reference to the original framebuffer. @@ -2361,7 +2378,7 @@ define([ clear.execute(context, passState); // Update globe depth rendering based on the current context and clear the globe depth framebuffer. - var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = (!picking || pickDepth) && defined(scene._globeDepth); + var useGlobeDepthFramebuffer = environmentState.useGlobeDepthFramebuffer = !picking && defined(scene._globeDepth); if (useGlobeDepthFramebuffer) { scene._globeDepth.update(context); scene._globeDepth.clear(context, passState, clearColor); @@ -2726,16 +2743,12 @@ define([ function renderTranslucentDepthForPick(scene, drawingBufferPosition) { // PERFORMANCE_IDEA: render translucent only and merge with the previous frame var context = scene._context; - var us = context.uniformState; var frameState = scene._frameState; - // Update with previous frame's number and time, assuming that render is called before picking. - updateFrameState(scene, frameState.frameNumber, frameState.time); - frameState.cullingVolume = getPickCullingVolume(scene, drawingBufferPosition, 1, 1); + clearPasses(frameState.passes); frameState.passes.pick = true; frameState.passes.depth = true; - - us.update(frameState); + frameState.cullingVolume = getPickCullingVolume(scene, drawingBufferPosition, 1, 1); var passState = scene._pickDepthPassState; if (!defined(passState)) { From f7bc4ee888ce5cd8705f1f7ad1b4dc6ffc2a0374 Mon Sep 17 00:00:00 2001 From: greenkeeperio-bot Date: Wed, 15 Feb 2017 15:27:24 -0500 Subject: [PATCH 047/115] chore(package): update aws-sdk to version 2.14.0 https://greenkeeper.io/ --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dc7ef5d514cc..4564b6cd17b6 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "almond": "^0.3.3", - "aws-sdk": "^2.13.0", + "aws-sdk": "^2.14.0", "bluebird": "^3.4.6", "compressible": "^2.0.9", "compression": "^1.6.2", From 1e5641bfbc67c104a558391f55862e3c6434862f Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Wed, 15 Feb 2017 15:40:15 -0500 Subject: [PATCH 048/115] return 0 features if instanced 3d tile content has no model collection --- Source/Scene/Instanced3DModel3DTileContent.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index a4d0deaf7719..fba0982d1e6a 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -101,7 +101,11 @@ define([ */ featuresLength : { get : function() { - return this._modelInstanceCollection.length; + if (defined(this._modelInstanceCollection)) { + return this._modelInstanceCollection.length; + } else { + return 0; + } } }, From 3ad9ff6b43049b4fb8f74e5b61fb1f40637d6484 Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Wed, 15 Feb 2017 15:57:33 -0500 Subject: [PATCH 049/115] check tileset statistics before updating counts --- Source/Scene/Batched3DModel3DTileContent.js | 4 +++- Source/Scene/Instanced3DModel3DTileContent.js | 4 +++- Source/Scene/PointCloud3DTileContent.js | 8 ++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index b254a4c1f4e3..df3c1fabbe4b 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -369,7 +369,9 @@ define([ this._model.shadows = this._tileset.shadows; this._model.debugWireframe = this._tileset.debugWireframe; this._model.update(frameState); - tileset._statistics.numberOfFeaturesSelected += this.featuresLength; + if (defined(tileset._statistics)) { + tileset._statistics.numberOfFeaturesSelected += this.featuresLength; + } frameState.addCommand = oldAddCommand; }; diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index fba0982d1e6a..876390cb7724 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -490,7 +490,9 @@ define([ this._modelInstanceCollection.shadows = this._tileset.shadows; this._modelInstanceCollection.debugWireframe = this._tileset.debugWireframe; this._modelInstanceCollection.update(frameState); - tileset._statistics.numberOfFeaturesSelected += this.featuresLength; + if (defined(tileset._statistics)) { + tileset._statistics.numberOfFeaturesSelected += this.featuresLength; + } frameState.addCommand = oldAddCommand; }; diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index 5d14c88c6c71..d9e74dad960a 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -1168,7 +1168,9 @@ define([ // Set state to ready this.state = Cesium3DTileContentState.READY; - tileset._statistics.numberOfPointFeaturesLoaded += this.featuresLength; + if (defined(tileset._statistics)) { + tileset._statistics.numberOfPointFeaturesLoaded += this.featuresLength; + } this._readyPromise.resolve(this); this._parsedContent = undefined; // Unload } @@ -1230,7 +1232,9 @@ define([ frameState.addCommand(this._pickCommand); } - tileset._statistics.numberOfPointFeaturesSelected += this.featuresLength; + if (defined(tileset._statistics)) { + tileset._statistics.numberOfPointFeaturesSelected += this.featuresLength; + } }; /** From eb5678370864dbc5f2d09903fbb446e62d677a56 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 15 Feb 2017 16:11:10 -0500 Subject: [PATCH 050/115] Create derived command with pass through fragment shader, depth writes enabled, and color writes disabled. Revert PassState depth mask overwrites. --- Source/Renderer/PassState.js | 13 ----- Source/Renderer/RenderState.js | 15 +++-- Source/Scene/Scene.js | 100 ++++++++++++++++++++++++++++++++- 3 files changed, 106 insertions(+), 22 deletions(-) diff --git a/Source/Renderer/PassState.js b/Source/Renderer/PassState.js index 92c935ad98fd..4a0e5515143a 100644 --- a/Source/Renderer/PassState.js +++ b/Source/Renderer/PassState.js @@ -56,19 +56,6 @@ define([], function() { * @default undefined */ this.viewport = undefined; - - /** - * When defined, this overrides the depth mask property of a {@link DrawCommand}'s render state. - * This is used to, for example, to allow the renderer to enable depth writes for picking translucent - * geometry. - *

      - * When this is undefined, the {@link DrawCommand}'s property is used. - *

      - * - * @type {Boolean} - * @default undefined - */ - this.depthMask = undefined; } return PassState; diff --git a/Source/Renderer/RenderState.js b/Source/Renderer/RenderState.js index 379106cca0e6..93c074526257 100644 --- a/Source/Renderer/RenderState.js +++ b/Source/Renderer/RenderState.js @@ -549,9 +549,8 @@ define([ gl.colorMask(colorMask.red, colorMask.green, colorMask.blue, colorMask.alpha); } - function applyDepthMask(gl, renderState, passState) { - var mask = defined(passState.depthMask) ? passState.depthMask : renderState.depthMask; - gl.depthMask(mask); + function applyDepthMask(gl, renderState) { + gl.depthMask(renderState.depthMask); } function applyStencilMask(gl, renderState) { @@ -642,10 +641,10 @@ define([ applyDepthRange(gl, renderState); applyDepthTest(gl, renderState); applyColorMask(gl, renderState); + applyDepthMask(gl, renderState); applyStencilMask(gl, renderState); applyStencilTest(gl, renderState); applySampleCoverage(gl, renderState); - applyDepthMask(gl, renderState, passState); applyScissorTest(gl, renderState, passState); applyBlending(gl, renderState, passState); applyViewport(gl, renderState, passState); @@ -687,6 +686,10 @@ define([ funcs.push(applyColorMask); } + if (previousState.depthMask !== nextState.depthMask) { + funcs.push(applyDepthMask); + } + if (previousState.stencilMask !== nextState.stencilMask) { funcs.push(applyStencilMask); } @@ -752,10 +755,6 @@ define([ if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { applyViewport(gl, renderState, passState); } - - if (previousRenderState !== renderState || previousPassState !== passState || previousPassState.context !== passState.context) { - applyDepthMask(gl, renderState, passState); - } }; RenderState.getState = function(renderState) { diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 768924a29e11..228d28186938 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -40,6 +40,7 @@ define([ '../Renderer/Pass', '../Renderer/PassState', '../Renderer/PixelDatatype', + '../Renderer/RenderState', '../Renderer/ShaderProgram', '../Renderer/ShaderSource', '../Renderer/Texture', @@ -112,6 +113,7 @@ define([ Pass, PassState, PixelDatatype, + RenderState, ShaderProgram, ShaderSource, Texture, @@ -1203,6 +1205,8 @@ define([ derivedCommands.oit = oit.createDerivedCommands(command, context, derivedCommands.oit); } } + + derivedCommands.depth = createDepthOnlyDerivedCommand(command, context, derivedCommands.depth); } } @@ -1601,6 +1605,8 @@ define([ // Some commands, such as OIT derived commands, do not have derived shadow commands themselves // and instead shadowing is built-in. In this case execute the command regularly below. command.derivedCommands.shadows.receiveCommand.execute(context, passState); + } else if (scene.frameState.passes.depth && defined(command.derivedCommands.depth)) { + command.derivedCommands.depth.depthOnlyCommand.execute(context, passState); } else { command.execute(context, passState); } @@ -2740,6 +2746,99 @@ define([ return object; }; + var depthOnlyShaderProgramCache = {}; + var depthOnlyRenderStateCache = {}; + + var fragDepthRegex = /\bgl_FragDepthEXT\b/; + var discardRegex = /\bdiscard\b/; + + function getDepthOnlyShaderProgram(context, shaderProgram) { + var id = shaderProgram.id; + var shader = depthOnlyShaderProgramCache[id]; + if (!defined(shader)) { + var attributeLocations = shaderProgram._attributeLocations; + var fs = shaderProgram.fragmentShaderSource; + + var writesFragDepth = false; + var discards = false; + + var sources = fs.sources; + var length = sources.length; + for (var i = 0; i < length; ++i) { + if (fragDepthRegex.test(sources[i])) { + writesFragDepth = true; + break; + } + if (discardRegex.test(sources[i])) { + discards = true; + break; + } + } + + if (!writesFragDepth && !discards) { + fs = new ShaderSource({ + sources : ['void main() { gl_FragColor = vec4(1.0); }'] + }); + } + + shader = ShaderProgram.fromCache({ + context : context, + vertexShaderSource : shaderProgram.vertexShaderSource, + fragmentShaderSource : fs, + attributeLocations : attributeLocations + }); + + depthOnlyShaderProgramCache[id] = shader; + } + + return shader; + } + + function getDepthOnlyRenderState(context, renderState) { + var depthOnlyState = depthOnlyRenderStateCache[renderState.id]; + if (!defined(depthOnlyState)) { + var rs = RenderState.getState(renderState); + rs.depthMask = true; + rs.colorMask = { + red : false, + green : false, + blue : false, + alpha : false + }; + + depthOnlyState = RenderState.fromCache(rs); + depthOnlyRenderStateCache[renderState.id] = depthOnlyState; + } + + return depthOnlyState; + } + + function createDepthOnlyDerivedCommand(command, context, result) { + if (!defined(result)) { + result = {}; + } + + var shader; + var renderState; + if (defined(result.depthOnlyCommand)) { + shader = result.depthOnlyCommand.shaderProgram; + renderState = result.depthOnlyCommand.renderState; + } + + result.depthOnlyCommand = DrawCommand.shallowClone(command, result.depthOnlyCommand); + + if (!defined(shader) || result.shaderProgramId !== command.shaderProgram.id) { + result.depthOnlyCommand.shaderProgram = getDepthOnlyShaderProgram(context, command.shaderProgram); + result.depthOnlyCommand.renderState = getDepthOnlyRenderState(context, command.renderState); + result.shaderProgramId = command.shaderProgram.id; + } else { + result.depthOnlyCommand.shaderProgram = shader; + result.depthOnlyCommand.renderState = renderState; + } + + return result; + } + function renderTranslucentDepthForPick(scene, drawingBufferPosition) { // PERFORMANCE_IDEA: render translucent only and merge with the previous frame var context = scene._context; @@ -2758,7 +2857,6 @@ define([ rectangle : new BoundingRectangle() }; passState.viewport = new BoundingRectangle(); - passState.depthMask = true; } var width = context.drawingBufferWidth; From 47efc792ecfdd96e386a90124ac4a6c5856d2d70 Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Wed, 15 Feb 2017 16:57:38 -0500 Subject: [PATCH 051/115] Clean up resources and fix tests. --- Source/Scene/Scene.js | 40 ++++++++++++++++++++++++++-------------- Specs/Scene/SceneSpec.js | 33 ++++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/Source/Scene/Scene.js b/Source/Scene/Scene.js index 228d28186938..ee4312a65b8d 100644 --- a/Source/Scene/Scene.js +++ b/Source/Scene/Scene.js @@ -306,6 +306,10 @@ define([ this._pickDepthPassState = undefined; this._pickDepthFramebuffer = undefined; + this._pickDepthFramebufferWidth = undefined; + this._pickDepthFramebufferHeight = undefined; + this._depthOnlyShaderProgramCache = {}; + this._depthOnlyRenderStateCache = {}; this._transitioner = new SceneTransitioner(this); @@ -571,7 +575,7 @@ define([ * @type {Boolean} * @default false */ - this.pickTranslucentDepth = true;//false; + this.pickTranslucentDepth = false; /** * The time in milliseconds to wait before checking if the camera has not moved and fire the cameraMoveEnd event. @@ -1206,7 +1210,7 @@ define([ } } - derivedCommands.depth = createDepthOnlyDerivedCommand(command, context, derivedCommands.depth); + derivedCommands.depth = createDepthOnlyDerivedCommand(scene, command, context, derivedCommands.depth); } } @@ -2746,15 +2750,13 @@ define([ return object; }; - var depthOnlyShaderProgramCache = {}; - var depthOnlyRenderStateCache = {}; - var fragDepthRegex = /\bgl_FragDepthEXT\b/; var discardRegex = /\bdiscard\b/; - function getDepthOnlyShaderProgram(context, shaderProgram) { + function getDepthOnlyShaderProgram(scene, context, shaderProgram) { var id = shaderProgram.id; - var shader = depthOnlyShaderProgramCache[id]; + var cache = scene._depthOnlyShaderProgramCache; + var shader = cache[id]; if (!defined(shader)) { var attributeLocations = shaderProgram._attributeLocations; var fs = shaderProgram.fragmentShaderSource; @@ -2788,14 +2790,15 @@ define([ attributeLocations : attributeLocations }); - depthOnlyShaderProgramCache[id] = shader; + cache[id] = shader; } return shader; } - function getDepthOnlyRenderState(context, renderState) { - var depthOnlyState = depthOnlyRenderStateCache[renderState.id]; + function getDepthOnlyRenderState(scene, renderState) { + var cache = scene._depthOnlyRenderStateCache; + var depthOnlyState = cache[renderState.id]; if (!defined(depthOnlyState)) { var rs = RenderState.getState(renderState); rs.depthMask = true; @@ -2807,13 +2810,13 @@ define([ }; depthOnlyState = RenderState.fromCache(rs); - depthOnlyRenderStateCache[renderState.id] = depthOnlyState; + cache[renderState.id] = depthOnlyState; } return depthOnlyState; } - function createDepthOnlyDerivedCommand(command, context, result) { + function createDepthOnlyDerivedCommand(scene, command, context, result) { if (!defined(result)) { result = {}; } @@ -2828,8 +2831,8 @@ define([ result.depthOnlyCommand = DrawCommand.shallowClone(command, result.depthOnlyCommand); if (!defined(shader) || result.shaderProgramId !== command.shaderProgram.id) { - result.depthOnlyCommand.shaderProgram = getDepthOnlyShaderProgram(context, command.shaderProgram); - result.depthOnlyCommand.renderState = getDepthOnlyRenderState(context, command.renderState); + result.depthOnlyCommand.shaderProgram = getDepthOnlyShaderProgram(scene, context, command.shaderProgram); + result.depthOnlyCommand.renderState = getDepthOnlyRenderState(scene, command.renderState); result.shaderProgramId = command.shaderProgram.id; } else { result.depthOnlyCommand.shaderProgram = shader; @@ -3202,6 +3205,7 @@ define([ this._screenSpaceCameraController = this._screenSpaceCameraController && this._screenSpaceCameraController.destroy(); this._deviceOrientationCameraController = this._deviceOrientationCameraController && !this._deviceOrientationCameraController.isDestroyed() && this._deviceOrientationCameraController.destroy(); this._pickFramebuffer = this._pickFramebuffer && this._pickFramebuffer.destroy(); + this._pickDepthFramebuffer = this._pickDepthFramebuffer && this._pickDepthFramebuffer.destroy(); this._primitives = this._primitives && this._primitives.destroy(); this._groundPrimitives = this._groundPrimitives && this._groundPrimitives.destroy(); this._globe = this._globe && this._globe.destroy(); @@ -3223,6 +3227,14 @@ define([ } this._fxaa.destroy(); + var cache = this._depthOnlyShaderProgramCache; + for (var name in cache) { + if (cache.hasOwnProperty(name) && defined(cache[name])) { + cache[name].destroy(); + } + } + this._depthOnlyShaderProgramCache = {}; + this._context = this._context && this._context.destroy(); this._frameState.creditDisplay.destroy(); if (defined(this._performanceDisplay)){ diff --git a/Specs/Scene/SceneSpec.js b/Specs/Scene/SceneSpec.js index a94eef8c859e..dc8164b9a815 100644 --- a/Specs/Scene/SceneSpec.js +++ b/Specs/Scene/SceneSpec.js @@ -19,7 +19,9 @@ defineSuite([ 'Renderer/Framebuffer', 'Renderer/Pass', 'Renderer/PixelDatatype', + 'Renderer/RenderState', 'Renderer/ShaderProgram', + 'Renderer/ShaderSource', 'Renderer/Texture', 'Scene/Camera', 'Scene/EllipsoidSurfaceAppearance', @@ -55,7 +57,9 @@ defineSuite([ Framebuffer, Pass, PixelDatatype, + RenderState, ShaderProgram, + ShaderSource, Texture, Camera, EllipsoidSurfaceAppearance, @@ -74,9 +78,21 @@ defineSuite([ 'use strict'; var scene; + var simpleShaderProgram; + var simpleRenderState; beforeAll(function() { scene = createScene(); + simpleShaderProgram = ShaderProgram.fromCache({ + context : scene.context, + vertexShaderSource : new ShaderSource({ + sources : ['void main() { gl_Position = vec4(1.0); }'] + }), + fragmentShaderSource : new ShaderSource({ + sources : ['void main() { gl_FragColor = vec4(1.0); }'] + }) + }); + simpleRenderState = new RenderState(); }); afterEach(function() { @@ -199,6 +215,8 @@ defineSuite([ it('debugCommandFilter filters commands', function() { var c = new DrawCommand({ + shaderProgram : simpleShaderProgram, + renderState : simpleRenderState, pass : Pass.OPAQUE }); c.execute = function() {}; @@ -216,6 +234,8 @@ defineSuite([ it('debugCommandFilter does not filter commands', function() { var c = new DrawCommand({ + shaderProgram : simpleShaderProgram, + renderState : simpleRenderState, pass : Pass.OPAQUE }); c.execute = function() {}; @@ -233,6 +253,8 @@ defineSuite([ var center = Cartesian3.add(scene.camera.position, scene.camera.direction, new Cartesian3()); var c = new DrawCommand({ + shaderProgram : simpleShaderProgram, + renderState : simpleRenderState, pass : Pass.OPAQUE, debugShowBoundingVolume : true, boundingVolume : new BoundingSphere(center, radius) @@ -249,13 +271,9 @@ defineSuite([ it('debugShowCommands tints commands', function() { var c = new DrawCommand({ - pass : Pass.OPAQUE, - - shaderProgram : ShaderProgram.fromCache({ - context : scene.context, - vertexShaderSource : 'void main() { gl_Position = vec4(1.0); }', - fragmentShaderSource : 'void main() { gl_FragColor = vec4(1.0); }' - }) + shaderProgram : simpleShaderProgram, + renderState : simpleRenderState, + pass : Pass.OPAQUE }); c.execute = function() {}; @@ -773,6 +791,7 @@ defineSuite([ primitives.add(rectanglePrimitive); scene.useDepthPicking = true; + scene.pickTranslucentDepth = false; expect(scene).toRenderAndCall(function() { var position = scene.pickPosition(windowPosition); expect(position).not.toBeDefined(); From 31854beafd8224f9b01a25cdc960f26551dc5bfd Mon Sep 17 00:00:00 2001 From: Austin Eng <213reeses@gmail.com> Date: Thu, 16 Feb 2017 12:09:32 -0500 Subject: [PATCH 052/115] report pointsLength --- Source/Scene/Cesium3DTileset.js | 10 +++++----- Source/Scene/PointCloud3DTileContent.js | 8 +++++--- .../CesiumInspector/Cesium3DTilesInspectorViewModel.js | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index a055172e55c4..3c985de38757 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -266,8 +266,8 @@ define([ // Features stats numberOfFeaturesSelected : 0, // number of features rendered numberOfFeaturesLoaded : 0, // number of features in memory - numberOfPointFeaturesSelected: 0, - numberOfPointFeaturesLoaded: 0, + numberOfPointsSelected: 0, + numberOfPointsLoaded: 0, // Styling stats numberOfTilesStyled : 0, numberOfFeaturesStyled : 0, @@ -1536,7 +1536,7 @@ define([ stats.numberOfTilesStyled = 0; stats.numberOfFeaturesStyled = 0; stats.numberOfFeaturesSelected = 0; - stats.numberOfPointFeaturesSelected = 0; + stats.numberOfPointsSelected = 0; } function updateLastStats(tileset, isPick) { @@ -1553,8 +1553,8 @@ define([ last.numberTotal = stats.numberTotal; last.numberOfFeaturesSelected = stats.numberOfFeaturesSelected; last.numberOfFeaturesLoaded = stats.numberOfFeaturesLoaded; - last.numberOfPointFeaturesSelected = stats.numberOfPointFeaturesSelected; - last.numberOfPointFeaturesLoaded = stats.numberOfPointFeaturesLoaded; + last.numberOfPointsSelected = stats.numberOfPointsSelected; + last.numberOfPointsLoaded = stats.numberOfPointsLoaded; last.numberOfTilesStyled = stats.numberOfTilesStyled; last.numberOfFeaturesStyled = stats.numberOfFeaturesStyled; } diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index d9e74dad960a..43f7d3234516 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -139,6 +139,7 @@ define([ this._contentReadyToProcessPromise = when.defer(); this._readyPromise = when.defer(); this._features = undefined; + this._pointsLength = 0; } defineProperties(PointCloud3DTileContent.prototype, { @@ -466,6 +467,7 @@ define([ batchIds : batchIds, styleableProperties : styleableProperties }; + this._pointsLength = pointsLength; this._isQuantized = isQuantized; this._isOctEncoded16P = isOctEncoded16P; @@ -1169,7 +1171,7 @@ define([ // Set state to ready this.state = Cesium3DTileContentState.READY; if (defined(tileset._statistics)) { - tileset._statistics.numberOfPointFeaturesLoaded += this.featuresLength; + tileset._statistics.numberOfPointsLoaded += this._pointsLength; } this._readyPromise.resolve(this); this._parsedContent = undefined; // Unload @@ -1233,7 +1235,7 @@ define([ } if (defined(tileset._statistics)) { - tileset._statistics.numberOfPointFeaturesSelected += this.featuresLength; + tileset._statistics.numberOfPointsSelected += this._pointsLength; } }; @@ -1248,7 +1250,7 @@ define([ * Part of the {@link Cesium3DTileContent} interface. */ PointCloud3DTileContent.prototype.destroy = function() { - this._tileset._statistics.numberOfPointFeaturesLoaded -= this.featuresLength; + this._tileset._statistics.numberOfPointsLoaded -= this._pointsLength; var command = this._drawCommand; var pickCommand = this._pickCommand; if (defined(command)) { diff --git a/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js b/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js index 340371813e29..cea70394de8d 100644 --- a/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js +++ b/Source/Widgets/CesiumInspector/Cesium3DTilesInspectorViewModel.js @@ -636,8 +636,8 @@ define([ // --- Features stats '

    • Features Selected: ' + stats.numberOfFeaturesSelected + '
    • ' + '
    • Features Loaded: ' + stats.numberOfFeaturesLoaded + '
    • ' + - '
    • Points Selected: ' + stats.numberOfPointFeaturesSelected + '
    • ' + - '
    • Points Loaded: ' + stats.numberOfPointFeaturesLoaded + '
    • '; + '
    • Points Selected: ' + stats.numberOfPointsSelected + '
    • ' + + '
    • Points Loaded: ' + stats.numberOfPointsLoaded + '
    • '; s += '
    '; s += '