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 glTF animations in tileset #8983

Merged
merged 9 commits into from
Jun 28, 2020
Merged

Conversation

ErixenCruz
Copy link
Contributor

Fixes #8962
Fixed issue where tileset was not playing glTF animations.

@ErixenCruz ErixenCruz requested a review from lilleyse June 22, 2020 19:06
@cesium-concierge
Copy link

Thanks for the pull request @ErixenCruz!

  • ✔️ Signed CLA found.
  • ❔ Unit tests were not updated.
    • Make sure you've updated tests to reflect your changes, added tests for any new code, and ran the code coverage tool.

Reviewers, don't forget to make sure that:

  • Cesium Viewer works.
  • Works in 2D/CV.
  • Works (or fails gracefully) in IE11.

@lilleyse
Copy link
Contributor

@ErixenCruz here are some tilesets to test with.

BatchedAnimated.zip - place in Specs/Data/Cesium3DTiles/Batched/
InstancedAnimated.zip - place in Specs/Data/Cesium3DTiles/Instanced/

Local sandcastle for viewing these

Add two tests to Cesium3DTilesetSpec, one for the batched tileset and another for the instanced tileset. Since the tests will be very similar you can factor out most of the work into a local function that both tests will call. The test should

  1. Load the tileset - see the "renders tileset" test for an example
  2. Once the tileset is loaded, render the scene at a specific time - see "renders with imageBaseLightingFactor" for an example.
  3. Grab the first command in frameState's command list (see "adds stencil clear command first when unresolved") and save it's model matrix (you can use Matrix4.clone)
  4. Render the scene again 0.5 seconds later.
  5. Grab the first command again and compare the model matrix with the saved model matrix. You can use expect(matrixA).not.toEqual(matrixB) for this.

Let me know how this goes!

@ErixenCruz
Copy link
Contributor Author

@lilleyse How's that?

Copy link
Contributor

@lilleyse lilleyse left a comment

Choose a reason for hiding this comment

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

Looks great @ErixenCruz, just one small suggestion for the instanced tileset code.

Comment on lines 1001 to 1009
this._model.readyPromise.then(function (model) {
model.activeAnimations
.addAll({
loop: ModelAnimationLoop.REPEAT,
})
.otherwise(function (error) {
that._state = LoadState.FAILED;
that._readyPromise.reject(error);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

The otherwise should be chained after .then rather than after .addAll. This .then/.otherwise chain allows the promise to be handled correctly whether the promise is resolved or rejected.

Chaining it after addAll wouldn't end up catching an error since addAll does not return a promise. My mistake for missing this earlier, I think I got lost in the indendation.

Suggested change
this._model.readyPromise.then(function (model) {
model.activeAnimations
.addAll({
loop: ModelAnimationLoop.REPEAT,
})
.otherwise(function (error) {
that._state = LoadState.FAILED;
that._readyPromise.reject(error);
});
this._model.readyPromise
.then(function (model) {
model.activeAnimations.addAll({
loop: ModelAnimationLoop.REPEAT,
});
})
.otherwise(function (error) {
that._state = LoadState.FAILED;
that._readyPromise.reject(error);
});

Copy link
Contributor

Choose a reason for hiding this comment

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

Despite this code suggestion, I've been thinking more about the overall design here and think it makes sense to bring the functionality to Instanced3DModel3DTileContent instead. I didn't noticed until reviewing that ModelInstanceCollection already has an activeAnimations getter and it's the caller's responsibility whether to add animations or not.

So the change will be something like this: in Instanced3DModel3DTileContent, after ModelInstanceCollection is created, add the animations when the collection is ready. It'll look just like the Batched3DModel3DTileContent code in this PR except that model will be a model instance collection.

@@ -637,6 +641,35 @@ describe(
});
});

function checkAnimation(url) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The tests looks great

@lilleyse
Copy link
Contributor

Looks like CI has some test failures. #8983 (comment) seems to be the cause. Once that's addressed there shouldn't be any issues.

@ErixenCruz
Copy link
Contributor Author

Even after the fixes, some tests still fail. In particular, Scene/Instanced3DModel3DTileContent rejects readyPromise on error times out. Investigating.

Comment on lines 442 to 445
.otherwise(function (error) {
//content._state = 3;
content._readyPromise.reject(error);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Note that Batched3DModel3DTileContent does not have a _readyPromise property, the readyPromise getter is actually just content._model.readyPromise. This otherwise block is not necessary and can be removed.

Comment on lines 558 to 561
.otherwise(function (error) {
//content._state = 3;
content._readyPromise.reject(error);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar comment to above - this .otherwise block is not needed.

Comment on lines 553 to 554
.then(function (model) {
model.activeAnimations.addAll({
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps rename model to collection

Comment on lines 999 to 1003
var that = this;
this._model.readyPromise.otherwise(function (error) {
that._state = LoadState.FAILED;
that._readyPromise.reject(error);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

This code is still required, otherwise the collection's own ready promise won't get rejected if there's a problem when loading the model.

@ErixenCruz
Copy link
Contributor Author

@lilleyse Tests pass! Like I mentioned, I have to rely on TravisCI for testing. Unreliable to run on my browser.

@lilleyse
Copy link
Contributor

Local tests work for me. There's some test failures on Mac/Chrome but none introduced in this branch.

Thanks @ErixenCruz

@lilleyse lilleyse merged commit 97492e7 into master Jun 28, 2020
@lilleyse lilleyse deleted the fix-glTF-animations-in-tileset branch June 28, 2020 00:11
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.

Support glTF animations in 3D Tiles payloads
3 participants