222 lines
4.9 KiB
JavaScript
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;
|
|
};
|