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

PointPrimitive and PointPrimitiveCollection #2632

Merged
merged 38 commits into from
May 5, 2015
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
86e94c7
Started work on a point primitive.
emackey Apr 7, 2015
30c968d
Specify PrimitiveType.POINTS.
emackey Apr 7, 2015
bca313c
Added some shaders for PointPrimitiveCollection.
emackey Apr 8, 2015
a9ba911
First sign that it's working!
emackey Apr 8, 2015
92820a4
Tweak anti-aliasing.
emackey Apr 8, 2015
7221af4
Remove cruft.
emackey Apr 8, 2015
4adcff3
Rename 2 parameters to match entity.point, rearrange attributes.
emackey Apr 9, 2015
1bdcab5
Upgrade VAF to not split up un-indexed verts into 64k chunks.
emackey Apr 9, 2015
d9ed942
Copy fix from #2630.
emackey Apr 10, 2015
1a5923d
Merge remote-tracking branch 'origin/master' into point-primitive
emackey Apr 10, 2015
887213a
Add unit tests for PointPrimitive and its collection.
emackey Apr 10, 2015
6d0389f
Switch PointVisualizer to use PointPrimitives instead of Billboards.
emackey Apr 10, 2015
7bfd1be
Make the point sizes match the old behavior.
emackey Apr 13, 2015
7ccd504
Update CHANGES.md.
emackey Apr 13, 2015
1b847ad
Merge remote-tracking branch 'origin/master' into point-primitive
emackey Apr 14, 2015
ad5d2bf
Add clamps for min/max point sizes. Add browser-zoom scale.
emackey Apr 14, 2015
0bbf178
Fix problems with point size clamping logic.
emackey Apr 14, 2015
3c462a6
Merge remote-tracking branch 'origin/master' into point-primitive
emackey Apr 15, 2015
95d4943
Merge remote-tracking branch 'origin/master' into point-primitive
emackey Apr 21, 2015
91b3e91
Merge remote-tracking branch 'origin/master' into point-primitive
pjcozzi Apr 24, 2015
a025567
Remove unused variables.
emackey Apr 27, 2015
f0fdbe6
Add "Points" entity demo, and fix missing translucencyByDistance.
emackey Apr 27, 2015
cf2852d
Add development PointPrimitive demo.
emackey Apr 27, 2015
22f0cd4
Some updates after review. More to come.
emackey Apr 27, 2015
ae10cad
Destructor cleanup.
emackey Apr 28, 2015
cbdbf2c
Refactor pointPrimitive specs to use Specs/createScene.
emackey Apr 28, 2015
6cd15fa
Merge remote-tracking branch 'origin/master' into point-primitive
emackey Apr 29, 2015
62a4593
CHANGES.md - Pushed to v1.10.
emackey Apr 29, 2015
31c7920
Incorporate some changes from Billboards in #2669.
emackey Apr 29, 2015
d38ff18
Doc tweak.
emackey May 4, 2015
5dc4195
Merge remote-tracking branch 'origin/master' into point-primitive
emackey May 4, 2015
f073a28
Tweak CHANGES.md
pjcozzi May 4, 2015
36e3c20
Tweak doc
pjcozzi May 4, 2015
773cc50
Make `czm_nearFarScalar` a shared function.
emackey May 5, 2015
fe63450
Tweak tests.
emackey May 5, 2015
6f7fb55
Improve coverage by adding missing tests.
emackey May 5, 2015
698839d
Test name grammar cleanup.
emackey May 5, 2015
8bd5dc9
Added test for czm_nearFarScalar.
emackey May 5, 2015
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: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Change Log
* Deprecated
*
* An exception is now thrown if `Primitive.modelMatrix` is not the identity matrix when in in 2D or Columbus View.
* Added new `PointPrimitive` and `PointPrimitiveCollection` as alternatives to billboards with circles.
* Changed `Entity.point` back-end graphics to use the new `PointPrimitive` instead of billboards. No change to the `Entity.point` API.
* Fix a bug which caused `Entity.viewFrom` to be ignored when flying to, zooming to, or tracking an Entity.
* The `InfoBox` title is now correctly updated if the name of `viewer.selectedEntity` changes on the fly. [#2644](https://github.com/AnalyticalGraphicsInc/cesium/pull/2644)
* Fixed a bug that caused `Corridor` and `PolylineVolume` geometry to be incorrect for sharp corners [#2626](https://github.com/AnalyticalGraphicsInc/cesium/pull/2626)
Expand Down
151 changes: 36 additions & 115 deletions Source/DataSources/PointVisualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ define([
'../Core/destroyObject',
'../Core/DeveloperError',
'../Core/NearFarScalar',
'../Scene/BillboardCollection',
'../Scene/PointPrimitiveCollection',
'./BoundingSphereState',
'./Property'
], function(
Expand All @@ -18,7 +18,7 @@ define([
destroyObject,
DeveloperError,
NearFarScalar,
BillboardCollection,
PointPrimitiveCollection,
BoundingSphereState,
Property) {
"use strict";
Expand All @@ -35,15 +35,15 @@ define([

var EntityData = function(entity) {
this.entity = entity;
this.billboard = undefined;
this.pointPrimitive = undefined;
this.color = undefined;
this.outlineColor = undefined;
this.pixelSize = undefined;
this.outlineWidth = undefined;
};

/**
* A {@link Visualizer} which maps {@link Entity#point} to a {@link Billboard}.
* A {@link Visualizer} which maps {@link Entity#point} to a {@link PointPrimitive}.
* @alias PointVisualizer
* @constructor
*
Expand All @@ -65,7 +65,7 @@ define([
this._scene = scene;
this._unusedIndexes = [];
this._entityCollection = entityCollection;
this._billboardCollection = undefined;
this._pointPrimitiveCollection = undefined;
this._items = new AssociativeArray();
this._onCollectionChanged(entityCollection, entityCollection.values, [], []);
};
Expand All @@ -90,82 +90,43 @@ define([
var item = items[i];
var entity = item.entity;
var pointGraphics = entity._point;
var billboard = item.billboard;
var pointPrimitive = item.pointPrimitive;
var show = entity.isShowing && entity.isAvailable(time) && Property.getValueOrDefault(pointGraphics._show, time, true);
if (show) {
position = Property.getValueOrUndefined(entity._position, time, position);
show = defined(position);
}
if (!show) {
returnBillboard(item, unusedIndexes);
returnPointPrimitive(item, unusedIndexes);
continue;
}

var init = false;
var needRedraw = false;
if (!defined(billboard)) {
init = true;
var billboardCollection = this._billboardCollection;
if (!defined(billboardCollection)) {
billboardCollection = new BillboardCollection();
this._billboardCollection = billboardCollection;
this._scene.primitives.add(billboardCollection);
if (!defined(pointPrimitive)) {
var pointPrimitiveCollection = this._pointPrimitiveCollection;
if (!defined(pointPrimitiveCollection)) {
pointPrimitiveCollection = new PointPrimitiveCollection();
this._pointPrimitiveCollection = pointPrimitiveCollection;
this._scene.primitives.add(pointPrimitiveCollection);
}

var length = unusedIndexes.length;
if (length > 0) {
billboard = billboardCollection.get(unusedIndexes.pop());
pointPrimitive = pointPrimitiveCollection.get(unusedIndexes.pop());
} else {
billboard = billboardCollection.add();
pointPrimitive = pointPrimitiveCollection.add();
}

billboard.id = entity;
billboard.image = undefined;
item.billboard = billboard;
needRedraw = true;
pointPrimitive.id = entity;
item.pointPrimitive = pointPrimitive;
}

billboard.show = true;
billboard.position = position;
billboard.scaleByDistance = Property.getValueOrUndefined(pointGraphics._scaleByDistance, time, scaleByDistance);

var colorProperty = pointGraphics._color;
var outlineColorProperty = pointGraphics._outlineColor;

var newColor = Property.getValueOrDefault(colorProperty, time, defaultColor, color);
var newOutlineColor = Property.getValueOrDefault(outlineColorProperty, time, defaultOutlineColor, outlineColor);
var newOutlineWidth = Math.round(Property.getValueOrDefault(pointGraphics._outlineWidth, time, defaultOutlineWidth));
var newPixelSize = Math.max(1, Math.round(Property.getValueOrDefault(pointGraphics._pixelSize, time, defaultPixelSize)));

if (newOutlineWidth > 0) {
billboard.scale = 1.0;
needRedraw = needRedraw || //
newOutlineWidth !== item.outlineWidth || //
newPixelSize !== item.pixelSize || //
!Color.equals(newColor, item.color) || //
!Color.equals(newOutlineColor, item.outlineColor);
} else {
billboard.scale = newPixelSize / 50.0;
newPixelSize = 50.0;
needRedraw = needRedraw || //
newOutlineWidth !== item.outlineWidth || //
!Color.equals(newColor, item.color) || //
!Color.equals(newOutlineColor, item.outlineColor);
}

if (needRedraw) {
item.color = Color.clone(newColor, item.color);
item.outlineColor = Color.clone(newOutlineColor, item.outlineColor);
item.pixelSize = newPixelSize;
item.outlineWidth = newOutlineWidth;

var centerAlpha = newColor.alpha;
var cssColor = newColor.toCssColorString();
var cssOutlineColor = newOutlineColor.toCssColorString();
var textureId = JSON.stringify([cssColor, newPixelSize, cssOutlineColor, newOutlineWidth]);

billboard.setImage(textureId, createCallback(centerAlpha, cssColor, cssOutlineColor, newOutlineWidth, newPixelSize));
}
pointPrimitive.show = true;
pointPrimitive.position = position;
pointPrimitive.scaleByDistance = Property.getValueOrUndefined(pointGraphics._scaleByDistance, time, scaleByDistance);
pointPrimitive.color = Property.getValueOrDefault(pointGraphics._color, time, defaultColor, color);
pointPrimitive.outlineColor = Property.getValueOrDefault(pointGraphics._outlineColor, time, defaultOutlineColor, outlineColor);
pointPrimitive.outlineWidth = Property.getValueOrDefault(pointGraphics._outlineWidth, time, defaultOutlineWidth);
pointPrimitive.pixelSize = Property.getValueOrDefault(pointGraphics._pixelSize, time, defaultPixelSize);
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably need to add a scene.clampPointSize similar to scene.clampLineWidth to avoid assigning a size the card/drivers don't support. I also assume all cards have fairly large maximums?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I've added this to the vertex shader, where in the most recent version this takes place after outline width and scale-by-distance effects have been included in the total glPointSize.

The typical size limits are shown on the very bottom chart on webglstats.com. Looks like the availability of extra-large (1023px) points has grown substantially in just the past year. Typical CZML point size real-world uses are far below 63 pixels, so they read as above 99% availability on this chart.

}
return true;
};
Expand All @@ -192,11 +153,11 @@ define([
//>>includeEnd('debug');

var item = this._items.get(entity.id);
if (!defined(item) || !defined(item.billboard)) {
if (!defined(item) || !defined(item.pointPrimitive)) {
return BoundingSphereState.FAILED;
}

result.center = Cartesian3.clone(item.billboard.position, result.center);
result.center = Cartesian3.clone(item.pointPrimitive.position, result.center);
result.radius = 0;
return BoundingSphereState.DONE;
};
Expand All @@ -215,8 +176,8 @@ define([
*/
PointVisualizer.prototype.destroy = function() {
this._entityCollection.collectionChanged.removeEventListener(PointVisualizer.prototype._onCollectionChanged, this);
if (defined(this._billboardCollection)) {
this._scene.primitives.remove(this._billboardCollection);
if (defined(this._pointPrimitiveCollection)) {
this._scene.primitives.remove(this._pointPrimitiveCollection);
}
return destroyObject(this);
};
Expand All @@ -241,68 +202,28 @@ define([
items.set(entity.id, new EntityData(entity));
}
} else {
returnBillboard(items.get(entity.id), unusedIndexes);
returnPointPrimitive(items.get(entity.id), unusedIndexes);
items.remove(entity.id);
}
}

for (i = removed.length - 1; i > -1; i--) {
entity = removed[i];
returnBillboard(items.get(entity.id), unusedIndexes);
returnPointPrimitive(items.get(entity.id), unusedIndexes);
items.remove(entity.id);
}
};

function returnBillboard(item, unusedIndexes) {
function returnPointPrimitive(item, unusedIndexes) {
if (defined(item)) {
var billboard = item.billboard;
if (defined(billboard)) {
item.billboard = undefined;
billboard.show = false;
billboard.image = undefined;
unusedIndexes.push(billboard._index);
var pointPrimitive = item.pointPrimitive;
if (defined(pointPrimitive)) {
item.pointPrimitive = undefined;
pointPrimitive.show = false;
unusedIndexes.push(pointPrimitive._index);
}
}
}

function createCallback(centerAlpha, cssColor, cssOutlineColor, cssOutlineWidth, newPixelSize) {
return function(id) {
var canvas = document.createElement('canvas');

var length = newPixelSize + (2 * cssOutlineWidth);
canvas.height = canvas.width = length;

var context2D = canvas.getContext('2d');
context2D.clearRect(0, 0, length, length);

if (cssOutlineWidth !== 0) {
context2D.beginPath();
context2D.arc(length / 2, length / 2, length / 2, 0, 2 * Math.PI, true);
context2D.closePath();
context2D.fillStyle = cssOutlineColor;
context2D.fill();
// Punch a hole in the center if needed.
if (centerAlpha < 1.0) {
context2D.save();
context2D.globalCompositeOperation = 'destination-out';
context2D.beginPath();
context2D.arc(length / 2, length / 2, newPixelSize / 2, 0, 2 * Math.PI, true);
context2D.closePath();
context2D.fillStyle = 'black';
context2D.fill();
context2D.restore();
}
}

context2D.beginPath();
context2D.arc(length / 2, length / 2, newPixelSize / 2, 0, 2 * Math.PI, true);
context2D.closePath();
context2D.fillStyle = cssColor;
context2D.fill();

return canvas;
};
}

return PointVisualizer;
});
4 changes: 2 additions & 2 deletions Source/Renderer/VertexArrayFacade.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ define([
destroyVA(this);
var va = this.va = [];

var numberOfVertexArrays = Math.ceil(this._size / CesiumMath.SIXTY_FOUR_KILOBYTES);
var numberOfVertexArrays = defined(indexBuffer) ? Math.ceil(this._size / CesiumMath.SIXTY_FOUR_KILOBYTES) : 1;
for ( var k = 0; k < numberOfVertexArrays; ++k) {
var attributes = [];
for (var usage in buffersByUsage) {
Expand All @@ -340,7 +340,7 @@ define([
va.push({
va : this._context.createVertexArray(attributes, indexBuffer),
indicesCount : 1.5 * ((k !== (numberOfVertexArrays - 1)) ? CesiumMath.SIXTY_FOUR_KILOBYTES : (this._size % CesiumMath.SIXTY_FOUR_KILOBYTES))
// TODO: not hardcode 1.5
// TODO: not hardcode 1.5, this assumes 6 indicies per 4 vertices (as for Billboard quads).
});
}
}
Expand Down
Loading