@openhps/core
Version:
Open Hybrid Positioning System - Core component
187 lines (172 loc) • 6.22 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.velocity = exports.default = void 0;
var _TempNode = _interopRequireDefault(require("../core/TempNode.js"));
var _ModelNode = require("./ModelNode.js");
var _Position = require("./Position.js");
var _TSLBase = require("../tsl/TSLBase.js");
var _constants = require("../core/constants.js");
var _Matrix = require("../../math/Matrix4.js");
var _UniformNode = require("../core/UniformNode.js");
var _OperatorNode = require("../math/OperatorNode.js");
var _Camera = require("./Camera.js");
var _UniformGroupNode = require("../core/UniformGroupNode.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const _objectData = new WeakMap();
/**
* A node for representing motion or velocity vectors. Foundation
* for advanced post processing effects like motion blur or TRAA.
*
* The node keeps track of the model, view and projection matrices
* of the previous frame and uses them to compute offsets in NDC space.
* These offsets represent the final velocity.
*
* @augments TempNode
*/
class VelocityNode extends _TempNode.default {
static get type() {
return 'VelocityNode';
}
/**
* Constructs a new vertex color node.
*/
constructor() {
super('vec2');
/**
* The current projection matrix.
*
* @type {?Matrix4}
* @default null
*/
this.projectionMatrix = null;
/**
* Overwritten since velocity nodes are updated per object.
*
* @type {string}
* @default 'object'
*/
this.updateType = _constants.NodeUpdateType.OBJECT;
/**
* Overwritten since velocity nodes save data after the update.
*
* @type {string}
* @default 'object'
*/
this.updateAfterType = _constants.NodeUpdateType.OBJECT;
/**
* Uniform node representing the previous model matrix in world space.
*
* @type {UniformNode<mat4>}
* @default null
*/
this.previousModelWorldMatrix = (0, _UniformNode.uniform)(new _Matrix.Matrix4());
/**
* Uniform node representing the previous projection matrix.
*
* @type {UniformNode<mat4>}
* @default null
*/
this.previousProjectionMatrix = (0, _UniformNode.uniform)(new _Matrix.Matrix4()).setGroup(_UniformGroupNode.renderGroup);
/**
* Uniform node representing the previous view matrix.
*
* @type {UniformNode<mat4>}
* @default null
*/
this.previousCameraViewMatrix = (0, _UniformNode.uniform)(new _Matrix.Matrix4());
}
/**
* Sets the given projection matrix.
*
* @param {Matrix4} projectionMatrix - The projection matrix to set.
*/
setProjectionMatrix(projectionMatrix) {
this.projectionMatrix = projectionMatrix;
}
/**
* Updates velocity specific uniforms.
*
* @param {NodeFrame} frame - A reference to the current node frame.
*/
update({
frameId,
camera,
object
}) {
const previousModelMatrix = getPreviousMatrix(object);
this.previousModelWorldMatrix.value.copy(previousModelMatrix);
//
const cameraData = getData(camera);
if (cameraData.frameId !== frameId) {
cameraData.frameId = frameId;
if (cameraData.previousProjectionMatrix === undefined) {
cameraData.previousProjectionMatrix = new _Matrix.Matrix4();
cameraData.previousCameraViewMatrix = new _Matrix.Matrix4();
cameraData.currentProjectionMatrix = new _Matrix.Matrix4();
cameraData.currentCameraViewMatrix = new _Matrix.Matrix4();
cameraData.previousProjectionMatrix.copy(this.projectionMatrix || camera.projectionMatrix);
cameraData.previousCameraViewMatrix.copy(camera.matrixWorldInverse);
} else {
cameraData.previousProjectionMatrix.copy(cameraData.currentProjectionMatrix);
cameraData.previousCameraViewMatrix.copy(cameraData.currentCameraViewMatrix);
}
cameraData.currentProjectionMatrix.copy(this.projectionMatrix || camera.projectionMatrix);
cameraData.currentCameraViewMatrix.copy(camera.matrixWorldInverse);
this.previousProjectionMatrix.value.copy(cameraData.previousProjectionMatrix);
this.previousCameraViewMatrix.value.copy(cameraData.previousCameraViewMatrix);
}
}
/**
* Overwritten to updated velocity specific uniforms.
*
* @param {NodeFrame} frame - A reference to the current node frame.
*/
updateAfter({
object
}) {
getPreviousMatrix(object).copy(object.matrixWorld);
}
/**
* Implements the velocity computation based on the previous and current vertex data.
*
* @param {NodeBuilder} builder - A reference to the current node builder.
* @return {Node<vec2>} The motion vector.
*/
setup( /*builder*/
) {
const projectionMatrix = this.projectionMatrix === null ? _Camera.cameraProjectionMatrix : (0, _UniformNode.uniform)(this.projectionMatrix);
const previousModelViewMatrix = this.previousCameraViewMatrix.mul(this.previousModelWorldMatrix);
const clipPositionCurrent = projectionMatrix.mul(_ModelNode.modelViewMatrix).mul(_Position.positionLocal);
const clipPositionPrevious = this.previousProjectionMatrix.mul(previousModelViewMatrix).mul(_Position.positionPrevious);
const ndcPositionCurrent = clipPositionCurrent.xy.div(clipPositionCurrent.w);
const ndcPositionPrevious = clipPositionPrevious.xy.div(clipPositionPrevious.w);
const velocity = (0, _OperatorNode.sub)(ndcPositionCurrent, ndcPositionPrevious);
return velocity;
}
}
function getData(object) {
let objectData = _objectData.get(object);
if (objectData === undefined) {
objectData = {};
_objectData.set(object, objectData);
}
return objectData;
}
function getPreviousMatrix(object, index = 0) {
const objectData = getData(object);
let matrix = objectData[index];
if (matrix === undefined) {
objectData[index] = matrix = new _Matrix.Matrix4();
}
return matrix;
}
var _default = exports.default = VelocityNode;
/**
* TSL object that represents the velocity of a render pass.
*
* @tsl
* @type {VelocityNode}
*/
const velocity = exports.velocity = /*@__PURE__*/(0, _TSLBase.nodeImmutable)(VelocityNode);