@itwin/core-common
Version:
iTwin.js components common to frontend and backend
113 lines • 4.88 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Tile
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.GlbHeader = exports.GltfV2ChunkTypes = exports.GltfVersions = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const TileIO_1 = require("./TileIO");
/** Known version of the [glTF format](https://www.khronos.org/gltf/).
* @internal
*/
var GltfVersions;
(function (GltfVersions) {
GltfVersions[GltfVersions["Version1"] = 1] = "Version1";
GltfVersions[GltfVersions["Version2"] = 2] = "Version2";
GltfVersions[GltfVersions["CurrentVersion"] = 1] = "CurrentVersion";
GltfVersions[GltfVersions["Gltf1SceneFormat"] = 0] = "Gltf1SceneFormat";
})(GltfVersions || (exports.GltfVersions = GltfVersions = {}));
/** @internal */
var GltfV2ChunkTypes;
(function (GltfV2ChunkTypes) {
GltfV2ChunkTypes[GltfV2ChunkTypes["JSON"] = 1313821514] = "JSON";
GltfV2ChunkTypes[GltfV2ChunkTypes["Binary"] = 5130562] = "Binary";
})(GltfV2ChunkTypes || (exports.GltfV2ChunkTypes = GltfV2ChunkTypes = {}));
function consumeNextChunk(stream) {
if (stream.isAtTheEnd)
return undefined;
const offset = stream.curPos + 8;
const length = stream.readUint32();
if (stream.isAtTheEnd)
return undefined;
const type = stream.readUint32();
stream.advance(length);
return stream.isPastTheEnd ? false : { offset, length, type };
}
/** @internal */
class GlbHeader extends TileIO_1.TileHeader {
gltfLength = 0;
jsonChunk = { offset: 0, length: 0 };
binaryChunk;
additionalChunks = [];
get isValid() {
return TileIO_1.TileFormat.Gltf === this.format;
}
constructor(stream) {
super(stream);
this.gltfLength = stream.readUint32();
const jsonLength = stream.readUint32();
const word5 = stream.readUint32();
// Early versions of the reality data tile publisher incorrectly put version 2 into header - handle these old tiles
// validating the chunk type.
if (this.version === GltfVersions.Version2 && word5 === GltfVersions.Gltf1SceneFormat)
this.version = GltfVersions.Version1;
this.jsonChunk = { offset: stream.curPos, length: jsonLength };
switch (this.version) {
case GltfVersions.Version1:
if (GltfVersions.Gltf1SceneFormat !== word5) {
this.invalidate();
return;
}
const binaryOffset = stream.curPos + jsonLength;
this.binaryChunk = { offset: binaryOffset, length: this.gltfLength - binaryOffset };
break;
case GltfVersions.Version2:
if (word5 !== GltfV2ChunkTypes.JSON) {
this.invalidate();
return;
}
stream.advance(jsonLength);
if (stream.isPastTheEnd) {
this.invalidate();
return;
}
let chunk;
while (chunk = consumeNextChunk(stream)) {
switch (chunk.type) {
case GltfV2ChunkTypes.JSON:
// Only one JSON chunk permitted and it must be the first.
this.invalidate();
return;
case GltfV2ChunkTypes.Binary:
// At most one binary chunk permitted and it must be the second if present.
if (this.binaryChunk || this.additionalChunks.length) {
this.invalidate();
return;
}
this.binaryChunk = { offset: chunk.offset, length: chunk.length };
break;
default:
// Any other chunk type should be ignored - for use by extensions.
this.additionalChunks.push(chunk);
break;
}
}
if (false === chunk) {
this.invalidate();
return;
}
(0, core_bentley_1.assert)(undefined === chunk);
(0, core_bentley_1.assert)(stream.isAtTheEnd);
break;
default:
this.invalidate();
break;
}
}
}
exports.GlbHeader = GlbHeader;
//# sourceMappingURL=GltfTileIO.js.map