Home Reference Source

src/math/QEFData.js

import { Vector3 } from "three";
import { SymmetricMatrix3 } from "./SymmetricMatrix3";

/**
 * A data container for the QEF solver.
 */

export class QEFData {

	/**
	 * Constructs a new QEF data container.
	 */

	constructor() {

		/**
		 * A symmetric matrix.
		 *
		 * @type {SymmetricMatrix3}
		 * @private
		 */

		this.ata = new SymmetricMatrix3();

		this.ata.set(

			0, 0, 0,
			0, 0,
			0

		);

		/**
		 * A vector.
		 *
		 * @type {Vector3}
		 * @private
		 */

		this.atb = new Vector3();

		/**
		 * An accumulation of the surface intersection points.
		 *
		 * @type {Vector3}
		 * @private
		 */

		this.massPointSum = new Vector3();

		/**
		 * The amount of accumulated surface intersection points.
		 *
		 * @type {Number}
		 */

		this.numPoints = 0;

	}

	/**
	 * Sets the values of this data instance.
	 *
	 * @param {SymmetricMatrix3} ata - ATA.
	 * @param {Vector3} atb - ATb.
	 * @param {Vector3} massPointSum - The accumulated mass points.
	 * @param {Vector3} numPoints - The number of mass points.
	 * @return {QEFData} This data.
	 */

	set(ata, atb, massPointSum, numPoints) {

		this.ata.copy(ata);
		this.atb.copy(atb);

		this.massPointSum.copy(massPointSum);
		this.numPoints = numPoints;

		return this;

	}

	/**
	 * Copies values from a given data instance.
	 *
	 * @param {QEFData} d - The data to copy.
	 * @return {QEFData} This data.
	 */

	copy(d) {

		return this.set(d.ata, d.atb, d.massPointSum, d.numPoints);

	}

	/**
	 * Adds the given surface intersection point and normal.
	 *
	 * @param {Vector3} p - An intersection point.
	 * @param {Vector3} n - A surface intersection normal.
	 */

	add(p, n) {

		const nx = n.x;
		const ny = n.y;
		const nz = n.z;

		const b = p.dot(n);

		const ata = this.ata.elements;
		const atb = this.atb;

		ata[0] += nx * nx;
		ata[1] += nx * ny; ata[3] += ny * ny;
		ata[2] += nx * nz; ata[4] += ny * nz; ata[5] += nz * nz;

		atb.x += b * nx;
		atb.y += b * ny;
		atb.z += b * nz;

		this.massPointSum.add(p);

		++this.numPoints;

	}

	/**
	 * Adds an entire data set.
	 *
	 * @param {QEFData} d - QEF data.
	 */

	addData(d) {

		this.ata.add(d.ata);
		this.atb.add(d.atb);

		this.massPointSum.add(d.massPointSum);
		this.numPoints += d.numPoints;

	}

	/**
	 * Clears this data.
	 */

	clear() {

		this.ata.set(

			0, 0, 0,
			0, 0,
			0

		);

		this.atb.set(0, 0, 0);
		this.massPointSum.set(0, 0, 0);
		this.numPoints = 0;

	}

	/**
	 * Clones this data.
	 *
	 * @return {QEFData} The cloned data.
	 */

	clone() {

		return new this.constructor().copy(this);

	}

}