-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Added heightReference to models #3938
Conversation
…ate billboard and model clamping. Also added tests for model clamping.
…nProvider changes.
|
||
var scene = this._billboardCollection._scene; | ||
if (defined(scene)) { | ||
scene.terrainProviderChanged.addEventListener(function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to do this once for the billboard collection, then loop over all the billboards in the collection? Save O(n) memory?
@tfili did you test this in Sandcastle with all the options that modify the model matrix like minimum pixel size and maximum scale? |
* @type {Event} | ||
* @readonly | ||
*/ | ||
terrainProviderChanged : { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add to CHANGES.md. You could also make the Globe
event private and only document this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the terrainProvider
is public on both Scene
and Globe
it would be a little weird to have this private on the Globe
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean will anyone use it on the Globe
directly? Or will everyone use it through Scene
? If the later, then why not keep the API surface area small and not provide two ways to do the same thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I'm all for reducing the API surface area, I'm not sure having the event only on the scene makes sense here. We should stay consistent with what we've done elsewhere and we made a choice to have the globe be a separate documented class and since the property is there publicly, the event should be too.
Whenever we get around to doing a large API cleanup, then I could see us making a lot of these things private; but we shouldn't just start now because it will make the API even more disjoint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
Looks to checkout with all model options. |
If you animate the model matrix with a model clamped to ground, the model only seems to update when the camera moves. Here is the example I used that is supposed to have a model and billboard clamped to ground at the same location: var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
function createModel(url, height, heading, pitch, roll) {
height = Cesium.defaultValue(height, 0.0);
heading = Cesium.defaultValue(heading, 0.0);
pitch = Cesium.defaultValue(pitch, 0.0);
roll = Cesium.defaultValue(roll, 0.0);
var origin = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, heading, pitch, roll);
scene.primitives.removeAll(); // Remove previous model
var model = scene.primitives.add(Cesium.Model.fromGltf({
scene : scene,
url : url,
modelMatrix : modelMatrix,
minimumPixelSize : 128,
heightReference : Cesium.HeightReference.CLAMP_TO_GROUND
}));
var billboardCollection = viewer.scene.primitives.add(new Cesium.BillboardCollection({
scene : viewer.scene
}));
var billboard = billboardCollection.add({
position : origin,
image : '../images/facility.gif',
heightReference : Cesium.HeightReference.CLAMP_TO_GROUND
});
model.readyPromise.then(function(model) {
// Play and loop all animations at half-speed
model.activeAnimations.addAll({
speedup : 0.5,
loop : Cesium.ModelAnimationLoop.REPEAT
});
var camera = viewer.camera;
viewer.scene.postRender.addEventListener(function(scene, time) {
var ellipsoid = viewer.scene.mapProjection.ellipsoid;
var modelMatrix = model.modelMatrix;
var currentPosition = Cesium.Cartesian3.fromCartesian4(Cesium.Matrix4.getColumn(modelMatrix, 3, new Cesium.Cartesian4()), new Cesium.Cartesian3());
var currentCarto = ellipsoid.cartesianToCartographic(currentPosition);
currentCarto.longitude += Cesium.Math.toRadians(0.000001);
var p = ellipsoid.cartographicToCartesian(currentCarto);
Cesium.Matrix4.setColumn(modelMatrix, 3, Cesium.Cartesian4.fromElements(p.x, p.y, p.z, 1.0), modelMatrix);
billboard.position = Cesium.Cartesian3.clone(p);
var position = Cesium.Cartesian3.clone(camera.position);
camera.lookAtTransform(model.modelMatrix);
camera.position = position;
});
// Zoom to model
var controller = scene.screenSpaceCameraController;
var r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
controller.minimumZoomDistance = r * 0.5;
var center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3());
var heading = Cesium.Math.toRadians(230.0);
var pitch = Cesium.Math.toRadians(-20.0);
camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, r * 2.0));
}).otherwise(function(error){
window.alert(error);
});
}
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function(movement) {
var pick = scene.pick(movement.endPosition);
if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) {
// Output glTF node and mesh under the mouse.
console.log('node: ' + pick.node.name + '. mesh: ' + pick.mesh.name);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
createModel('../../SampleData/models/CesiumMan/Cesium_Man.glb'); |
…el until a new tile was loaded.
@bagnell Should be good to go. |
Adds a heightReference property for models. If you use it
scene
is also required. This will render models on terrain (or relative to it). Tests were also added inModelSpec.js
.In order to get this working properly #3921 was fixed. The issue was that the
QuadTreePrimitive
removes theupdateHeight
callback once we get to the highest resolution tile. If we changed terrain providers we never add the callback again. I added aterrainProviderChanged
event toGlobe
andScene
and hooked them up to theBillboard
andModel
so it updates the clamped positions when the provider is changed.Tests were added to
Globe
to make sure the event fires and toBillboardCollection
andModel
to make sure it gets the event when the provider is changed.CHANGES.md
was also updated.