UNPKG

@itwin/core-common

Version:

iTwin.js components common to frontend and backend

151 lines 6.34 kB
/*--------------------------------------------------------------------------------------------- * 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 */ import { assert } from "@itwin/core-bentley"; import { TileFormat, TileHeader } from "./TileIO"; /** Known version of the [glTF format](https://www.khronos.org/gltf/). * @internal */ export 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 || (GltfVersions = {})); /** @internal */ export var GltfV2ChunkTypes; (function (GltfV2ChunkTypes) { GltfV2ChunkTypes[GltfV2ChunkTypes["JSON"] = 1313821514] = "JSON"; GltfV2ChunkTypes[GltfV2ChunkTypes["Binary"] = 5130562] = "Binary"; })(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 */ export class GlbHeader extends TileHeader { gltfLength = 0; jsonChunk = { offset: 0, length: 0 }; binaryChunk; additionalChunks = []; get isValid() { return 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; } assert(undefined === chunk); assert(stream.isAtTheEnd); break; default: this.invalidate(); break; } } } /** @internal */ export class GltfHeader extends TileHeader { gltfLength; scenePosition = 0; sceneStrLength = 0; binaryPosition = 0; get isValid() { return TileFormat.Gltf === this.format; } constructor(stream) { super(stream); this.gltfLength = stream.readUint32(); this.sceneStrLength = stream.readUint32(); const value5 = 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 && value5 === GltfVersions.Gltf1SceneFormat) this.version = GltfVersions.Version1; if (this.version === GltfVersions.Version1) { const gltfSceneFormat = value5; if (GltfVersions.Gltf1SceneFormat !== gltfSceneFormat) { this.invalidate(); return; } this.scenePosition = stream.curPos; this.binaryPosition = stream.curPos + this.sceneStrLength; } else if (this.version === GltfVersions.Version2) { const sceneChunkType = value5; this.scenePosition = stream.curPos; stream.curPos = stream.curPos + this.sceneStrLength; const binaryLength = stream.readUint32(); const binaryChunkType = stream.readUint32(); if (GltfV2ChunkTypes.JSON !== sceneChunkType || GltfV2ChunkTypes.Binary !== binaryChunkType || 0 === binaryLength) { this.invalidate(); return; } this.binaryPosition = stream.curPos; } else { this.invalidate(); } } } //# sourceMappingURL=GltfTileIO.js.map