Skip to content

Commit f13dc97

Browse files
authored
Merge pull request #6632 from AnalyticalGraphicsInc/gltf-2.0-orientation
Detect glTF 2.0 and change forward to match Cesium's convention.
2 parents f73a9f6 + 56f94d9 commit f13dc97

File tree

9 files changed

+135
-8
lines changed

9 files changed

+135
-8
lines changed

Apps/SampleData/models/DracoCompressed/CesiumMilkTruck.gltf

+18
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@
1717
"children": [
1818
3,
1919
1
20+
],
21+
"matrix": [
22+
0,
23+
0,
24+
1,
25+
0,
26+
0,
27+
1,
28+
0,
29+
0,
30+
-1,
31+
0,
32+
0,
33+
0,
34+
0,
35+
0,
36+
0,
37+
1
2038
]
2139
},
2240
{

Apps/Sandcastle/gallery/Physically-Based Materials.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
viewer.scene.globe.depthTestAgainstTerrain = true;
5454

5555
var position = new Cesium.Cartesian3(-1371108.6511167218, -5508684.080096612, 2901825.449865087);
56-
var heading = Cesium.Math.toRadians(90);
56+
var heading = Cesium.Math.toRadians(180);
5757
var pitch = Cesium.Math.toRadians(2);
5858
var roll = Cesium.Math.toRadians(-6);
5959
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);

CHANGES.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ Change Log
33

44
### 1.47 - 2018-07-02
55

6+
##### Breaking Changes :mega:
7+
* glTF 2.0 models corrected to face +Z forwards per specification. Internally Cesium uses +X as forward, so a new +Z to +X rotation was added for 2.0 models only. [#6632](https://github.com/AnalyticalGraphicsInc/cesium/pull/6632)
8+
69
##### Additions :tada:
710
* `PostProcessStage` has a `selectedFeatures` property which is an array of primitives used for selectively applying a post-process stage. In the fragment shader, use the function `bool czm_selected(vec2 textureCoordinates` to determine whether or not the stage should be applied at that fragment.
811
* The black-and-white and silhouette stages have per-feature support.
@@ -27,6 +30,7 @@ Change Log
2730
* Removed `Scene.copyGlobeDepth`. Globe depth will now be copied by default when supported. [#6393](https://github.com/AnalyticalGraphicsInc/cesium/pull/6393)
2831
* The default `classificationType` for `GroundPrimitive`, `CorridorGraphics`, `EllipseGraphics`, `PolygonGraphics` and `RectangleGraphics` is now `ClassificationType.TERRAIN`. If you wish the geometry to color both terrain and 3D tiles, pass in the option `classificationType: Cesium.ClassificationType.BOTH`.
2932
* Removed support for the `options` argument for `Credit` [#6373](https://github.com/AnalyticalGraphicsInc/cesium/issues/6373). Pass in an html string instead.
33+
* glTF 2.0 models corrected to face +Z forwards per specification. Internally Cesium uses +X as forward, so a new +Z to +X rotation was added for 2.0 models only. [#6632](https://github.com/AnalyticalGraphicsInc/cesium/pull/6632)
3034

3135
##### Deprecated :hourglass_flowing_sand:
3236
* The `Scene.fxaa` property has been deprecated and will be removed in Cesium 1.47. Use `Scene.postProcessStages.fxaa.enabled`.

Source/Scene/Batched3DModel3DTileContent.js

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ define([
1212
'../Core/RequestType',
1313
'../Core/RuntimeError',
1414
'../Renderer/Pass',
15+
'./Axis',
1516
'./Cesium3DTileBatchTable',
1617
'./Cesium3DTileFeature',
1718
'./Cesium3DTileFeatureTable',
@@ -32,6 +33,7 @@ define([
3233
RequestType,
3334
RuntimeError,
3435
Pass,
36+
Axis,
3537
Cesium3DTileBatchTable,
3638
Cesium3DTileFeature,
3739
Cesium3DTileFeatureTable,
@@ -356,6 +358,7 @@ define([
356358
requestType : RequestType.TILES3D,
357359
modelMatrix : tile.computedTransform,
358360
upAxis : tileset._gltfUpAxis,
361+
forwardAxis : Axis.X,
359362
shadows: tileset.shadows,
360363
debugWireframe: tileset.debugWireframe,
361364
incrementallyLoadTextures : false,
@@ -376,6 +379,7 @@ define([
376379
requestType : RequestType.TILES3D,
377380
modelMatrix : tile.computedTransform,
378381
upAxis : tileset._gltfUpAxis,
382+
forwardAxis : Axis.X,
379383
debugWireframe : tileset.debugWireframe,
380384
vertexShaderLoaded : getVertexShaderCallback(content),
381385
classificationShaderLoaded : getClassificationFragmentShaderCallback(content),

Source/Scene/Model.js

+32
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ define([
577577
this._ignoreCommands = defaultValue(options.ignoreCommands, false);
578578
this._requestType = options.requestType;
579579
this._upAxis = defaultValue(options.upAxis, Axis.Y);
580+
this._forwardAxis = defaultValue(options.forwardAxis, Axis.Z);
580581

581582
/**
582583
* @private
@@ -970,6 +971,25 @@ define([
970971
}
971972
},
972973

974+
/**
975+
* Gets the model's forward axis.
976+
* By default, glTF 2.0 models are z-forward according to the glTF spec, however older
977+
* glTF (1.0, 0.8) models used x-forward. Note that only Axis.X and Axis.Z are supported.
978+
*
979+
* @memberof Model.prototype
980+
*
981+
* @type {Number}
982+
* @default Axis.Z
983+
* @readonly
984+
*
985+
* @private
986+
*/
987+
forwardAxis : {
988+
get : function() {
989+
return this._forwardAxis;
990+
}
991+
},
992+
973993
/**
974994
* Gets the model's triangle count.
975995
*
@@ -1367,6 +1387,10 @@ define([
13671387
} else if (model._upAxis === Axis.X) {
13681388
BoundingSphere.transformWithoutScale(boundingSphere, Axis.X_UP_TO_Z_UP, boundingSphere);
13691389
}
1390+
if (model._forwardAxis === Axis.Z) {
1391+
// glTF 2.0 has a Z-forward convention that must be adapted here to X-forward.
1392+
BoundingSphere.transformWithoutScale(boundingSphere, Axis.Z_UP_TO_X_UP, boundingSphere);
1393+
}
13701394
return boundingSphere;
13711395
}
13721396

@@ -4225,6 +4249,10 @@ define([
42254249
};
42264250
frameState.brdfLutGenerator.update(frameState);
42274251
updateVersion(this.gltf);
4252+
if (defined(this.gltf.asset) && defined(this.gltf.asset.extras) &&
4253+
this.gltf.asset.extras.gltf_pipeline_upgrade_10to20) {
4254+
this._forwardAxis = Axis.X;
4255+
}
42284256
ModelUtility.checkSupportedExtensions(this.extensionsRequired);
42294257
addPipelineExtras(this.gltf);
42304258
addDefaults(this.gltf);
@@ -4358,6 +4386,10 @@ define([
43584386
} else if (this._upAxis === Axis.X) {
43594387
Matrix4.multiplyTransformation(computedModelMatrix, Axis.X_UP_TO_Z_UP, computedModelMatrix);
43604388
}
4389+
if (this._forwardAxis === Axis.Z) {
4390+
// glTF 2.0 has a Z-forward convention that must be adapted here to X-forward.
4391+
Matrix4.multiplyTransformation(computedModelMatrix, Axis.Z_UP_TO_X_UP, computedModelMatrix);
4392+
}
43614393
}
43624394

43634395
// Update modelMatrix throughout the graph as needed

Source/ThirdParty/GltfPipeline/updateVersion.js

+4
Original file line numberDiff line numberDiff line change
@@ -883,8 +883,12 @@ define([
883883
if (!defined(gltf.asset)) {
884884
gltf.asset = {};
885885
}
886+
if (!defined(gltf.asset.extras)) {
887+
gltf.asset.extras = {};
888+
}
886889
var asset = gltf.asset;
887890
asset.version = '2.0';
891+
asset.extras.gltf_pipeline_upgrade_10to20 = true;
888892
// material.instanceTechnique properties should be directly on the material. instanceTechnique is a gltf 0.8 property but is seen in some 1.0 models.
889893
updateInstanceTechniques(gltf);
890894
// animation.samplers now refers directly to accessors and animation.parameters should be removed

Specs/Data/Models/DracoCompression/CesiumMan/CesiumMan.gltf

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
1
1919
],
2020
"matrix": [
21-
1,
2221
0,
2322
0,
23+
1,
2424
0,
25+
1,
2526
0,
2627
0,
27-
-1,
2828
0,
2929
0,
3030
1,

Specs/Data/Models/DracoCompression/CesiumMilkTruck/CesiumMilkTruck.gltf

+18
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@
1717
"children": [
1818
3,
1919
1
20+
],
21+
"matrix": [
22+
0,
23+
0,
24+
1,
25+
0,
26+
0,
27+
1,
28+
0,
29+
0,
30+
-1,
31+
0,
32+
0,
33+
0,
34+
0,
35+
0,
36+
0,
37+
1
2038
]
2139
},
2240
{

Specs/Scene/ModelSpec.js

+52-5
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ defineSuite([
396396
model.show = false;
397397
});
398398

399-
it('Renders x-up model', function() {
399+
it('renders x-up model', function() {
400400
return Resource.fetchJson(boxEcefUrl).then(function(gltf) {
401401
// Model data is z-up. Edit the transform to be z-up to x-up.
402402
gltf.nodes.node_transform.matrix = Matrix4.pack(Axis.Z_UP_TO_X_UP, new Array(16));
@@ -412,7 +412,7 @@ defineSuite([
412412
});
413413
});
414414

415-
it('Renders y-up model', function() {
415+
it('renders y-up model', function() {
416416
return Resource.fetchJson(boxEcefUrl).then(function(gltf) {
417417
// Model data is z-up. Edit the transform to be z-up to y-up.
418418
gltf.nodes.node_transform.matrix = Matrix4.pack(Axis.Z_UP_TO_Y_UP, new Array(16));
@@ -428,7 +428,7 @@ defineSuite([
428428
});
429429
});
430430

431-
it('Renders z-up model', function() {
431+
it('renders z-up model', function() {
432432
return Resource.fetchJson(boxEcefUrl).then(function(gltf) {
433433
// Model data is z-up. Edit the transform to be the identity.
434434
gltf.nodes.node_transform.matrix = Matrix4.pack(Matrix4.IDENTITY, new Array(16));
@@ -444,6 +444,50 @@ defineSuite([
444444
});
445445
});
446446

447+
it('renders x-forward model', function() {
448+
return Resource.fetchJson(boxEcefUrl).then(function(gltf) {
449+
return loadModelJson(gltf, {
450+
forwardAxis : Axis.X
451+
}).then(function(m) {
452+
verifyRender(m);
453+
expect(m.forwardAxis).toBe(Axis.X);
454+
primitives.remove(m);
455+
});
456+
});
457+
});
458+
459+
it('renders z-forward model', function() {
460+
return Resource.fetchJson(boxPbrUrl).then(function(gltf) {
461+
return loadModelJson(gltf, {
462+
forwardAxis : Axis.Z
463+
}).then(function(m) {
464+
verifyRender(m);
465+
expect(m.forwardAxis).toBe(Axis.Z);
466+
primitives.remove(m);
467+
});
468+
});
469+
});
470+
471+
it('detects glTF 1.0 models as x-forward', function() {
472+
return Resource.fetchJson(boxEcefUrl).then(function(gltf) {
473+
return loadModelJson(gltf).then(function(m) {
474+
verifyRender(m);
475+
expect(m.forwardAxis).toBe(Axis.X);
476+
primitives.remove(m);
477+
});
478+
});
479+
});
480+
481+
it('detects glTF 2.0 models as z-forward', function() {
482+
return Resource.fetchJson(boxPbrUrl).then(function(gltf) {
483+
return loadModelJson(gltf).then(function(m) {
484+
verifyRender(m);
485+
expect(m.forwardAxis).toBe(Axis.Z);
486+
primitives.remove(m);
487+
});
488+
});
489+
});
490+
447491
it('resolves readyPromise', function() {
448492
return texturedBoxModel.readyPromise.then(function(model) {
449493
verifyRender(model);
@@ -2229,6 +2273,7 @@ defineSuite([
22292273

22302274
function checkVertexColors(model) {
22312275
model.zoomTo();
2276+
scene.camera.rotateRight(CesiumMath.PI_OVER_TWO);
22322277
scene.camera.moveUp(0.1);
22332278
// Red
22342279
scene.camera.moveLeft(0.5);
@@ -2453,7 +2498,8 @@ defineSuite([
24532498

24542499
it('loads a glTF with KHR_draco_mesh_compression extension with integer attributes', function() {
24552500
return loadModel(dracoCompressedModelWithAnimationUrl, {
2456-
dequantizeInShader : false
2501+
dequantizeInShader : false,
2502+
forwardAxis : Axis.X
24572503
}).then(function(m) {
24582504
verifyRender(m);
24592505
primitives.remove(m);
@@ -2501,7 +2547,8 @@ defineSuite([
25012547

25022548
it('loads a draco compressed glTF and dequantizes in the shader, skipping generic attributes', function() {
25032549
return loadModel(dracoCompressedModelWithAnimationUrl, {
2504-
dequantizeInShader : true
2550+
dequantizeInShader : true,
2551+
forwardAxis : Axis.X
25052552
}).then(function(m) {
25062553
verifyRender(m);
25072554

0 commit comments

Comments
 (0)