@openhps/core
Version:
Open Hybrid Positioning System - Core component
246 lines • 9.24 kB
JavaScript
"use strict";
var ReferenceSpace_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReferenceSpace = void 0;
const tslib_1 = require("tslib");
const DataObject_1 = require("../DataObject");
const decorators_1 = require("../../decorators");
const math_1 = require("../../../utils/math");
const utils_1 = require("../../../utils");
/**
* A reference space transforms absolute positions to another (global) reference space.
* The following data can be transformed:
* - Position coordinates
* - Linear velocity
* - Angular velocity
* - Orientation
* - Position accuracy
*/
let ReferenceSpace = ReferenceSpace_1 = class ReferenceSpace extends DataObject_1.DataObject {
constructor(parent) {
super();
this.parent = parent;
this._scaleMatrix = new math_1.Matrix4();
this._transformationMatrix = new math_1.Matrix4().identity();
this._translationMatrix = new math_1.Matrix4().identity();
this._rotation = new math_1.Quaternion();
}
/**
* Create a reference space from another object
* @param {DataObject} object Reference space
*/
static fromDataObject(object) {
const space = new ReferenceSpace_1();
space.uid = object.uid;
space.displayName = object.displayName;
if (object.getPosition()) {
space.translation(...object.getPosition().toVector3(utils_1.LengthUnit.METER).toArray());
if (object.getPosition().orientation) {
space.rotation(object.getPosition().orientation);
}
}
return space;
}
/**
* Set the parent space
* @param {TransformationSpace} space Parent space
*/
set parent(space) {
if (!space) {
return;
}
else {
this.parentUID = space.uid;
this._parent = space;
}
}
/**
* Get the parent space if loaded
* @returns {TransformationSpace | undefined} Transformation space or undefined
*/
get parent() {
return this._parent;
}
/**
* Update parent reference spaces
* @param {DataService} service Service to use for updating
* @returns {Promise<void>} Update promise
*/
update(service) {
return new Promise((resolve, reject) => {
if (this.parentUID) {
// Update parent
service
.findByUID(this.parentUID)
.then((parent) => {
this._parent = parent;
if (!parent) {
throw new Error(`Unable to find reference space with uid: ${this.parentUID}!`);
}
return this._parent.update(service);
})
.then(resolve)
.catch(reject);
}
else {
resolve();
}
});
}
orthographic(left, right, bottom, top, near, far) {
this._transformationMatrix.multiply(new math_1.Matrix4().makeOrthographic(left, right, bottom, top, near, far));
return this;
}
/**
* Transform perspective
* @param {number} left Farthest left on the x-axis
* @param {number} right Farthest right on the x-axis
* @param {number} bottom Farthest down on the y-axis
* @param {number} top Farthest up on the y-axis
* @param {number} near Distance to the near clipping plane along the -Z axis
* @param {number} far Distance to the far clipping plane along the -Z axis
* @returns {ReferenceSpace} Reference space instance
*/
perspective(left, right, bottom, top, near, far) {
this._transformationMatrix.multiply(new math_1.Matrix4().makePerspective(left, right, bottom, top, near, far));
return this;
}
reset() {
this._transformationMatrix.identity();
this._scaleMatrix = new math_1.Matrix4();
this._rotation = new math_1.Quaternion();
return this;
}
referenceUnit(unit) {
this._unit = unit;
return this;
}
translation(dX, dY, dZ = 0) {
this._translationMatrix.multiply(new math_1.Matrix4().makeTranslation(dX, dY, dZ));
this._transformationMatrix.multiply(this._translationMatrix);
return this;
}
scale(kX, kY, kZ = 1.0) {
this._scaleMatrix = new math_1.Matrix4().makeScale(kX, kY, kZ);
this._transformationMatrix.multiply(this._scaleMatrix);
return this;
}
rotation(r) {
if (r instanceof math_1.Quaternion) {
this._rotation = r.clone();
this._transformationMatrix.multiply(this._rotation.toRotationMatrix());
}
else if (r instanceof math_1.Euler) {
this._rotation = math_1.Quaternion.fromEuler(r);
this._transformationMatrix.multiply(this._rotation.toRotationMatrix());
}
else if (r instanceof math_1.AxisAngle) {
this._rotation = math_1.Quaternion.fromAxisAngle(r);
this._transformationMatrix.multiply(this._rotation.toRotationMatrix());
}
else {
this._rotation = math_1.Quaternion.fromEuler(r);
this._transformationMatrix.multiply(this._rotation.toRotationMatrix());
}
return this;
}
/**
* Transform a position
* @param {AbsolutePosition} position Position to transform
* @param {SpaceTransformationOptions} [options] Transformation options
* @returns {AbsolutePosition} Transformed position
*/
transform(position, options) {
const config = options || {};
// Clone the position
const newPosition = this._parent ? this._parent.transform(position, options) : position.clone();
// Transform the position to the length unit
if (this._unit) {
newPosition.fromVector(newPosition.toVector3(this._unit));
newPosition.setAccuracy(newPosition.accuracy.to(this._unit));
}
const transformationMatrix = config.inverse
? this.transformationMatrix.clone().invert()
: this.transformationMatrix;
const rotation = config.inverse ? this.rotationQuaternion.clone().invert() : this.rotationQuaternion;
const scale = config.inverse ? this._scaleMatrix.clone().invert() : this.scaleMatrix;
// Transform the point using the transformation matrix
newPosition.fromVector(newPosition.toVector3().applyMatrix4(transformationMatrix));
// Transform the orientation (rotation)
if (newPosition.orientation) {
// Rotate the quaterion
newPosition.orientation.multiply(rotation);
}
if (newPosition.linearVelocity) {
// Transform the linear velocity (rotation and scale)
newPosition.linearVelocity.applyMatrix4(scale).applyMatrix4(math_1.Matrix4.rotationFromQuaternion(rotation));
}
newPosition.setAccuracy(new math_1.Vector3(newPosition.accuracy.valueOf(), 0, 0).applyMatrix4(scale).x, newPosition.accuracy.unit);
newPosition.referenceSpaceUID = this.uid;
return newPosition;
}
get transformationMatrix() {
return this._transformationMatrix;
}
set transformationMatrix(matrix) {
this._transformationMatrix = matrix;
}
/**
* Get the transformation matrix for scaling
* @returns {Matrix4} Transformation matrix
*/
get scaleMatrix() {
return this._scaleMatrix;
}
set scaleMatrix(matrix) {
this._scaleMatrix = matrix;
}
get rotationQuaternion() {
return this._rotation;
}
set rotationQuaternion(quaternion) {
this._rotation = quaternion;
}
get translationMatrix() {
return this._translationMatrix;
}
set translationMatrix(matrix) {
this._translationMatrix = matrix;
}
};
exports.ReferenceSpace = ReferenceSpace;
tslib_1.__decorate([
(0, decorators_1.SerializableMember)({
name: 'translationMatrix',
}),
tslib_1.__metadata("design:type", math_1.Matrix4)
], ReferenceSpace.prototype, "_translationMatrix", void 0);
tslib_1.__decorate([
(0, decorators_1.SerializableMember)({
name: 'transformationMatrix',
}),
tslib_1.__metadata("design:type", math_1.Matrix4)
], ReferenceSpace.prototype, "_transformationMatrix", void 0);
tslib_1.__decorate([
(0, decorators_1.SerializableMember)({
name: 'scaleMatrix',
}),
tslib_1.__metadata("design:type", math_1.Matrix4)
], ReferenceSpace.prototype, "_scaleMatrix", void 0);
tslib_1.__decorate([
(0, decorators_1.SerializableMember)({
name: 'rotation',
}),
tslib_1.__metadata("design:type", math_1.Quaternion)
], ReferenceSpace.prototype, "_rotation", void 0);
tslib_1.__decorate([
(0, decorators_1.SerializableMember)({
name: 'unit',
}),
tslib_1.__metadata("design:type", utils_1.LengthUnit)
], ReferenceSpace.prototype, "_unit", void 0);
exports.ReferenceSpace = ReferenceSpace = ReferenceSpace_1 = tslib_1.__decorate([
(0, decorators_1.SerializableObject)(),
tslib_1.__metadata("design:paramtypes", [Object])
], ReferenceSpace);
//# sourceMappingURL=ReferenceSpace.js.map