UNPKG

@vrame/xeokit-sdk

Version:

3D BIM IFC Viewer SDK for AEC engineering applications. Open Source JavaScript Toolkit based on pure WebGL for top performance, real-world coordinates and full double precision

259 lines (242 loc) 7.98 kB
//---------------------------------------------------------------------------------------------------------------------- // This file is named "Metriqs.js" because "Metrics.js" is blocked by uBlock Origin (https://en.wikipedia.org/wiki/UBlock_Origin) //---------------------------------------------------------------------------------------------------------------------- import {Component} from "../Component.js"; import {math} from "../math/math.js"; const unitsInfo = { meters: { abbrev: "m" }, metres: { abbrev: "m" }, centimeters: { abbrev: "cm" }, centimetres: { abbrev: "cm" }, millimeters: { abbrev: "mm" }, millimetres: { abbrev: "mm" }, yards: { abbrev: "yd" }, feet: { abbrev: "ft" }, inches: { abbrev: "in" } }; /** * @desc Configures its {@link Scene}'s measurement unit and mapping between the Real-space and World-space 3D Cartesian coordinate systems. * * * ## Overview * * * Located at {@link Scene#metrics}. * * {@link Metrics#units} configures the Real-space unit type, which is ````"meters"```` by default. * * {@link Metrics#scale} configures the number of Real-space units represented by each unit within the World-space 3D coordinate system. This is ````1.0```` by default. * * {@link Metrics#origin} configures the 3D Real-space origin, in current Real-space units, at which this {@link Scene}'s World-space coordinate origin sits, This is ````[0,0,0]```` by default. * * ## Usage * * Let's load a model using an {@link XKTLoaderPlugin}, then configure the Real-space unit type and the coordinate * mapping between the Real-space and World-space 3D coordinate systems. * * ````JavaScript * import {Viewer, XKTLoaderPlugin} from "xeokit-sdk.es.js"; * * const viewer = new Viewer({ * canvasId: "myCanvas" * }); * * viewer.scene.camera.eye = [-2.37, 18.97, -26.12]; * viewer.scene.camera.look = [10.97, 5.82, -11.22]; * viewer.scene.camera.up = [0.36, 0.83, 0.40]; * * const xktLoader = new XKTLoaderPlugin(viewer); * * const model = xktLoader.load({ * src: "./models/xkt/duplex/duplex.xkt" * }); * * const metrics = viewer.scene.metrics; * * metrics.units = "meters"; * metrics.scale = 10.0; * metrics.origin = [100.0, 0.0, 200.0]; * ```` */ class Metrics extends Component { /** * @constructor * @private */ constructor(owner, cfg = {}) { super(owner, cfg); this._units = "meters"; this._scale = 1.0; this._origin = math.vec3([0, 0, 0]); this.units = cfg.units; this.scale = cfg.scale; this.origin = cfg.origin; } /** * Gets info about the supported Real-space unit types. * * This will be: * * ````javascript * { * { * meters: { * abbrev: "m" * }, * metres: { * abbrev: "m" * }, * centimeters: { * abbrev: "cm" * }, * centimetres: { * abbrev: "cm" * }, * millimeters: { * abbrev: "mm" * }, * millimetres: { * abbrev: "mm" * }, * yards: { * abbrev: "yd" * }, * feet: { * abbrev: "ft" * }, * inches: { * abbrev: "in" * } * } * } * ```` * * @type {*} */ get unitsInfo() { return unitsInfo; } /** * Sets the {@link Scene}'s Real-space unit type. * * Accepted values are ````"meters"````, ````"centimeters"````, ````"millimeters"````, ````"metres"````, ````"centimetres"````, ````"millimetres"````, ````"yards"````, ````"feet"```` and ````"inches"````. * * @emits ````"units"```` event on change, with the value of this property. * @type {String} */ set units(value) { if (!value) { value = "meters"; } const info = unitsInfo[value]; if (!info) { this.error("Unsupported value for 'units': " + value + " defaulting to 'meters'"); value = "meters"; } this._units = value; this.fire("units", this._units); } /** * Gets the {@link Scene}'s Real-space unit type. * * @type {String} */ get units() { return this._units; } /** * Sets the number of Real-space units represented by each unit of the {@link Scene}'s World-space coordinate system. * * For example, if {@link Metrics#units} is ````"meters"````, and there are ten meters per World-space coordinate system unit, then ````scale```` would have a value of ````10.0````. * * @emits ````"scale"```` event on change, with the value of this property. * @type {Number} */ set scale(value) { value = value || 1; if (value <= 0) { this.error("scale value should be larger than zero"); return; } this._scale = value; this.fire("scale", this._scale); } /** * Gets the number of Real-space units represented by each unit of the {@link Scene}'s World-space coordinate system. * * @type {Number} */ get scale() { return this._scale; } /** * Sets the Real-space 3D origin, in Real-space units, at which this {@link Scene}'s World-space coordinate origin ````[0,0,0]```` sits. * * @emits "origin" event on change, with the value of this property. * @type {Number[]} */ set origin(value) { if (!value) { this._origin[0] = 0; this._origin[1] = 0; this._origin[2] = 0; return; } this._origin[0] = value[0]; this._origin[1] = value[1]; this._origin[2] = value[2]; this.fire("origin", this._origin); } /** * Gets the 3D Real-space origin, in Real-space units, at which this {@link Scene}'s World-space coordinate origin ````[0,0,0]```` sits. * * @type {Number[]} */ get origin() { return this._origin; } /** * Converts a 3D position from World-space to Real-space. * * This is equivalent to ````realPos = #origin + (worldPos * #scale)````. * * @param {Number[]} worldPos World-space 3D position, in World coordinate system units. * @param {Number[]} [realPos] Destination for Real-space 3D position. * @returns {Number[]} Real-space 3D position, in units indicated by {@link Metrics#units}. */ worldToRealPos(worldPos, realPos = math.vec3(3)) { realPos[0] = this._origin[0] + (this._scale * worldPos[0]); realPos[1] = this._origin[1] + (this._scale * worldPos[1]); realPos[2] = this._origin[2] + (this._scale * worldPos[2]); } /** * Converts a 3D position from Real-space to World-space. * * This is equivalent to ````worldPos = (worldPos - #origin) / #scale````. * * @param {Number[]} realPos Real-space 3D position. * @param {Number[]} [worldPos] Destination for World-space 3D position. * @returns {Number[]} World-space 3D position. */ realToWorldPos(realPos, worldPos = math.vec3(3)) { worldPos[0] = (realPos[0] - this._origin[0]) / this._scale; worldPos[1] = (realPos[1] - this._origin[1]) / this._scale; worldPos[2] = (realPos[2] - this._origin[2]) / this._scale; return worldPos; } } export {Metrics};