Skip to content

Commit 0ffd273

Browse files
authored
Merge pull request #6805 from AnalyticalGraphicsInc/gltf-update-pipeline
Update gltf Pipeline and support KHR_techniques_webgl and KHR_blend
2 parents d9bb9c2 + c0eaf28 commit 0ffd273

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+5274
-3532
lines changed

CHANGES.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Change Log
44
### 1.50 - 2018-10-01
55

66
##### Additions :tada:
7+
* Added support for glTF extension [KHR_materials_pbrSpecularGlossiness](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness) [#7006](https://github.com/AnalyticalGraphicsInc/cesium/pull/7006).
8+
* Added support for glTF extension [KHR_materials_unlit](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit) [#6977](https://github.com/AnalyticalGraphicsInc/cesium/pull/6977).
9+
* Added support for glTF extensions [KHR_techniques_webgl](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_techniques_webgl) and [KHR_blend](https://github.com/KhronosGroup/glTF/pull/1302). [#6805](https://github.com/AnalyticalGraphicsInc/cesium/pull/6805)
10+
* Update [gltf-pipeline](https://github.com/AnalyticalGraphicsInc/gltf-pipeline/) to 2.0. [#6805](https://github.com/AnalyticalGraphicsInc/cesium/pull/6805)
711
* Added `cartographicLimitRectangle` to `Globe`. Use this to limit terrain and imagery to a specific `Rectangle` area. [#6987](https://github.com/AnalyticalGraphicsInc/cesium/pull/6987)
812
* Added `OpenCageGeocoderService`, which provides geocoding via [OpenCage](https://opencagedata.com/). [#7015](https://github.com/AnalyticalGraphicsInc/cesium/pull/7015)
913

@@ -28,7 +32,6 @@ Change Log
2832
* Added `GeocoderViewModel.destinationFound` for specifying a function that is called upon a successful geocode. The default behavior is to fly to the destination found by the geocoder. [#6915](https://github.com/AnalyticalGraphicsInc/cesium/pull/6915
2933
* Added `ClippingPlaneCollection.planeAdded` and `ClippingPlaneCollection.planeRemoved` events. `planeAdded` is raised when a new plane is added to the collection and `planeRemoved` is raised when a plane is removed. [#6875](https://github.com/AnalyticalGraphicsInc/cesium/pull/6875)
3034
* Added `Matrix4.setScale` for setting the scale on an affine transformation matrix [#6888](https://github.com/AnalyticalGraphicsInc/cesium/pull/6888)
31-
)
3235
* Added optional `width` and `height` to `Scene.drillPick` for specifying a search area. [#6922](https://github.com/AnalyticalGraphicsInc/cesium/pull/6922)
3336
* Added `Cesium3DTileset.root` for getting the root tile of a tileset. [#6944](https://github.com/AnalyticalGraphicsInc/cesium/pull/6944)
3437
* Added `Cesium3DTileset.extras` and `Cesium3DTile.extras` for getting application specific metadata from 3D Tiles. [#6974](https://github.com/AnalyticalGraphicsInc/cesium/pull/6974)

Source/ThirdParty/GltfPipeline/webGLConstantToGlslType.js Source/Core/webGLConstantToGlslType.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
define([
2-
'../../Core/WebGLConstants'
2+
'./WebGLConstants'
33
], function(
44
WebGLConstants) {
55
'use strict';

Source/Scene/ClassificationModel.js

+48-163
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ define([
33
'../Core/BoundingSphere',
44
'../Core/Cartesian3',
55
'../Core/Cartesian4',
6-
'../Core/Cartographic',
76
'../Core/Color',
87
'../Core/combine',
98
'../Core/ComponentDatatype',
@@ -16,23 +15,22 @@ define([
1615
'../Core/IndexDatatype',
1716
'../Core/Matrix4',
1817
'../Core/PrimitiveType',
19-
'../Core/Quaternion',
20-
'../Core/Resource',
2118
'../Core/RuntimeError',
2219
'../Core/Transforms',
2320
'../Core/WebGLConstants',
2421
'../ThirdParty/GltfPipeline/addDefaults',
2522
'../ThirdParty/GltfPipeline/ForEach',
2623
'../ThirdParty/GltfPipeline/getAccessorByteStride',
2724
'../ThirdParty/GltfPipeline/numberOfComponentsForType',
28-
'../ThirdParty/GltfPipeline/parseBinaryGltf',
29-
'../ThirdParty/GltfPipeline/processModelMaterialsCommon',
30-
'../ThirdParty/GltfPipeline/processPbrMetallicRoughness',
25+
'../ThirdParty/GltfPipeline/parseGlb',
26+
'../ThirdParty/GltfPipeline/updateVersion',
3127
'../ThirdParty/when',
3228
'./Axis',
3329
'./ClassificationType',
3430
'./ModelLoadResources',
3531
'./ModelUtility',
32+
'./processModelMaterialsCommon',
33+
'./processPbrMaterials',
3634
'./SceneMode',
3735
'./Vector3DTileBatch',
3836
'./Vector3DTilePrimitive'
@@ -41,7 +39,6 @@ define([
4139
BoundingSphere,
4240
Cartesian3,
4341
Cartesian4,
44-
Cartographic,
4542
Color,
4643
combine,
4744
ComponentDatatype,
@@ -54,23 +51,22 @@ define([
5451
IndexDatatype,
5552
Matrix4,
5653
PrimitiveType,
57-
Quaternion,
58-
Resource,
5954
RuntimeError,
6055
Transforms,
6156
WebGLConstants,
6257
addDefaults,
6358
ForEach,
6459
getAccessorByteStride,
6560
numberOfComponentsForType,
66-
parseBinaryGltf,
67-
processModelMaterialsCommon,
68-
processPbrMetallicRoughness,
61+
parseGlb,
62+
updateVersion,
6963
when,
7064
Axis,
7165
ClassificationType,
7266
ModelLoadResources,
7367
ModelUtility,
68+
processModelMaterialsCommon,
69+
processPbrMaterials,
7470
SceneMode,
7571
Vector3DTileBatch,
7672
Vector3DTilePrimitive) {
@@ -84,12 +80,7 @@ define([
8480

8581
var boundingSphereCartesian3Scratch = new Cartesian3();
8682

87-
var ModelState = {
88-
NEEDS_LOAD : 0,
89-
LOADING : 1,
90-
LOADED : 2,
91-
FAILED : 3
92-
};
83+
var ModelState = ModelUtility.ModelState;
9384

9485
///////////////////////////////////////////////////////////////////////////
9586

@@ -102,18 +93,16 @@ define([
10293
*
10394
* @private
10495
*
105-
* @param {Object} [options] Object with the following properties:
106-
* @param {Object|ArrayBuffer|Uint8Array} options.gltf The object for the glTF JSON or an arraybuffer of Binary glTF defined by the KHR_binary_glTF extension.
107-
* @param {Resource|String} [options.basePath=''] The base path that paths in the glTF JSON are relative to.
96+
* @param {Object} options Object with the following properties:
97+
* @param {ArrayBuffer|Uint8Array} options.gltf A binary glTF buffer.
10898
* @param {Boolean} [options.show=true] Determines if the model primitive will be shown.
10999
* @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates.
110100
* @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model.
111101
* @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe.
112102
* @param {ClassificationType} [options.classificationType] What this model will classify.
113103
*
114-
* @exception {DeveloperError} bgltf is not a valid Binary glTF file.
115-
* @exception {DeveloperError} Only glTF Binary version 1 is supported.
116104
* @exception {RuntimeError} Only binary glTF is supported.
105+
* @exception {RuntimeError} Buffer data must be embedded in the binary glTF.
117106
* @exception {RuntimeError} Only one node is supported for classification and it must have a mesh.
118107
* @exception {RuntimeError} Only one mesh is supported when using b3dm for classification.
119108
* @exception {RuntimeError} Only one primitive per mesh is supported when using b3dm for classification.
@@ -129,15 +118,22 @@ define([
129118
}
130119

131120
if (gltf instanceof Uint8Array) {
132-
// Binary glTF
133-
gltf = parseBinaryGltf(gltf); // Updates to 2.0 and adds pipeline extras
121+
// Parse and update binary glTF
122+
gltf = parseGlb(gltf);
123+
updateVersion(gltf);
134124
addDefaults(gltf);
135125
processModelMaterialsCommon(gltf);
136-
processPbrMetallicRoughness(gltf);
126+
processPbrMaterials(gltf);
137127
} else {
138128
throw new RuntimeError('Only binary glTF is supported as a classifier.');
139129
}
140130

131+
ForEach.buffer(gltf, function(buffer) {
132+
if (!defined(buffer.extras._pipeline.source)) {
133+
throw new RuntimeError('Buffer data must be embedded in the binary gltf.');
134+
}
135+
});
136+
141137
var gltfNodes = gltf.nodes;
142138
var gltfMeshes = gltf.meshes;
143139

@@ -168,9 +164,6 @@ define([
168164

169165
this._gltf = gltf;
170166

171-
var basePath = defaultValue(options.basePath, '');
172-
this._resource = Resource.createIfNeeded(basePath);
173-
174167
/**
175168
* Determines if the model primitive will be shown.
176169
*
@@ -288,26 +281,6 @@ define([
288281
}
289282
},
290283

291-
/**
292-
* The base path that paths in the glTF JSON are relative to. The base
293-
* path is the same path as the path containing the .gltf file
294-
* minus the .gltf file, when binary, image, and shader files are
295-
* in the same directory as the .gltf. When this is <code>''</code>,
296-
* the app's base path is used.
297-
*
298-
* @memberof ClassificationModel.prototype
299-
*
300-
* @type {String}
301-
* @readonly
302-
*
303-
* @default ''
304-
*/
305-
basePath : {
306-
get : function() {
307-
return this._resource.url;
308-
}
309-
},
310-
311284
/**
312285
* The model's bounding sphere in its local coordinate system.
313286
*
@@ -497,52 +470,8 @@ define([
497470
}
498471
});
499472

500-
var aMinScratch = new Cartesian3();
501-
var aMaxScratch = new Cartesian3();
502-
503-
function computeBoundingSphere(model) {
504-
var gltf = model.gltf;
505-
var gltfNodes = gltf.nodes;
506-
var gltfMeshes = gltf.meshes;
507-
508-
var min = new Cartesian3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
509-
var max = new Cartesian3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
510-
511-
var n = gltfNodes[0];
512-
var meshId = n.mesh;
513-
514-
var transformToRoot = ModelUtility.getTransform(n);
515-
var mesh = gltfMeshes[meshId];
516-
var primitive = mesh.primitives[0];
517-
var positionAccessor = primitive.attributes.POSITION;
518-
var minMax = ModelUtility.getAccessorMinMax(gltf, positionAccessor);
519-
var aMin = Cartesian3.fromArray(minMax.min, 0, aMinScratch);
520-
var aMax = Cartesian3.fromArray(minMax.max, 0, aMaxScratch);
521-
if (defined(min) && defined(max)) {
522-
Matrix4.multiplyByPoint(transformToRoot, aMin, aMin);
523-
Matrix4.multiplyByPoint(transformToRoot, aMax, aMax);
524-
Cartesian3.minimumByComponent(min, aMin, min);
525-
Cartesian3.maximumByComponent(max, aMax, max);
526-
}
527-
528-
var boundingSphere = BoundingSphere.fromCornerPoints(min, max);
529-
if (model._upAxis === Axis.Y) {
530-
BoundingSphere.transformWithoutScale(boundingSphere, Axis.Y_UP_TO_Z_UP, boundingSphere);
531-
} else if (model._upAxis === Axis.X) {
532-
BoundingSphere.transformWithoutScale(boundingSphere, Axis.X_UP_TO_Z_UP, boundingSphere);
533-
}
534-
return boundingSphere;
535-
}
536-
537473
///////////////////////////////////////////////////////////////////////////
538474

539-
function getFailedLoadFunction(model, type, path) {
540-
return function() {
541-
model._state = ModelState.FAILED;
542-
model._readyPromise.reject(new RuntimeError('Failed to load ' + type + ': ' + path));
543-
};
544-
}
545-
546475
function addBuffersToLoadResources(model) {
547476
var gltf = model.gltf;
548477
var loadResources = model._loadResources;
@@ -551,36 +480,6 @@ define([
551480
});
552481
}
553482

554-
function bufferLoad(model, id) {
555-
return function(arrayBuffer) {
556-
var loadResources = model._loadResources;
557-
var buffer = new Uint8Array(arrayBuffer);
558-
--loadResources.pendingBufferLoads;
559-
model.gltf.buffers[id].extras._pipeline.source = buffer;
560-
};
561-
}
562-
563-
function parseBuffers(model) {
564-
var loadResources = model._loadResources;
565-
// Iterate this way for compatibility with objects and arrays
566-
var buffers = model.gltf.buffers;
567-
var length = buffers.length;
568-
for (var i = 0; i < length; ++i) {
569-
var buffer = buffers[i];
570-
buffer.extras = defaultValue(buffer.extras, {});
571-
buffer.extras._pipeline = defaultValue(buffer.extras._pipeline, {});
572-
if (defined(buffer.extras._pipeline.source)) {
573-
loadResources.buffers[i] = buffer.extras._pipeline.source;
574-
} else {
575-
var bufferResource = model._resource.getDerivedResource({
576-
url : buffer.uri
577-
});
578-
++loadResources.pendingBufferLoads;
579-
bufferResource.fetchArrayBuffer().then(bufferLoad(model, i)).otherwise(getFailedLoadFunction(model, 'buffer', bufferResource.uri));
580-
}
581-
}
582-
}
583-
584483
function parseBufferViews(model) {
585484
var bufferViews = model.gltf.bufferViews;
586485

@@ -745,11 +644,7 @@ define([
745644

746645
function createVertexArray(model) {
747646
var loadResources = model._loadResources;
748-
if (!loadResources.finishedBuffersCreation()) {
749-
return;
750-
}
751-
752-
if (defined(model._vertexArray)) {
647+
if (!loadResources.finishedBuffersCreation() || defined(model._vertexArray)) {
753648
return;
754649
}
755650

@@ -762,25 +657,22 @@ define([
762657
var primitive = primitives[0];
763658
var attributeLocations = getAttributeLocations();
764659
var attributes = {};
765-
var primitiveAttributes = primitive.attributes;
766-
for (var attributeName in primitiveAttributes) {
767-
if (primitiveAttributes.hasOwnProperty(attributeName)) {
768-
var attributeLocation = attributeLocations[attributeName];
769-
// Skip if the attribute is not used by the material, e.g., because the asset was exported
770-
// with an attribute that wasn't used and the asset wasn't optimized.
771-
if (defined(attributeLocation)) {
772-
var a = accessors[primitiveAttributes[attributeName]];
773-
attributes[attributeName] = {
774-
index : attributeLocation,
775-
vertexBuffer : rendererBuffers[a.bufferView],
776-
componentsPerAttribute : numberOfComponentsForType(a.type),
777-
componentDatatype : a.componentType,
778-
offsetInBytes : a.byteOffset,
779-
strideInBytes : getAccessorByteStride(gltf, a)
780-
};
781-
}
660+
ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeName) {
661+
// Skip if the attribute is not used by the material, e.g., because the asset
662+
// was exported with an attribute that wasn't used and the asset wasn't optimized.
663+
var attributeLocation = attributeLocations[attributeName];
664+
if (defined(attributeLocation)) {
665+
var a = accessors[accessorId];
666+
attributes[attributeName] = {
667+
index: attributeLocation,
668+
vertexBuffer: rendererBuffers[a.bufferView],
669+
componentsPerAttribute: numberOfComponentsForType(a.type),
670+
componentDatatype: a.componentType,
671+
offsetInBytes: a.byteOffset,
672+
strideInBytes: getAccessorByteStride(gltf, a)
673+
};
782674
}
783-
}
675+
});
784676

785677
var indexBuffer;
786678
if (defined(primitive.indices)) {
@@ -813,23 +705,16 @@ define([
813705
return;
814706
}
815707

816-
var techniques = model.gltf.techniques;
817-
var technique = techniques[0];
818-
var parameters = technique.parameters;
819-
var uniforms = technique.uniforms;
820-
821708
var uniformMap = {};
822-
for (var name in uniforms) {
823-
if (uniforms.hasOwnProperty(name) && name !== 'extras') {
824-
var parameterName = uniforms[name];
825-
var parameter = parameters[parameterName];
826-
827-
if (!defined(parameter.semantic) || !defined(gltfSemanticUniforms[parameter.semantic])) {
828-
continue;
709+
ForEach.technique(model.gltf, function(technique) {
710+
ForEach.techniqueUniform(technique, function(uniform, uniformName) {
711+
if (!defined(uniform.semantic) || !defined(gltfSemanticUniforms[uniform.semantic])) {
712+
return;
829713
}
830-
uniformMap[name] = gltfSemanticUniforms[parameter.semantic](context.uniformState, model);
831-
}
832-
}
714+
715+
uniformMap[uniformName] = gltfSemanticUniforms[uniform.semantic](context.uniformState, model);
716+
});
717+
});
833718

834719
model._uniformMap = uniformMap;
835720
}
@@ -1095,7 +980,7 @@ define([
1095980
}
1096981

1097982
this._loadResources = new ModelLoadResources();
1098-
parseBuffers(this);
983+
ModelUtility.parseBuffers(this);
1099984
}
1100985
}
1101986

@@ -1111,7 +996,7 @@ define([
1111996
addBuffersToLoadResources(this);
1112997
parseBufferViews(this);
1113998

1114-
this._boundingSphere = computeBoundingSphere(this);
999+
this._boundingSphere = ModelUtility.computeBoundingSphere(this);
11151000
this._initialRadius = this._boundingSphere.radius;
11161001
createResources(this, frameState);
11171002
}

0 commit comments

Comments
 (0)