Skip to content

Commit

Permalink
Merge pull request #6805 from AnalyticalGraphicsInc/gltf-update-pipeline
Browse files Browse the repository at this point in the history
Update gltf Pipeline and support KHR_techniques_webgl and KHR_blend
  • Loading branch information
lilleyse authored Sep 19, 2018
2 parents d9bb9c2 + c0eaf28 commit 0ffd273
Show file tree
Hide file tree
Showing 63 changed files with 5,274 additions and 3,532 deletions.
5 changes: 4 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Change Log
### 1.50 - 2018-10-01

##### Additions :tada:
* 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).
* 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).
* 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)
* Update [gltf-pipeline](https://github.com/AnalyticalGraphicsInc/gltf-pipeline/) to 2.0. [#6805](https://github.com/AnalyticalGraphicsInc/cesium/pull/6805)
* Added `cartographicLimitRectangle` to `Globe`. Use this to limit terrain and imagery to a specific `Rectangle` area. [#6987](https://github.com/AnalyticalGraphicsInc/cesium/pull/6987)
* Added `OpenCageGeocoderService`, which provides geocoding via [OpenCage](https://opencagedata.com/). [#7015](https://github.com/AnalyticalGraphicsInc/cesium/pull/7015)

Expand All @@ -28,7 +32,6 @@ Change Log
* 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
* 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)
* Added `Matrix4.setScale` for setting the scale on an affine transformation matrix [#6888](https://github.com/AnalyticalGraphicsInc/cesium/pull/6888)
)
* Added optional `width` and `height` to `Scene.drillPick` for specifying a search area. [#6922](https://github.com/AnalyticalGraphicsInc/cesium/pull/6922)
* Added `Cesium3DTileset.root` for getting the root tile of a tileset. [#6944](https://github.com/AnalyticalGraphicsInc/cesium/pull/6944)
* Added `Cesium3DTileset.extras` and `Cesium3DTile.extras` for getting application specific metadata from 3D Tiles. [#6974](https://github.com/AnalyticalGraphicsInc/cesium/pull/6974)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
define([
'../../Core/WebGLConstants'
'./WebGLConstants'
], function(
WebGLConstants) {
'use strict';
Expand Down
211 changes: 48 additions & 163 deletions Source/Scene/ClassificationModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ define([
'../Core/BoundingSphere',
'../Core/Cartesian3',
'../Core/Cartesian4',
'../Core/Cartographic',
'../Core/Color',
'../Core/combine',
'../Core/ComponentDatatype',
Expand All @@ -16,23 +15,22 @@ define([
'../Core/IndexDatatype',
'../Core/Matrix4',
'../Core/PrimitiveType',
'../Core/Quaternion',
'../Core/Resource',
'../Core/RuntimeError',
'../Core/Transforms',
'../Core/WebGLConstants',
'../ThirdParty/GltfPipeline/addDefaults',
'../ThirdParty/GltfPipeline/ForEach',
'../ThirdParty/GltfPipeline/getAccessorByteStride',
'../ThirdParty/GltfPipeline/numberOfComponentsForType',
'../ThirdParty/GltfPipeline/parseBinaryGltf',
'../ThirdParty/GltfPipeline/processModelMaterialsCommon',
'../ThirdParty/GltfPipeline/processPbrMetallicRoughness',
'../ThirdParty/GltfPipeline/parseGlb',
'../ThirdParty/GltfPipeline/updateVersion',
'../ThirdParty/when',
'./Axis',
'./ClassificationType',
'./ModelLoadResources',
'./ModelUtility',
'./processModelMaterialsCommon',
'./processPbrMaterials',
'./SceneMode',
'./Vector3DTileBatch',
'./Vector3DTilePrimitive'
Expand All @@ -41,7 +39,6 @@ define([
BoundingSphere,
Cartesian3,
Cartesian4,
Cartographic,
Color,
combine,
ComponentDatatype,
Expand All @@ -54,23 +51,22 @@ define([
IndexDatatype,
Matrix4,
PrimitiveType,
Quaternion,
Resource,
RuntimeError,
Transforms,
WebGLConstants,
addDefaults,
ForEach,
getAccessorByteStride,
numberOfComponentsForType,
parseBinaryGltf,
processModelMaterialsCommon,
processPbrMetallicRoughness,
parseGlb,
updateVersion,
when,
Axis,
ClassificationType,
ModelLoadResources,
ModelUtility,
processModelMaterialsCommon,
processPbrMaterials,
SceneMode,
Vector3DTileBatch,
Vector3DTilePrimitive) {
Expand All @@ -84,12 +80,7 @@ define([

var boundingSphereCartesian3Scratch = new Cartesian3();

var ModelState = {
NEEDS_LOAD : 0,
LOADING : 1,
LOADED : 2,
FAILED : 3
};
var ModelState = ModelUtility.ModelState;

///////////////////////////////////////////////////////////////////////////

Expand All @@ -102,18 +93,16 @@ define([
*
* @private
*
* @param {Object} [options] Object with the following properties:
* @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.
* @param {Resource|String} [options.basePath=''] The base path that paths in the glTF JSON are relative to.
* @param {Object} options Object with the following properties:
* @param {ArrayBuffer|Uint8Array} options.gltf A binary glTF buffer.
* @param {Boolean} [options.show=true] Determines if the model primitive will be shown.
* @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates.
* @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model.
* @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe.
* @param {ClassificationType} [options.classificationType] What this model will classify.
*
* @exception {DeveloperError} bgltf is not a valid Binary glTF file.
* @exception {DeveloperError} Only glTF Binary version 1 is supported.
* @exception {RuntimeError} Only binary glTF is supported.
* @exception {RuntimeError} Buffer data must be embedded in the binary glTF.
* @exception {RuntimeError} Only one node is supported for classification and it must have a mesh.
* @exception {RuntimeError} Only one mesh is supported when using b3dm for classification.
* @exception {RuntimeError} Only one primitive per mesh is supported when using b3dm for classification.
Expand All @@ -129,15 +118,22 @@ define([
}

if (gltf instanceof Uint8Array) {
// Binary glTF
gltf = parseBinaryGltf(gltf); // Updates to 2.0 and adds pipeline extras
// Parse and update binary glTF
gltf = parseGlb(gltf);
updateVersion(gltf);
addDefaults(gltf);
processModelMaterialsCommon(gltf);
processPbrMetallicRoughness(gltf);
processPbrMaterials(gltf);
} else {
throw new RuntimeError('Only binary glTF is supported as a classifier.');
}

ForEach.buffer(gltf, function(buffer) {
if (!defined(buffer.extras._pipeline.source)) {
throw new RuntimeError('Buffer data must be embedded in the binary gltf.');
}
});

var gltfNodes = gltf.nodes;
var gltfMeshes = gltf.meshes;

Expand Down Expand Up @@ -168,9 +164,6 @@ define([

this._gltf = gltf;

var basePath = defaultValue(options.basePath, '');
this._resource = Resource.createIfNeeded(basePath);

/**
* Determines if the model primitive will be shown.
*
Expand Down Expand Up @@ -288,26 +281,6 @@ define([
}
},

/**
* The base path that paths in the glTF JSON are relative to. The base
* path is the same path as the path containing the .gltf file
* minus the .gltf file, when binary, image, and shader files are
* in the same directory as the .gltf. When this is <code>''</code>,
* the app's base path is used.
*
* @memberof ClassificationModel.prototype
*
* @type {String}
* @readonly
*
* @default ''
*/
basePath : {
get : function() {
return this._resource.url;
}
},

/**
* The model's bounding sphere in its local coordinate system.
*
Expand Down Expand Up @@ -497,52 +470,8 @@ define([
}
});

var aMinScratch = new Cartesian3();
var aMaxScratch = new Cartesian3();

function computeBoundingSphere(model) {
var gltf = model.gltf;
var gltfNodes = gltf.nodes;
var gltfMeshes = gltf.meshes;

var min = new Cartesian3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
var max = new Cartesian3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);

var n = gltfNodes[0];
var meshId = n.mesh;

var transformToRoot = ModelUtility.getTransform(n);
var mesh = gltfMeshes[meshId];
var primitive = mesh.primitives[0];
var positionAccessor = primitive.attributes.POSITION;
var minMax = ModelUtility.getAccessorMinMax(gltf, positionAccessor);
var aMin = Cartesian3.fromArray(minMax.min, 0, aMinScratch);
var aMax = Cartesian3.fromArray(minMax.max, 0, aMaxScratch);
if (defined(min) && defined(max)) {
Matrix4.multiplyByPoint(transformToRoot, aMin, aMin);
Matrix4.multiplyByPoint(transformToRoot, aMax, aMax);
Cartesian3.minimumByComponent(min, aMin, min);
Cartesian3.maximumByComponent(max, aMax, max);
}

var boundingSphere = BoundingSphere.fromCornerPoints(min, max);
if (model._upAxis === Axis.Y) {
BoundingSphere.transformWithoutScale(boundingSphere, Axis.Y_UP_TO_Z_UP, boundingSphere);
} else if (model._upAxis === Axis.X) {
BoundingSphere.transformWithoutScale(boundingSphere, Axis.X_UP_TO_Z_UP, boundingSphere);
}
return boundingSphere;
}

///////////////////////////////////////////////////////////////////////////

function getFailedLoadFunction(model, type, path) {
return function() {
model._state = ModelState.FAILED;
model._readyPromise.reject(new RuntimeError('Failed to load ' + type + ': ' + path));
};
}

function addBuffersToLoadResources(model) {
var gltf = model.gltf;
var loadResources = model._loadResources;
Expand All @@ -551,36 +480,6 @@ define([
});
}

function bufferLoad(model, id) {
return function(arrayBuffer) {
var loadResources = model._loadResources;
var buffer = new Uint8Array(arrayBuffer);
--loadResources.pendingBufferLoads;
model.gltf.buffers[id].extras._pipeline.source = buffer;
};
}

function parseBuffers(model) {
var loadResources = model._loadResources;
// Iterate this way for compatibility with objects and arrays
var buffers = model.gltf.buffers;
var length = buffers.length;
for (var i = 0; i < length; ++i) {
var buffer = buffers[i];
buffer.extras = defaultValue(buffer.extras, {});
buffer.extras._pipeline = defaultValue(buffer.extras._pipeline, {});
if (defined(buffer.extras._pipeline.source)) {
loadResources.buffers[i] = buffer.extras._pipeline.source;
} else {
var bufferResource = model._resource.getDerivedResource({
url : buffer.uri
});
++loadResources.pendingBufferLoads;
bufferResource.fetchArrayBuffer().then(bufferLoad(model, i)).otherwise(getFailedLoadFunction(model, 'buffer', bufferResource.uri));
}
}
}

function parseBufferViews(model) {
var bufferViews = model.gltf.bufferViews;

Expand Down Expand Up @@ -745,11 +644,7 @@ define([

function createVertexArray(model) {
var loadResources = model._loadResources;
if (!loadResources.finishedBuffersCreation()) {
return;
}

if (defined(model._vertexArray)) {
if (!loadResources.finishedBuffersCreation() || defined(model._vertexArray)) {
return;
}

Expand All @@ -762,25 +657,22 @@ define([
var primitive = primitives[0];
var attributeLocations = getAttributeLocations();
var attributes = {};
var primitiveAttributes = primitive.attributes;
for (var attributeName in primitiveAttributes) {
if (primitiveAttributes.hasOwnProperty(attributeName)) {
var attributeLocation = attributeLocations[attributeName];
// Skip if the attribute is not used by the material, e.g., because the asset was exported
// with an attribute that wasn't used and the asset wasn't optimized.
if (defined(attributeLocation)) {
var a = accessors[primitiveAttributes[attributeName]];
attributes[attributeName] = {
index : attributeLocation,
vertexBuffer : rendererBuffers[a.bufferView],
componentsPerAttribute : numberOfComponentsForType(a.type),
componentDatatype : a.componentType,
offsetInBytes : a.byteOffset,
strideInBytes : getAccessorByteStride(gltf, a)
};
}
ForEach.meshPrimitiveAttribute(primitive, function(accessorId, attributeName) {
// Skip if the attribute is not used by the material, e.g., because the asset
// was exported with an attribute that wasn't used and the asset wasn't optimized.
var attributeLocation = attributeLocations[attributeName];
if (defined(attributeLocation)) {
var a = accessors[accessorId];
attributes[attributeName] = {
index: attributeLocation,
vertexBuffer: rendererBuffers[a.bufferView],
componentsPerAttribute: numberOfComponentsForType(a.type),
componentDatatype: a.componentType,
offsetInBytes: a.byteOffset,
strideInBytes: getAccessorByteStride(gltf, a)
};
}
}
});

var indexBuffer;
if (defined(primitive.indices)) {
Expand Down Expand Up @@ -813,23 +705,16 @@ define([
return;
}

var techniques = model.gltf.techniques;
var technique = techniques[0];
var parameters = technique.parameters;
var uniforms = technique.uniforms;

var uniformMap = {};
for (var name in uniforms) {
if (uniforms.hasOwnProperty(name) && name !== 'extras') {
var parameterName = uniforms[name];
var parameter = parameters[parameterName];

if (!defined(parameter.semantic) || !defined(gltfSemanticUniforms[parameter.semantic])) {
continue;
ForEach.technique(model.gltf, function(technique) {
ForEach.techniqueUniform(technique, function(uniform, uniformName) {
if (!defined(uniform.semantic) || !defined(gltfSemanticUniforms[uniform.semantic])) {
return;
}
uniformMap[name] = gltfSemanticUniforms[parameter.semantic](context.uniformState, model);
}
}

uniformMap[uniformName] = gltfSemanticUniforms[uniform.semantic](context.uniformState, model);
});
});

model._uniformMap = uniformMap;
}
Expand Down Expand Up @@ -1095,7 +980,7 @@ define([
}

this._loadResources = new ModelLoadResources();
parseBuffers(this);
ModelUtility.parseBuffers(this);
}
}

Expand All @@ -1111,7 +996,7 @@ define([
addBuffersToLoadResources(this);
parseBufferViews(this);

this._boundingSphere = computeBoundingSphere(this);
this._boundingSphere = ModelUtility.computeBoundingSphere(this);
this._initialRadius = this._boundingSphere.radius;
createResources(this, frameState);
}
Expand Down
Loading

0 comments on commit 0ffd273

Please sign in to comment.