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

Fix geometry offset attribute for 2D and CV #6753

Merged
merged 3 commits into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 2 additions & 17 deletions Source/Core/OffsetGeometryInstanceAttribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ define([
'use strict';

/**
* Value and type information for per-instance geometry attribute that determines if the geometry instance has a distance display condition.
* Value and type information for per-instance geometry attribute that determines the geometry instance offset
*
* @alias OffsetGeometryInstanceAttribute
* @constructor
Expand All @@ -22,23 +22,8 @@ define([
* @param {Number} [y=0] The y translation
* @param {Number} [z=0] The z translation
*
* @example
* var center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883);
* var offset = Cartesian3.multiplyByScalar(ellipsoid.geodeticSurfaceNormal(center), 1000, new Cartesian3());
* var instance = new Cesium.GeometryInstance({
* geometry : new Cesium.BoxGeometry({
* vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL,
* minimum : new Cesium.Cartesian3(-250000.0, -250000.0, -250000.0),
* maximum : new Cesium.Cartesian3(250000.0, 250000.0, 250000.0)
* }),
* modelMatrix : Cesium.Transforms.eastNorthUpToFixedFrame(center),
* id : 'box',
* attributes : {
* offset : Cesium.OffsetGeometryInstanceAttribute.fromCartesian3(offset)
* }
* });
*
* @private
*
* @see GeometryInstance
* @see GeometryInstanceAttribute
*/
Expand Down
100 changes: 92 additions & 8 deletions Source/Scene/Primitive.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@ define([
this._batchTable = undefined;
this._batchTableAttributeIndices = undefined;
this._offsetInstanceExtend = undefined;
this._batchTableOffsetAttribute2DIndex = undefined;
this._batchTableOffsetsUpdated = false;
this._instanceBoundingSpheres = undefined;
this._instanceBoundingSpheresCV = undefined;
this._tempBoundingSpheres = undefined;
Expand Down Expand Up @@ -586,6 +588,7 @@ define([
var attributes = [];
var attributeIndices = {};
var boundingSphereAttributeIndices = {};
var offset2DIndex;

var firstInstance = instances[0];
var instanceAttributes = firstInstance.attributes;
Expand Down Expand Up @@ -636,6 +639,15 @@ define([
boundingSphereAttributeIndices.radius = attributes.length - 1;
}

if (names.indexOf('offset') !== -1) {
attributes.push({
functionName : 'czm_batchTable_offset2D',
componentDatatype : ComponentDatatype.FLOAT,
componentsPerAttribute : 3
});
offset2DIndex = attributes.length - 1;
}

attributes.push({
functionName : 'czm_batchTable_pickColor',
componentDatatype : ComponentDatatype.UNSIGNED_BYTE,
Expand Down Expand Up @@ -682,6 +694,7 @@ define([
primitive._batchTable = batchTable;
primitive._batchTableAttributeIndices = attributeIndices;
primitive._batchTableBoundingSphereAttributeIndices = boundingSphereAttributeIndices;
primitive._batchTableOffsetAttribute2DIndex = offset2DIndex;
}

function cloneAttribute(attribute) {
Expand Down Expand Up @@ -887,7 +900,14 @@ define([
var modifiedShader = vertexShaderSource.replace(/attribute\s+float\s+batchId;/g, attr);

var str = 'vec4 $1 = czm_computePosition();\n';
str += ' $1 = $1 + vec4(czm_batchTable_offset(batchId) * applyOffset, 0.0);';
str += ' if (czm_sceneMode == czm_sceneMode3D)\n';
str += ' {\n';
str += ' $1 = $1 + vec4(czm_batchTable_offset(batchId) * applyOffset, 0.0);';
str += ' }\n';
str += ' else\n';
str += ' {\n';
str += ' $1 = $1 + vec4(czm_batchTable_offset2D(batchId) * applyOffset, 0.0);';
str += ' }\n';
modifiedShader = modifiedShader.replace(/vec4\s+([A-Za-z0-9_]+)\s+=\s+czm_computePosition\(\);/g, str);
return modifiedShader;
};
Expand All @@ -905,12 +925,12 @@ define([
' vec2 distanceDisplayCondition = czm_batchTable_distanceDisplayCondition(batchId);\n' +
' vec3 boundingSphereCenter3DHigh = czm_batchTable_boundingSphereCenter3DHigh(batchId);\n' +
' vec3 boundingSphereCenter3DLow = czm_batchTable_boundingSphereCenter3DLow(batchId);\n' +
' vec3 boundingSphereCenter2DHigh = czm_batchTable_boundingSphereCenter2DHigh(batchId);\n' +
' vec3 boundingSphereCenter2DLow = czm_batchTable_boundingSphereCenter2DLow(batchId);\n' +
' float boundingSphereRadius = czm_batchTable_boundingSphereRadius(batchId);\n';

if (!scene3DOnly) {
distanceDisplayConditionMain +=
' vec3 boundingSphereCenter2DHigh = czm_batchTable_boundingSphereCenter2DHigh(batchId);\n' +
' vec3 boundingSphereCenter2DLow = czm_batchTable_boundingSphereCenter2DLow(batchId);\n' +
' vec4 centerRTE;\n' +
' if (czm_morphTime == 1.0)\n' +
' {\n' +
Expand Down Expand Up @@ -1394,17 +1414,76 @@ define([
batchTable.setBatchedAttribute(i, center3DHighIndex, encodedCenter.high);
batchTable.setBatchedAttribute(i, center3DLowIndex, encodedCenter.low);

var cartographic = ellipsoid.cartesianToCartographic(center, scratchBoundingSphereCartographic);
var center2D = projection.project(cartographic, scratchBoundingSphereCenter2D);
encodedCenter = EncodedCartesian3.fromCartesian(center2D, scratchBoundingSphereCenterEncoded);
batchTable.setBatchedAttribute(i, center2DHighIndex, encodedCenter.high);
batchTable.setBatchedAttribute(i, center2DLowIndex, encodedCenter.low);
if (!frameState.scene3DOnly) {
var cartographic = ellipsoid.cartesianToCartographic(center, scratchBoundingSphereCartographic);
var center2D = projection.project(cartographic, scratchBoundingSphereCenter2D);
encodedCenter = EncodedCartesian3.fromCartesian(center2D, scratchBoundingSphereCenterEncoded);
batchTable.setBatchedAttribute(i, center2DHighIndex, encodedCenter.high);
batchTable.setBatchedAttribute(i, center2DLowIndex, encodedCenter.low);
}

batchTable.setBatchedAttribute(i, radiusIndex, radius);
}

primitive._batchTableBoundingSpheresUpdated = true;
}

var offsetScratchCartesian = new Cartesian3();
var offsetCenterScratch = new Cartesian3();
function updateBatchTableOffsets(primitive, frameState) {
var hasOffset = defined(primitive._batchTableAttributeIndices.offset);
if (!hasOffset || primitive._batchTableOffsetsUpdated || frameState.scene3DOnly) {
return;
}

var index2D = primitive._batchTableOffsetAttribute2DIndex;

var projection = frameState.mapProjection;
var ellipsoid = projection.ellipsoid;

var batchTable = primitive._batchTable;
var boundingSpheres = primitive._instanceBoundingSpheres;
var length = boundingSpheres.length;

for (var i = 0; i < length; ++i) {
var boundingSphere = boundingSpheres[i];
if (!defined(boundingSphere)) {
continue;
}
var offset = batchTable.getBatchedAttribute(i, primitive._batchTableAttributeIndices.offset);
if (Cartesian3.equals(offset, Cartesian3.ZERO)) {
batchTable.setBatchedAttribute(i, index2D, Cartesian3.ZERO);
continue;
}

var modelMatrix = primitive.modelMatrix;
if (defined(modelMatrix)) {
boundingSphere = BoundingSphere.transform(boundingSphere, modelMatrix, scratchBoundingSphere);
}

var center = boundingSphere.center;
center = ellipsoid.scaleToGeodeticSurface(center, offsetCenterScratch);
var cartographic = ellipsoid.cartesianToCartographic(center, scratchBoundingSphereCartographic);
var center2D = projection.project(cartographic, scratchBoundingSphereCenter2D);

var newPoint = Cartesian3.add(offset, center, offsetScratchCartesian);
cartographic = ellipsoid.cartesianToCartographic(newPoint, cartographic);

var newPointProjected = projection.project(cartographic, offsetScratchCartesian);

var newVector = Cartesian3.subtract(newPointProjected, center2D, offsetScratchCartesian);

var x = newVector.x;
newVector.x = newVector.z;
newVector.z = newVector.y;
newVector.y = x;

batchTable.setBatchedAttribute(i, index2D, newVector);
}

primitive._batchTableOffsetsUpdated = true;
}

function createVertexArray(primitive, frameState) {
var attributeLocations = primitive._attributeLocations;
var geometries = primitive._geometries;
Expand Down Expand Up @@ -1822,13 +1901,17 @@ define([

if (this._state === PrimitiveState.COMBINED) {
updateBatchTableBoundingSpheres(this, frameState);
updateBatchTableOffsets(this, frameState);
createVertexArray(this, frameState);
}

if (!this.show || this._state !== PrimitiveState.COMPLETE) {
return;
}

if (!this._batchTableOffsetsUpdated) {
updateBatchTableOffsets(this, frameState);
}
if (this._recomputeBoundingSpheres) {
recomputeBoundingSpheres(this, frameState);
}
Expand Down Expand Up @@ -1934,6 +2017,7 @@ define([
batchTable.setBatchedAttribute(instanceIndex, attributeIndex, attributeValue);
if (name === 'offset') {
primitive._recomputeBoundingSpheres = true;
primitive._batchTableOffsetsUpdated = false;
}
};
}
Expand Down