playcanvas
Version:
PlayCanvas WebGL game engine
167 lines (164 loc) • 4.48 kB
JavaScript
import { platform } from '../../core/platform.js';
import { Mat4 } from '../../core/math/mat4.js';
import { Quat } from '../../core/math/quat.js';
import { Vec3 } from '../../core/math/vec3.js';
/**
* @import { XrFinger } from './xr-finger.js'
* @import { XrHand } from './xr-hand.js'
*/ var tipJointIds = platform.browser && window.XRHand ? [
'thumb-tip',
'index-finger-tip',
'middle-finger-tip',
'ring-finger-tip',
'pinky-finger-tip'
] : [];
var tipJointIdsIndex = {};
for(var i = 0; i < tipJointIds.length; i++){
tipJointIdsIndex[tipJointIds[i]] = true;
}
/**
* Represents the joint of a finger.
*
* @category XR
*/ class XrJoint {
/**
* @param {XRJointPose} pose - XRJointPose of this joint.
* @ignore
*/ update(pose) {
this._dirtyLocal = true;
this._radius = pose.radius;
this._localPosition.copy(pose.transform.position);
this._localRotation.copy(pose.transform.orientation);
}
/** @private */ _updateTransforms() {
if (this._dirtyLocal) {
this._dirtyLocal = false;
this._localTransform.setTRS(this._localPosition, this._localRotation, Vec3.ONE);
}
var manager = this._hand._manager;
var parent = manager.camera.parent;
if (parent) {
this._worldTransform.mul2(parent.getWorldTransform(), this._localTransform);
} else {
this._worldTransform.copy(this._localTransform);
}
}
/**
* Get the world space position of a joint.
*
* @returns {Vec3} The world space position of a joint.
*/ getPosition() {
this._updateTransforms();
this._worldTransform.getTranslation(this._position);
return this._position;
}
/**
* Get the world space rotation of a joint.
*
* @returns {Quat} The world space rotation of a joint.
*/ getRotation() {
this._updateTransforms();
this._rotation.setFromMat4(this._worldTransform);
return this._rotation;
}
/**
* Id of a joint based on WebXR Hand Input Specs.
*
* @type {XRHandJoint}
*/ get id() {
return this._id;
}
/**
* Index of a joint within a finger, starting from 0 (root of a finger) all the way to tip of
* the finger.
*
* @type {number}
*/ get index() {
return this._index;
}
/**
* Hand that joint relates to.
*
* @type {XrHand}
*/ get hand() {
return this._hand;
}
/**
* Finger that joint relates to.
*
* @type {XrFinger|null}
*/ get finger() {
return this._finger;
}
/**
* True if joint is a wrist.
*
* @type {boolean}
*/ get wrist() {
return this._wrist;
}
/**
* True if joint is a tip of a finger.
*
* @type {boolean}
*/ get tip() {
return this._tip;
}
/**
* The radius of a joint, which is a distance from joint to the edge of a skin.
*
* @type {number}
*/ get radius() {
return this._radius || 0.005;
}
/**
* Create an XrJoint instance.
*
* @param {number} index - Index of a joint within a finger.
* @param {XRHandJoint} id - Id of a joint based on WebXR Hand Input Specs.
* @param {XrHand} hand - Hand that joint relates to.
* @param {XrFinger|null} finger - Finger that joint is related to. Can be null in the case of
* the wrist joint.
* @ignore
*/ constructor(index, id, hand, finger = null){
/**
* @type {number|null}
* @private
*/ this._radius = null;
/**
* @type {Mat4}
* @private
*/ this._localTransform = new Mat4();
/**
* @type {Mat4}
* @private
*/ this._worldTransform = new Mat4();
/**
* @type {Vec3}
* @private
*/ this._localPosition = new Vec3();
/**
* @type {Quat}
* @private
*/ this._localRotation = new Quat();
/**
* @type {Vec3}
* @private
*/ this._position = new Vec3();
/**
* @type {Quat}
* @private
*/ this._rotation = new Quat();
/**
* @type {boolean}
* @private
*/ this._dirtyLocal = true;
this._index = index;
this._id = id;
this._hand = hand;
this._finger = finger;
this._wrist = id === 'wrist';
this._tip = this._finger && !!tipJointIdsIndex[id];
}
}
export { XrJoint };