UNPKG

@itwin/core-frontend

Version:
207 lines • 9.91 kB
"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 Rendering */ Object.defineProperty(exports, "__esModule", { value: true }); exports.RealityMeshParamsBuilder = exports.RealityMeshParams = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const core_geometry_1 = require("@itwin/core-geometry"); const core_common_1 = require("@itwin/core-common"); const MeshPrimitive_1 = require("../common/internal/render/MeshPrimitive"); function precondition(condition, message) { if (condition) return; if ("string" !== typeof message) message = message(); throw new Error(`Logic Error: ${message}`); } /** @public */ var RealityMeshParams; (function (RealityMeshParams) { /** @internal */ function fromGltfMesh(mesh) { // The specialized reality mesh shaders expect a mesh with uvs and no edges. if (mesh.primitive.type !== MeshPrimitive_1.MeshPrimitiveType.Mesh || mesh.primitive.edges || !mesh.pointQParams || !mesh.uvQParams || !mesh.points || !mesh.uvs || !mesh.indices) return undefined; return { indices: mesh.indices, positions: { params: mesh.pointQParams, points: mesh.points, }, uvs: { params: mesh.uvQParams, points: mesh.uvs, }, normals: mesh.normals, // featureID: 0, texture: mesh.primitive.displayParams.textureMapping?.texture, }; } RealityMeshParams.fromGltfMesh = fromGltfMesh; /** @alpha */ function toPolyface(params, options) { const { positions, normals, uvs, indices } = params; const includeNormals = options?.wantNormals && undefined !== normals; const includeParams = options?.wantParams; const polyface = core_geometry_1.IndexedPolyface.create(includeNormals, includeParams); const points = positions.points; const point = new core_geometry_1.Point3d(); const transform = options?.transform; for (let i = 0; i < positions.points.length; i += 3) { positions.params.unquantize(points[i], points[i + 1], points[i + 2], point); transform?.multiplyPoint3d(point, point); polyface.addPoint(point); } if (includeNormals) { const normal = new core_geometry_1.Vector3d(); for (const oen of normals) polyface.addNormal(core_common_1.OctEncodedNormal.decodeValue(oen, normal)); } if (includeParams) { const uv = new core_geometry_1.Point2d(); for (let i = 0; i < uvs.points.length; i += 2) polyface.addParam(uvs.params.unquantize(uvs.points[i], uvs.points[i + 1], uv)); } let j = 0; indices.forEach((index) => { polyface.addPointIndex(index); if (includeNormals) polyface.addNormalIndex(index); if (includeParams) polyface.addParamIndex(index); if (0 === (++j % 3)) polyface.terminateFacet(); }); return polyface; } RealityMeshParams.toPolyface = toPolyface; })(RealityMeshParams || (exports.RealityMeshParams = RealityMeshParams = {})); /** Incrementally constructs a [[RealityMeshParams]]. * The following simple example produces a rectangular mesh containing two triangles. * ```ts * [[include:Build_Reality_Mesh_Params]] * ``` * @beta */ class RealityMeshParamsBuilder { /** The indices of the vertices in each triangle of the mesh. * @see [[addTriangle]] to add 3 indices describing a single triangle. * @see [[addQuad]] to add 4 indices describing two triangles sharing an edge. * @see [[addIndices]] to add any number of indices. */ indices; /** The 3d position of each vertex in the mesh. * @see [[addQuantizedVertex]] and [[addUnquantizedVertex]] to add a vertex. */ positions; /** The 2d texture coordinates of each vertex in the mesh. * @see [[addQuantizedVertex]] and [[addUnquantizedVertex]] to add a vertex. */ uvs; /** The normal vector of each vertex in the mesh, or `undefined` if [[RealityMeshParamsBuilderOptions.wantNormals]] was not `true` when constructing the builder. * A normal vector must be supplied to [[addQuantizedVertex]] and [[addUnquantizedVertex]] if and only if [[RealityMeshParamsBuilderOptions.wantNormals]] was * specified as `true`. * The vectors are stored as [OctEncodedNormal]($common)s. */ normals; // Scratch variables _q3d = new core_common_1.QPoint3d(); _q2d = new core_common_1.QPoint2d(); /** Construct a builder from the specified options. */ constructor(options) { let initialType; if (undefined !== options.initialVertexCapacity && options.initialVertexCapacity > 0xff) initialType = options.initialVertexCapacity > 0xffff ? Uint32Array : Uint16Array; this.indices = new core_bentley_1.UintArrayBuilder({ initialCapacity: options.initialIndexCapacity, initialType, }); if (options.wantNormals) this.normals = new core_bentley_1.Uint16ArrayBuilder({ initialCapacity: options.initialVertexCapacity }); this.positions = new core_common_1.QPoint3dBufferBuilder({ range: options.positionRange, initialCapacity: options.initialVertexCapacity, }); this.uvs = new core_common_1.QPoint2dBufferBuilder({ range: options.uvRange ?? new core_geometry_1.Range2d(0, 0, 1, 1), initialCapacity: options.initialVertexCapacity, }); } /** Add a vertex to the mesh and return its index in [[positions]]. * @param position The 3d position, which will be quantized to the [[RealityMeshParamsBuilderOptions.positionRange]] supplied to the builder's constructor. * @param uv The texture coordinates, which will be quantized to the [[RealityMeshParamsBuilderOptions.uvRange]] supplied to the builder's constructor. * @param the normal vector, to be supplied if and only if [[RealityMeshParamsBuilderOptions.wantNormals]] was `true` when the builder was constructed. * @see [[addQuantizedVertex]] if your vertex data is already quantized. * @returns the index of the new vertex in [[positions]]. */ addUnquantizedVertex(position, uv, normal) { this._q3d.init(position, this.positions.params); this._q2d.init(uv, this.uvs.params); const oen = normal ? core_common_1.OctEncodedNormal.encode(normal) : undefined; return this.addQuantizedVertex(this._q3d, this._q2d, oen); } /** Original API had weird mix of quantized and unquantized, used by CesiumTerrainProvider. * @internal */ addVertex(position, uv, normal) { this._q3d.init(position, this.positions.params); this.addQuantizedVertex(this._q3d, uv, normal); } /** Add a vertex to the mesh and return its index in [[positions]]. * @param position The 3d position, quantized to the [[RealityMeshParamsBuilderOptions.positionRange]] supplied to the builder's constructor. * @param uv The texture coordinates, quantized to the [[RealityMeshParamsBuilderOptions.uvRange]] supplied to the builder's constructor. * @param normal The unsigned 16-bit [OctEncodedNormal]($common) integer representation of the normal vector, to be supplied if and only if * [[RealityMeshParamsBuilderOptions.wantNormals]] was `true` when the builder was constructed. * @see [[addUnquantizedVertex]] if your vertex data is not already quantized. * @returns the index of the new vertex in [[positions]]. * @throws Error if `normal` is `undefined` but `wantNormals` was specified at construction of the builder, or vice-versa. */ addQuantizedVertex(position, uv, normal) { precondition((undefined === normal) === (undefined === this.normals), "RealityMeshParams requires all vertices to have normals, or none."); this.positions.push(position); this.uvs.push(uv); if (undefined !== normal) { (0, core_bentley_1.assert)(undefined !== this.normals); this.normals.push(normal); } return this.positions.length - 1; } /** Add a triangle corresponding to the three specified vertices. */ addTriangle(i0, i1, i2) { this.addIndex(i0); this.addIndex(i1); this.addIndex(i2); } /** Add two triangles sharing an edge. This is equivalent to calling `addTriangle(i0, i1, i2); addTriangle(i1, i3, i2);`. */ addQuad(i0, i1, i2, i3) { this.addTriangle(i0, i1, i2); this.addTriangle(i1, i3, i2); } /** Add all of the indices in `indices` to the index buffer. */ addIndices(indices) { for (const index of indices) this.addIndex(index); } addIndex(index) { this.indices.push(index); } /** Extract the finished [[RealityMeshParams]]. * @throws Error if the mesh contains no triangles. */ finish() { precondition(this.positions.length >= 3 && this.indices.length >= 3, "RealityMeshParams requires at least one triangle"); return { positions: this.positions.finish(), uvs: this.uvs.finish(), normals: this.normals?.toTypedArray(), indices: this.indices.toTypedArray(), }; } } exports.RealityMeshParamsBuilder = RealityMeshParamsBuilder; //# sourceMappingURL=RealityMeshParams.js.map