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

Model Instancing #3049

Closed

Conversation

lilleyse
Copy link
Contributor

For #3001

To do:

  • Handle adding and removing instances
  • Handle updating instances
  • Test that picking works
  • Fix precision jittering
  • Performance measurements
  • Add specs
  • Frustum culling instances (optional)
  • @pjcozzi - add this to the glTF spec: "This assumes techniques that share a program do not declare different semantics for the same uniforms."


createCollection('../../SampleData/models/CesiumAir/Cesium_Air.bgltf', 10);

//function createModel(url, height) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't leave in commented out code. Should we delete this?

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 use this code for testing sometimes, and I will delete it once I'm further along with testing. In fact I'll probably need it back for the performance testing.

@@ -796,6 +842,8 @@ define([
* @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom.
* @param {Boolean} [options.allowPicking=true] When <code>true</code>, each glTF mesh and primitive is pickable with {@link Scene#pick}.
* @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded.
* @param {Boolean} [options.instanced=false] Whether the model will be instanced.
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 as above.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 28, 2015

Add tests to the task list for this pull request.

};

/**
* A 3D model instance collection. All instances reference the same underlying model, but have unique
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's mark this @private until we hook it up to 3D Tiles. This way we can change it if needed. We probably won't merge it until then either, but we can still merge billboard instancing.


this._model = undefined;
this._boundingSphere = undefined;
this._instancingEnabled = false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps _instancingSupported. I had to look at all of the code to realize what this is for.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 28, 2015

I suggest we hook this up to 3D Tiles before doing the following items in your task list:

  • Handle adding and removing instances
  • Handle updating instances
  • Frustum culling instances (optional)

We would still do the others beforehand.

};

defineProperties(ModelInstanceCollection.prototype, {
model : {
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this getter used for?

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 28, 2015

This is off to a good start, but I am not sure that ModelInstanceCollection and Model and factored correctly; it feels like we had to put too many changes into Model so it is losing cohesion. Let's brainstorm more on if this is the right approach.

var position = new Cesium.Cartesian3.fromDegrees(longitude, latitude, height + i * 20);

var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, heading, pitch, roll);
instances.push({
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll need an explicit ModelInstance type as we flush out picking, show/hide, etc.

@lilleyse
Copy link
Contributor Author

I was able to fix the jittering issues by trying something you mentioned earlier. I created a uniform for the modelView matrix of the collection's bounding volume. Then I modified each instance's model matrix to be an offset from the center of the bounding volume.

This will work fine for 3d tiles at least. For larger regions, I could see us doing a similar approach - finding a bounding volume for the visible set of objects. Or just subdividing collections before hand, or stream the instance modelView matrices.

I still need to do all the refactoring, so you don't have to check this code yet.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 28, 2015

Great news. When zoomed in close, this should be good for ~131,071 meter spacing. See http://blogs.agi.com/insight3d/index.php/2008/09/03/precisions-precisions/

For instanced satellite models, for example, we would probably just stream the model matrices. For static models, 3D Tiles implicitly provides subdivision.

@lilleyse
Copy link
Contributor Author

Updated so that all the instancing code out of Model.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 30, 2015

@lilleyse can you please update the task list at the top of this PR?

@@ -772,6 +781,10 @@ define([
return JSON.parse(json);
}

Model.getDefaultCacheKey = function(url) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why put this on Model instead of just having a file-scoped function? Do you plan to use this in the tests?

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 calling it in ModelInstanceCollection as well. I'm not really happy with this either.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I missed that. I think it is fine; I'll let you know if I come up with anything else.

In the meantime, explicitly mark it @private.

Copy link
Contributor

Choose a reason for hiding this comment

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

At the very least, it should be Model._getDefaultCacheKey and be marked @private. But why not just have ModelInstanceCollection access the _url property directly? Can't _url be undefined if the model was loaded from a JSON object?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When making the cache key Model converts the url to an absolute url, otherwise I would use _url directly. I'm handling the case where ModelInstanceCollection creates the Model from JSON or binary now.

@@ -306,6 +306,16 @@ define([
this._releaseGltfJson = defaultValue(options.releaseGltfJson, false);
this._animationIds = undefined;

// Undocumented options
Copy link
Contributor

Choose a reason for hiding this comment

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

I can help you set up some test data for when we merge this into the 3d-tiles branch and need to confirm it still works after fixing the merge conflicts.

for (i = 0; i < commandsLength; ++i) {
var modelCommand = modelCommands[i];
for (j = 0; j < instancesLength; ++j) {
var commandIndex = i*instancesLength+j;
Copy link
Contributor

Choose a reason for hiding this comment

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

We always use whitespace, e.g., i * instancesLength + j

return;
}

if (this._show === false) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if (!this._show) {

var model = this._model;
model.update(context, frameState, []);

if (model._ready && (this._state === LoadState.LOADING)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Use model.ready.

@pjcozzi
Copy link
Contributor

pjcozzi commented Sep 30, 2015

This is getting into pretty good shape. I'll make another pass over it once we flush it out by integrating it with 3D Tiles and writing the tests.

@pjcozzi pjcozzi closed this Oct 5, 2015
@pjcozzi
Copy link
Contributor

pjcozzi commented Oct 6, 2015

The rest of this review is in #3059, which is a pull request into the 3d-tiles branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants