2017-01-17 13:24:45 +01:00
|
|
|
/**
|
|
|
|
* Quaternion
|
|
|
|
* @param x
|
|
|
|
* @param y
|
|
|
|
* @param z
|
|
|
|
* @param w
|
|
|
|
* @param axis
|
|
|
|
* @param angle
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.API.Quaternion = function (
|
|
|
|
x,
|
|
|
|
y,
|
|
|
|
z,
|
|
|
|
w,
|
|
|
|
axis,
|
|
|
|
angle
|
|
|
|
) {
|
2016-12-08 19:43:16 +01:00
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(x)) {
|
2016-12-08 19:43:16 +01:00
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
this.x = x;
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(y)) {
|
2016-12-08 19:43:16 +01:00
|
|
|
y = 0;
|
|
|
|
}
|
|
|
|
this.y = y;
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(z)) {
|
2016-12-08 19:43:16 +01:00
|
|
|
z = 0;
|
|
|
|
}
|
|
|
|
this.z = z;
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(w)) {
|
2016-12-08 19:43:16 +01:00
|
|
|
w = 1;
|
|
|
|
}
|
|
|
|
this.w = w;
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(axis)) {
|
|
|
|
axis = new GameLib.API.Vector3();
|
2016-12-09 20:32:09 +01:00
|
|
|
}
|
|
|
|
this.axis = axis;
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (GameLib.Utils.UndefinedOrNull(angle)) {
|
2016-12-09 20:32:09 +01:00
|
|
|
angle = 0;
|
|
|
|
}
|
|
|
|
this.angle = angle;
|
2016-12-08 19:43:16 +01:00
|
|
|
};
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.translate = function (v) {
|
2016-12-08 19:43:16 +01:00
|
|
|
this.x += v.x;
|
|
|
|
this.y += v.y;
|
|
|
|
this.z += v.z;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.copy = function () {
|
|
|
|
return new GameLib.API.Quaternion(
|
2016-12-08 19:43:16 +01:00
|
|
|
this.x,
|
|
|
|
this.y,
|
|
|
|
this.z,
|
|
|
|
this.w
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Note, this normalize function leaves 'w' component untouched
|
|
|
|
*/
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.normalize = function () {
|
2016-12-08 19:43:16 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.multiply = function (q) {
|
2016-12-13 15:41:02 +01:00
|
|
|
|
|
|
|
var x, y, z, w;
|
|
|
|
var a = q;
|
|
|
|
var b = this;
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (q instanceof GameLib.API.Matrix4) {
|
2016-12-13 15:41:02 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2016-12-08 19:43:16 +01:00
|
|
|
this.x = x;
|
|
|
|
this.y = y;
|
|
|
|
this.z = z;
|
|
|
|
this.w = w;
|
2016-12-13 15:41:02 +01:00
|
|
|
|
|
|
|
return this;
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
} else if (q instanceof GameLib.API.Quaternion) {
|
2016-12-13 15:41:02 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2016-12-08 19:43:16 +01:00
|
|
|
} else {
|
2016-12-13 15:41:02 +01:00
|
|
|
console.log("This functionality not implemented - please do this");
|
|
|
|
throw new Error("This functionality not implemented - please do this");
|
2016-12-08 19:43:16 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.setFromAngle = function (angle) {
|
2016-12-09 20:32:09 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.subtract = function (v) {
|
2016-12-08 19:43:16 +01:00
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (v instanceof GameLib.API.Vector3) {
|
2016-12-08 19:43:16 +01:00
|
|
|
this.x -= v.x;
|
|
|
|
this.y -= v.y;
|
|
|
|
this.z -= v.z;
|
|
|
|
}
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
if (v instanceof GameLib.API.Quaternion) {
|
2016-12-08 19:43:16 +01:00
|
|
|
this.x -= v.x;
|
|
|
|
this.y -= v.y;
|
|
|
|
this.z -= v.z;
|
|
|
|
this.w -= v.w;
|
|
|
|
}
|
|
|
|
|
2016-12-13 15:41:02 +01:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.magnitude = function () {
|
2016-12-13 15:41:02 +01:00
|
|
|
return Math.sqrt(
|
|
|
|
(this.x * this.x) +
|
|
|
|
(this.y * this.y) +
|
|
|
|
(this.z * this.z) +
|
|
|
|
(this.w * this.w)
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.normalize = function () {
|
2016-12-13 15:41:02 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2016-12-15 14:53:39 +01:00
|
|
|
* @param matrix4 GameLib.Matrix4
|
2016-12-13 15:41:02 +01:00
|
|
|
*/
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.setFromRotationMatrix = function(matrix4) {
|
2016-12-13 15:41:02 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2016-12-15 14:53:39 +01:00
|
|
|
* @param quaternion GameLib.Quaternion
|
2016-12-13 15:41:02 +01:00
|
|
|
* @param t
|
2016-12-15 14:53:39 +01:00
|
|
|
* @returns {GameLib.Quaternion}
|
2016-12-13 15:41:02 +01:00
|
|
|
*/
|
2016-12-15 14:53:39 +01:00
|
|
|
GameLib.API.Quaternion.prototype.slerp = function (quaternion, t) {
|
2016-12-13 15:41:02 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2016-12-08 19:43:16 +01:00
|
|
|
return this;
|
2017-01-05 19:34:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns an API quaternion from an Object quaternion
|
|
|
|
* @param objectQuaternion
|
|
|
|
* @constructor
|
|
|
|
*/
|
2017-06-14 14:21:57 +02:00
|
|
|
GameLib.API.Quaternion.FromObject = function (objectQuaternion) {
|
2017-01-17 13:24:45 +01:00
|
|
|
|
|
|
|
var apiAxis = null;
|
|
|
|
|
|
|
|
if (objectQuaternion.axis) {
|
2017-06-14 14:21:57 +02:00
|
|
|
apiAxis = GameLib.API.Vector3.FromObject(objectQuaternion.axis);
|
2017-01-17 13:24:45 +01:00
|
|
|
}
|
|
|
|
|
2017-01-05 19:34:28 +01:00
|
|
|
return new GameLib.API.Quaternion(
|
|
|
|
objectQuaternion.x,
|
|
|
|
objectQuaternion.y,
|
|
|
|
objectQuaternion.z,
|
|
|
|
objectQuaternion.w,
|
2017-01-17 13:24:45 +01:00
|
|
|
apiAxis,
|
2017-01-05 19:34:28 +01:00
|
|
|
objectQuaternion.angle
|
|
|
|
)
|
2016-12-08 19:43:16 +01:00
|
|
|
};
|