@itwin/core-frontend
Version:
iTwin.js frontend components
207 lines • 9.91 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 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