Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3D Tiles - Point Cloud Styling #4336

Merged
merged 31 commits into from Oct 19, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
41fc014
pnts shader styling
lilleyse Sep 19, 2016
46d00e3
Merge branch '3d-tiles' into pnts-styling
lilleyse Sep 20, 2016
8e98836
Organization
lilleyse Sep 20, 2016
b7c2dfd
Rearrange shader construction
lilleyse Sep 20, 2016
cc1c4e6
Reorganize parameters and support ARRAY type
lilleyse Sep 27, 2016
5cb1088
Change conditions from an object to an array
lilleyse Sep 27, 2016
758ebb2
Change how result params are used
lilleyse Sep 27, 2016
9d2838e
Stricter type comparisons
lilleyse Sep 27, 2016
096b15b
Reset scratch index for Expression.evaluate
lilleyse Sep 28, 2016
976f32f
Fix tests
lilleyse Sep 28, 2016
953f9be
Merge branch '3d-tiles' into pnts-styling
lilleyse Sep 28, 2016
1fd4b27
Calculate literal colors right away
lilleyse Sep 28, 2016
dbd681d
Limit array length
lilleyse Sep 28, 2016
75beb23
Added Point Cloud Styling sandcastle
lilleyse Sep 28, 2016
72ee217
Add back TODO
lilleyse Sep 28, 2016
88903d5
More detailed shader error messages, removed type-checking errors in …
lilleyse Sep 29, 2016
62ecd50
Revert ExpressionSpec
lilleyse Sep 29, 2016
7754b66
Reorganzation of styleContent
lilleyse Sep 29, 2016
cab3705
Add BATCH_ID comment
lilleyse Sep 30, 2016
464cee8
Added ability to style based on POSITION, COLOR, and NORMAL semantics
lilleyse Sep 30, 2016
18be9d6
Support DOUBLE, INT, and UNSIGNED_INT point cloud style properties
lilleyse Sep 30, 2016
079d6f6
Added tests
lilleyse Oct 4, 2016
6d8a879
Tweak test for OIT
lilleyse Oct 10, 2016
84d8ff7
Log warning for float conversion
lilleyse Oct 10, 2016
a217024
Style point size
lilleyse Oct 10, 2016
55cf834
Change === to == and !== to !=
lilleyse Oct 10, 2016
8823472
Rename size to pointSize
lilleyse Oct 18, 2016
c04ff78
Support both === and !==
lilleyse Oct 18, 2016
f0f86ad
Merge branch '3d-tiles' into pnts-styling
lilleyse Oct 18, 2016
83efc1b
Fix styling edge case
lilleyse Oct 18, 2016
45d96d8
Merge branch '3d-tiles' into pnts-styling
lilleyse Oct 18, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Apps/Sandcastle/gallery/3D Tiles.html
Expand Up @@ -97,7 +97,7 @@
"true" : "color('blue')"
}
},
// "show": false
// "show": false,
// "show" : "${Height} >= 0",
"meta" : {
"description" : "'Building id ${id} has height ${Height}.'"
Expand Down
73 changes: 71 additions & 2 deletions Source/Scene/Cesium3DTileStyle.js
Expand Up @@ -62,6 +62,11 @@ define([
this._show = undefined;
this._meta = undefined;

this._colorShaderFunction = undefined;
this._showShaderFunction = undefined;
this._colorShaderFunctionReady = false;
this._showShaderFunctionReady = false;

var style = this;
if (typeof data === 'string') {
RequestScheduler.request(data, loadJson).then(function(styleJson) {
Expand All @@ -80,6 +85,17 @@ define([
that._style = clone(styleJson, true);

styleJson = defaultValue(styleJson, defaultValue.EMPTY_OBJECT);

if (!defined(styleJson.color)) {
// If there is no color style do not create a shader function. Otherwise a function would be created by the default style (white).
that._colorShaderFunctionReady = true;
}

if (!defined(styleJson.show)) {
// If there is no show style do not create a shader function.
that._showShaderFunctionReady = true;
}

var colorExpression = defaultValue(styleJson.color, DEFAULT_JSON_COLOR_EXPRESSION);
var showExpression = defaultValue(styleJson.show, DEFAULT_JSON_BOOLEAN_EXPRESSION);

Expand Down Expand Up @@ -294,9 +310,62 @@ define([
set : function(value) {
this._meta = value;
}
},

}
});

/**
* Gets the color shader function for this style.
*
* @param {String} name Name to give to the generated function.
* @param {String} variablePrefix Prefix that is added to any variable names to access vertex attributes.
* @param {Object} info Stores information about the generated shader function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename info. From this context, I have no idea what it is.

*
* @returns {String} The shader function.
*
* @private
*/
Cesium3DTileStyle.prototype.getColorShaderFunction = function(name, variablePrefix, info) {
if (this._colorShaderFunctionReady) {
// Return the cached result, may be undefined
return this._colorShaderFunction;
}

this._colorShaderFunctionReady = true;
this._colorShaderFunction = this.color.getShaderFunction(name, variablePrefix, 'vec4', info);
//>>includeStart('debug', pragmas.debug);
if (!defined(this._colorShaderFunction)) {
throw new DeveloperError('Could not generate valid shader code for the color style.');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this is @private, I would still document this @exception since there is other doc there. Same comment below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if this happens in non-pathological cases, we should have a more detailed error message.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be hard to give more detailed error messages for this inside Node.getShaderExpression.

}
//>>includeEnd('debug');
return this._colorShaderFunction;
};

/**
* Gets the show shader function for this style.
*
* @param {String} name Name to give to the generated function.
* @param {String} variablePrefix Prefix that is added to any variable names to access vertex attributes.
* @param {Object} info Stores information about the generated shader function.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment.

*
* @returns {String} The shader function.
*
* @private
*/
Cesium3DTileStyle.prototype.getShowShaderFunction = function(name, variablePrefix, info) {
if (this._showShaderFunctionReady) {
// Return the cached result, may be undefined
return this._showShaderFunction;
}

this._showShaderFunctionReady = true;
this._showShaderFunction = this.show.getShaderFunction(name, variablePrefix, 'bool', info);
//>>includeStart('debug', pragmas.debug);
if (!defined(this._showShaderFunction)) {
throw new DeveloperError('Could not generate valid shader code for the show style.');
}
//>>includeEnd('debug');
return this._showShaderFunction;
};

return Cesium3DTileStyle;
});
21 changes: 14 additions & 7 deletions Source/Scene/Cesium3DTileStyleEngine.js
Expand Up @@ -2,11 +2,13 @@
define([
'../Core/Color',
'../Core/defined',
'../Core/defineProperties'
'../Core/defineProperties',
'./PointCloud3DTileContent'
], function(
Color,
defined,
defineProperties) {
defineProperties,
PointCloud3DTileContent) {
'use strict';

/**
Expand Down Expand Up @@ -74,36 +76,41 @@ define([
// 2) this tile is now visible, but it wasn't visible when the style was first assigned
if (tile.lastStyleTime !== lastStyleTime) {
tile.lastStyleTime = lastStyleTime;
styleCompositeContent(this, tile.content, stats);
styleCompositeContent(this, frameState, tile.content, stats);

++stats.numberOfTilesStyled;
}
}
}
};

function styleCompositeContent(styleEngine, content, stats) {
function styleCompositeContent(styleEngine, frameState, content, stats) {
var innerContents = content.innerContents;
if (defined(innerContents)) {
var length = innerContents.length;
for (var i = 0; i < length; ++i) {
// Recurse for composites of composites
styleCompositeContent(styleEngine, innerContents[i], stats);
styleCompositeContent(styleEngine, frameState, innerContents[i], stats);
}
} else {
// Not a composite tile
styleContent(styleEngine, content, stats);
styleContent(styleEngine, frameState, content, stats);
}
}

var scratchColor = new Color();

function styleContent(styleEngine, content, stats) {
function styleContent(styleEngine, frameState, content, stats) {
var length = content.featuresLength;
var style = styleEngine._style;

stats.numberOfFeaturesStyled += length;

// Apply style to point cloud. Only apply style if the point cloud is not backed by a batch table.
if ((content instanceof PointCloud3DTileContent) && (length === 0)) {
content.applyStyle(frameState, style);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps rework this function so that each content type has a function like applyStyleWithShader that returns a boolean. If it returns false then the style was not applied and the loop below can be used. This avoids the special cases and reduces coupling.

}

if (!defined(style)) {
clearStyle(content);
return;
Expand Down
49 changes: 48 additions & 1 deletion Source/Scene/ConditionsExpression.js
Expand Up @@ -134,12 +134,59 @@ define([
var length = conditions.length;
for (var i = 0; i < length; ++i) {
var statement = conditions[i];
if (statement.condition.evaluate(feature, result)) {
if (statement.condition.evaluate(feature)) {
return statement.expression.evaluateColor(feature, result);
}
}
}
};

/**
* Gets the shader function for this expression.
* Returns undefined if the shader function can't be generated from this expression.
*
* @param {String} name Name to give to the generated function.
* @param {String} variablePrefix Prefix that is added to any variable names to access vertex attributes.
* @param {String} returnType The return type of the generated function.
* @param {Object} info Stores information about the generated shader function.
*
* @returns {String} The shader function.
*
* @private
*/
ConditionsExpression.prototype.getShaderFunction = function(name, variablePrefix, returnType, info) {
var conditions = this._runtimeConditions;
if (!defined(conditions) || conditions.length === 0) {
return undefined;
}

var shaderFunction = '';
var length = conditions.length;
for (var i = 0; i < length; ++i) {
var statement = conditions[i];
var condition = statement.condition.getShaderExpression(variablePrefix, info);
var expression = statement.expression.getShaderExpression(variablePrefix, info);

if (!defined(condition) || !defined(expression)) {
return undefined;
}

// Build the if/else chain from the list of conditions
shaderFunction +=
' ' + ((i === 0) ? 'if' : 'else if') + ' (' + condition + ') \n' +
' { \n' +
' return ' + expression + '; \n' +
' } \n';
}

shaderFunction = returnType + ' ' + name + '() \n' +
'{ \n' +
shaderFunction +
' return ' + returnType + '(1.0); \n' + // Return a default value if no conditions are met
'} \n';

return shaderFunction;
};

return ConditionsExpression;
});