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

Support batch table binary section for pnts #4112

Merged
merged 5 commits into from
Jul 14, 2016
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
2 changes: 1 addition & 1 deletion Apps/Sandcastle/gallery/3D Tiles.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
}, {
name : 'Composite', url : '../../../Specs/Data/Cesium3DTiles/Composite/Composite/'
}, {
name : 'Points', url : '../../../Specs/Data/Cesium3DTiles/Points/Points/'
name : 'Points', url : '../../../Specs/Data/Cesium3DTiles/Points/PointsRGB/'
}];

var tileset;
Expand Down
21 changes: 12 additions & 9 deletions Source/Core/PointGeometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ define([
if (!defined(options.positionsTypedArray)) {
throw new DeveloperError('options.positionsTypedArray is required.');
}
if (!defined(options.colorsTypedArray)) {
throw new DeveloperError('options.colorsTypedArray is required');
}
//>>includeEnd('debug');

this._positionsTypedArray = options.positionsTypedArray;
Expand Down Expand Up @@ -80,12 +77,18 @@ define([
values : positions
});

attributes.color = new GeometryAttribute({
componentDatatype : ComponentDatatype.UNSIGNED_BYTE,
componentsPerAttribute : 3,
values : pointGeometry._colorsTypedArray,
normalize : true
});
var colors = pointGeometry._colorsTypedArray;
if (defined(colors)) {
// Check if the colors are provided as rgb or rgba
var colorComponentsPerAttribute = (colors.length === positions.length) ? 3 : 4;

attributes.color = new GeometryAttribute({
componentDatatype : ComponentDatatype.UNSIGNED_BYTE,
componentsPerAttribute : colorComponentsPerAttribute,
values : colors,
normalize : true
});
}

// User provided bounding sphere to save computation time.
var boundingSphere = pointGeometry._boundingSphere;
Expand Down
112 changes: 104 additions & 8 deletions Source/Scene/Points3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ define([
'../Core/DeveloperError',
'../Core/GeometryInstance',
'../Core/getMagic',
'../Core/getStringFromTypedArray',
'../Core/loadArrayBuffer',
'../Core/PointGeometry',
'../Core/Request',
Expand All @@ -30,6 +31,7 @@ define([
DeveloperError,
GeometryInstance,
getMagic,
getStringFromTypedArray,
loadArrayBuffer,
PointGeometry,
Request,
Expand All @@ -56,6 +58,7 @@ define([
this._url = url;
this._tileset = tileset;
this._tile = tile;
this._constantColor = Color.clone(Color.WHITE);

/**
* The following properties are part of the {@link Cesium3DTileContent} interface.
Expand All @@ -66,8 +69,6 @@ define([
this.batchTableResources = undefined;
this.featurePropertiesDirty = false;
this.boundingSphere = tile.contentBoundingVolume.boundingSphere;
this._debugColor = Color.fromRandom({ alpha : 1.0 });
this._debugColorizeTiles = false;
}

defineProperties(Points3DTileContent.prototype, {
Expand Down Expand Up @@ -108,6 +109,7 @@ define([
};

var sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
var sizeOfFloat32 = Float32Array.BYTES_PER_ELEMENT;

/**
* Part of the {@link Cesium3DTileContent} interface.
Expand Down Expand Up @@ -166,11 +168,97 @@ define([
var pointsLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;

var positionsOffsetInBytes = byteOffset;
var positions = new Float32Array(arrayBuffer, positionsOffsetInBytes, pointsLength * 3);
var batchTableJSONByteLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;

var batchTableBinaryByteLength = view.getUint32(byteOffset, true);
byteOffset += sizeOfUint32;

var positions = new Float32Array(arrayBuffer, byteOffset, pointsLength * 3);
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, in b3dm and i3dm, the batch table comes before glTF. We should be consistent here for now and move the positions payload after the batch table; however, we might want to switch them all later if there is a benefit, e.g., to avoid parsing it in some cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah that's true, I'll make the change in a new PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm surprised we haven't run into this before, but TypedArray constructors expect their byte offset to be aligned to the type. For two of the points tilesets, the byte length of the batch table is odd and this causes problems when creating a Float32Array of the positions. Do we want to require byte alignment in the spec?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, definitely need to say this in the spec. @tfili and I have ran into this before and I know some of the work we did included the padding

Copy link
Contributor

Choose a reason for hiding this comment

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

byteOffset += pointsLength * 3 * sizeOfFloat32;

var colors;
var translucent = false;
var hasConstantColor = false;

if (batchTableJSONByteLength > 0) {
// Get the batch table JSON
var batchTableString = getStringFromTypedArray(uint8Array, byteOffset, batchTableJSONByteLength);
var batchTableJSON = JSON.parse(batchTableString);
byteOffset += batchTableJSONByteLength;

// Get the batch table binary
var batchTableBinary;
if (batchTableBinaryByteLength > 0) {
batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength);
}
byteOffset += batchTableBinaryByteLength;

// Get the point colors
var tiles3DRGB = batchTableJSON.TILES3D_RGB;
var tiles3DRGBA = batchTableJSON.TILES3D_RGBA;
var tiles3DColor = batchTableJSON.TILES3D_COLOR;

if (defined(tiles3DRGBA)) {
colors = new Uint8Array(batchTableBinary, tiles3DRGBA.byteOffset, pointsLength * 4);
translucent = true;
} else if (defined(tiles3DRGB)) {
colors = new Uint8Array(batchTableBinary, tiles3DRGB.byteOffset, pointsLength * 3);
} else if (defined(tiles3DColor)) {
this._constantColor = Color.fromBytes(tiles3DColor[0], tiles3DColor[1], tiles3DColor[2], tiles3DColor[3], this._constantColor);
hasConstantColor = true;
}
}

var hasColors = defined(colors);

if (!hasColors && !hasConstantColor) {
this._constantColor = Color.DARKGRAY;
}

var vs = 'attribute vec3 position3DHigh; \n' +
'attribute vec3 position3DLow; \n' +
'uniform float pointSize; \n';
if (hasColors) {
if (translucent) {
vs += 'attribute vec4 color; \n' +
'varying vec4 v_color; \n';
} else {
vs += 'attribute vec3 color; \n' +
'varying vec3 v_color; \n';
}
}
vs += 'void main() \n' +
'{ \n' +
' gl_Position = czm_modelViewProjectionRelativeToEye * czm_computePosition(); \n' +
' gl_PointSize = pointSize; \n';
if (hasColors) {
vs += ' v_color = color; \n';
}
vs += '}';

var fs = 'uniform vec4 highlightColor; \n';
if (hasColors) {
if (translucent) {
fs += 'varying vec4 v_color; \n';
} else {
fs += 'varying vec3 v_color; \n';
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm I think I'm going to fix this so the attribute is just a single value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually this won't work easily with GeometryAttribute.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can't we provide a uniform using an appearance?

Otherwise put a TODO here (not PERFORMANCE_IDEA) so we optimize this before merging into master.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll try that.

}
fs += 'void main() \n' +
'{ \n';

if (hasColors) {
if (translucent) {
fs += ' gl_FragColor = v_color * highlightColor; \n';
} else {
fs += ' gl_FragColor = vec4(v_color * highlightColor.rgb, highlightColor.a); \n';
}
} else {
fs += ' gl_FragColor = highlightColor; \n';
}

var colorsOffsetInBytes = positionsOffsetInBytes + (pointsLength * (3 * Float32Array.BYTES_PER_ELEMENT));
var colors = new Uint8Array(arrayBuffer, colorsOffsetInBytes, pointsLength * 3);
fs += '} \n';

// TODO: performance test with 'interleave : true'
var instance = new GeometryInstance({
Expand All @@ -180,9 +268,17 @@ define([
boundingSphere : this.boundingSphere
})
});

var appearance = new PointAppearance({
highlightColor : this._constantColor,
translucent : translucent,
vertexShaderSource : vs,
fragmentShaderSource : fs
});

var primitive = new Primitive({
geometryInstances : instance,
appearance : new PointAppearance(),
appearance : appearance,
asynchronous : false,
allowPicking : false,
cull : false,
Expand All @@ -208,7 +304,7 @@ define([
* Part of the {@link Cesium3DTileContent} interface.
*/
Points3DTileContent.prototype.applyDebugSettings = function(enabled, color) {
color = enabled ? color : Color.WHITE;
color = enabled ? color : this._constantColor;
this._primitive.appearance.uniforms.highlightColor = color;
};

Expand Down
4 changes: 3 additions & 1 deletion Specs/Cesium3DTilesTester.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ define([
var magic = defaultValue(options.magic, [112, 110, 116, 115]);
var version = defaultValue(options.version, 1);

var headerByteLength = 16;
var headerByteLength = 24;
var byteLength = headerByteLength;
var buffer = new ArrayBuffer(byteLength);
var view = new DataView(buffer);
Expand All @@ -245,6 +245,8 @@ define([
view.setUint32(4, version, true); // version
view.setUint32(8, byteLength, true); // byteLength
view.setUint32(12, 0, true); // pointsLength
view.setUint32(16, 0, true); // batchTableJSONByteLength
view.setUint32(20, 0, true); // batchTableBinaryByteLength

return buffer;
};
Expand Down
8 changes: 0 additions & 8 deletions Specs/Core/PointGeometrySpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,6 @@ defineSuite([
}).toThrowDeveloperError();
});

it('throws without colorsTypedArray', function() {
expect(function() {
return new PointGeometry({
positionsTypedArray : positionsTypedArray
});
}).toThrowDeveloperError();
});

it('creates with boundingSphere', function() {
var points = new PointGeometry({
positionsTypedArray : positionsTypedArray,
Expand Down
Binary file removed Specs/Data/Cesium3DTiles/Points/Points/points.pnts
Binary file not shown.
Binary file not shown.
21 changes: 21 additions & 0 deletions Specs/Data/Cesium3DTiles/Points/PointsConstantColor/tileset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"asset": {
"version": "0.0"
},
"geometricError": 346.4,
"refine": "add",
"root": {
"boundingVolume": {
"sphere": [
1215011.9317263428,
-4736309.3434217675,
4081602.0044800863,
100
]
},
"geometricError": 0,
"content": {
"url": "pointsConstantColor.pnts"
}
}
}
Binary file not shown.
21 changes: 21 additions & 0 deletions Specs/Data/Cesium3DTiles/Points/PointsNoColor/tileset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"asset": {
"version": "0.0"
},
"geometricError": 346.4,
"refine": "add",
"root": {
"boundingVolume": {
"sphere": [
1215011.9317263428,
-4736309.3434217675,
4081602.0044800863,
100
]
},
"geometricError": 0,
"content": {
"url": "pointsNoColor.pnts"
}
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"geometricError": 0,
"content": {
"url": "points.pnts"
"url": "pointsRGB.pnts"
}
}
}
Binary file not shown.
21 changes: 21 additions & 0 deletions Specs/Data/Cesium3DTiles/Points/PointsRGBA/tileset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"asset": {
"version": "0.0"
},
"geometricError": 346.4,
"refine": "add",
"root": {
"boundingVolume": {
"sphere": [
1215011.9317263428,
-4736309.3434217675,
4081602.0044800863,
100
]
},
"geometricError": 0,
"content": {
"url": "pointsRGBA.pnts"
}
}
}
29 changes: 22 additions & 7 deletions Specs/Scene/Points3DTileContentSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ defineSuite([
var centerLongitude = -1.31968;
var centerLatitude = 0.698874;

var pointsUrl = './Data/Cesium3DTiles/Points/Points';
var pointsRGBUrl = './Data/Cesium3DTiles/Points/PointsRGB';
var pointsRGBAUrl = './Data/Cesium3DTiles/Points/PointsRGBA';
var pointsNoColorUrl = './Data/Cesium3DTiles/Points/PointsNoColor';
var pointsConstantColorUrl = './Data/Cesium3DTiles/Points/PointsConstantColor';

beforeAll(function() {
// Point tiles use RTC, which for now requires scene3DOnly to be true
Expand Down Expand Up @@ -70,19 +73,31 @@ defineSuite([
});

it('resolves readyPromise', function() {
return Cesium3DTilesTester.resolvesReadyPromise(scene, pointsUrl);
return Cesium3DTilesTester.resolvesReadyPromise(scene, pointsRGBUrl);
});

it('rejects readyPromise on failed request', function() {
return Cesium3DTilesTester.rejectsReadyPromiseOnFailedRequest('pnts');
});

it('renders points', function() {
return Cesium3DTilesTester.loadTileset(scene, pointsUrl).then(expectRenderPoints);
it('renders points with rgb colors', function() {
return Cesium3DTilesTester.loadTileset(scene, pointsRGBUrl).then(expectRenderPoints);
});

it('renders points with rgba colors', function() {
return Cesium3DTilesTester.loadTileset(scene, pointsRGBAUrl).then(expectRenderPoints);
});

it('renders points with no colors', function() {
return Cesium3DTilesTester.loadTileset(scene, pointsNoColorUrl).then(expectRenderPoints);
});

it('renders points with constant colors', function() {
return Cesium3DTilesTester.loadTileset(scene, pointsConstantColorUrl).then(expectRenderPoints);
});

it('renders with debug color', function() {
return Cesium3DTilesTester.loadTileset(scene, pointsUrl).then(function(tileset) {
return Cesium3DTilesTester.loadTileset(scene, pointsRGBUrl).then(function(tileset) {
var color = expectRenderPoints(tileset);
tileset.debugColorizeTiles = true;
var debugColor = expectRenderPoints(tileset);
Expand All @@ -94,11 +109,11 @@ defineSuite([
});

it('destroys', function() {
return Cesium3DTilesTester.tileDestroys(scene, pointsUrl);
return Cesium3DTilesTester.tileDestroys(scene, pointsRGBUrl);
});

it('destroys before loading finishes', function() {
return Cesium3DTilesTester.tileDestroysBeforeLoad(scene, pointsUrl);
return Cesium3DTilesTester.tileDestroysBeforeLoad(scene, pointsRGBUrl);
});

}, 'WebGL');