r3-legacy/src/r3-api-quaternion-0.js

222 lines
4.9 KiB
JavaScript

/**
* R3.API.Quaternion
* @param apiComponent
* @constructor
*/
R3.API.Quaternion = function(
apiComponent
) {
__DEREGISTER_COMPONENT__;
__API_COMPONENT__;
if (R3.Utils.UndefinedOrNull(apiComponent.x)) {
apiComponent.x = 0;
}
this.x = apiComponent.x;
if (R3.Utils.UndefinedOrNull(apiComponent.y)) {
apiComponent.y = 0;
}
this.y = apiComponent.y;
if (R3.Utils.UndefinedOrNull(apiComponent.z)) {
apiComponent.z = 0;
}
this.z = apiComponent.z;
if (R3.Utils.UndefinedOrNull(apiComponent.w)) {
apiComponent.w = 1;
}
this.w = apiComponent.w;
if (R3.Utils.UndefinedOrNull(apiComponent.axis)) {
var name = 'Quaternion Axis';
if (this.parent && this.parent.name) {
name = this.parent.name + ' - Quaternion Axis';
}
apiComponent.axis = new R3.API.Vector3(
{
parent : this.parent,
name : name,
register : this.register
}
);
}
this.axis = apiComponent.axis;
if (R3.Utils.UndefinedOrNull(apiComponent.angle)) {
apiComponent.angle = 0;
}
this.angle = apiComponent.angle;
};
R3.API.Quaternion.prototype = Object.create(R3.API.Component.prototype);
R3.API.Quaternion.prototype.constructor = R3.API.Quaternion;
R3.API.Quaternion.prototype.translate = function(v) {
this.x += v.x;
this.y += v.y;
this.z += v.z;
return this;
};
R3.API.Quaternion.prototype.copy = function() {
return new R3.API.Quaternion(
this
);
};
/**
* Note, this normalize function leaves 'w' component untouched
*/
R3.API.Quaternion.prototype.normalize = function() {
var EPSILON = 0.000001;
var v2 = this.x * this.x + this.y * this.y + this.z * this.z;
if (v2 < EPSILON) {
return this; //do nothing for zero vector
}
var invLength = 1 / Math.sqrt(v2);
this.x *= invLength;
this.y *= invLength;
this.z *= invLength;
};
R3.API.Quaternion.prototype.multiply = function(q) {
var x, y, z, w;
var a = q;
var b = this;
if (q instanceof R3.API.Matrix4) {
x = a.rows[0].x * b.x + a.rows[0].y * b.y + a.rows[0].z * b.z + a.rows[0].w * b.w;
y = a.rows[1].x * b.x + a.rows[1].y * b.y + a.rows[1].z * b.z + a.rows[1].w * b.w;
z = a.rows[2].x * b.x + a.rows[2].y * b.y + a.rows[2].z * b.z + a.rows[2].w * b.w;
w = a.rows[3].x * b.x + a.rows[3].y * b.y + a.rows[3].z * b.z + a.rows[3].w * b.w;
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
} else if (q instanceof R3.API.Quaternion) {
x = ((a.x * b.x) - (a.y * b.y) - (a.z * b.z) - (a.w * a.w));
y = ((a.x * b.y) + (a.y * b.x) - (a.z * b.w) + (a.w * a.z));
z = ((a.x * b.z) + (a.y * b.w) + (a.z * b.x) - (a.w * a.y));
w = ((a.x * b.w) - (a.y * b.z) + (a.z * b.y) + (a.w * a.x));
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
} else {
console.log("This functionality not implemented - please do this");
throw new Error("This functionality not implemented - please do this");
}
};
R3.API.Quaternion.prototype.setFromAngle = function(angle) {
this.instance.setFromAxisAngle(this.axis.instance, angle);
this.x = this.instance.x;
this.y = this.instance.y;
this.z = this.instance.z;
this.w = this.instance.w;
return this;
};
R3.API.Quaternion.prototype.subtract = function(v) {
if (v instanceof R3.API.Vector3) {
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
}
if (v instanceof R3.API.Quaternion) {
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
this.w -= v.w;
}
return this;
};
R3.API.Quaternion.prototype.magnitude = function() {
return Math.sqrt(
(this.x * this.x) +
(this.y * this.y) +
(this.z * this.z) +
(this.w * this.w)
);
};
R3.API.Quaternion.prototype.normalize = function() {
var magnitude = this.magnitude();
if (magnitude < 0.000001) {
return this; //do nothing for zero vector
}
this.x *= magnitude;
this.y *= magnitude;
this.z *= magnitude;
this.w *= magnitude;
return this;
};
/**
*
* @param matrix4 R3.Matrix4
*/
R3.API.Quaternion.prototype.setFromRotationMatrix = function(matrix4) {
this.instance.setFromRotationMatrix(matrix4.instance);
this.x = this.instance.x;
this.y = this.instance.y;
this.z = this.instance.z;
this.w = this.instance.w;
};
/**
*
* @param quaternion R3.Quaternion
* @param t
* @returns {R3.Quaternion}
*/
R3.API.Quaternion.prototype.slerp = function(quaternion, t) {
this.updateInstance();
this.instance.slerp(quaternion.instance, t);
this.x = this.instance.x;
this.y = this.instance.y;
this.z = this.instance.z;
this.w = this.instance.w;
return this;
};