224 lines
5.8 KiB
JavaScript
224 lines
5.8 KiB
JavaScript
GameLib.API.Quaternion.Points = function () {
|
|
this.vectors = [];
|
|
};
|
|
|
|
GameLib.API.Quaternion.Points.prototype.add = function (vector) {
|
|
|
|
if (vector instanceof GameLib.API.Vector3) {
|
|
vector = new GameLib.API.Quaternion(
|
|
vector.x,
|
|
vector.y,
|
|
vector.z,
|
|
1
|
|
)
|
|
}
|
|
|
|
if (!vector instanceof GameLib.API.Quaternion) {
|
|
console.warn("Vector needs to be of type Quaternion");
|
|
throw new Error("Vector needs to be of type Quaternion");
|
|
}
|
|
|
|
this.vectors.push(vector);
|
|
|
|
return this;
|
|
};
|
|
|
|
GameLib.API.Quaternion.Points.prototype.copy = function () {
|
|
|
|
var vectors = [];
|
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
vectors.push(this.vectors[i].copy());
|
|
}
|
|
|
|
return vectors;
|
|
};
|
|
|
|
GameLib.API.Quaternion.Points.prototype.maximizeXDistance = function (grain) {
|
|
|
|
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
|
|
|
var multiplier = 0;
|
|
|
|
var rotationMatrixY = new GameLib.API.Matrix4().rotationMatrixY(grain);
|
|
|
|
var totalRadians = 0;
|
|
|
|
var backupVectors = this.copy();
|
|
|
|
var maxXDistance = 0;
|
|
|
|
for (var i = 0; i < Math.PI * 2; i += grain) {
|
|
|
|
multiplier++;
|
|
|
|
for (var j = 0; j < this.vectors.length; j++) {
|
|
this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]);
|
|
}
|
|
|
|
var distances = this.distances();
|
|
|
|
if (distances.x > maxXDistance) {
|
|
|
|
maxXDistance = distances.x;
|
|
totalRadians = multiplier * grain;
|
|
}
|
|
}
|
|
|
|
this.vectors = backupVectors;
|
|
|
|
// console.log("distance: " + maxXDistance + " radians : " + totalRadians);
|
|
|
|
var maxRotationMatrix = new GameLib.API.Matrix4().rotationMatrixY(totalRadians);
|
|
|
|
for (var k = 0; k < this.vectors.length; k++) {
|
|
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
|
}
|
|
|
|
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
|
|
|
};
|
|
|
|
GameLib.API.Quaternion.Points.prototype.maximizeYDistance = function (grain) {
|
|
|
|
// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
|
|
|
|
var multiplier = 0;
|
|
|
|
var rotationMatrixX = new GameLib.API.Matrix4().rotationMatrixX(grain);
|
|
|
|
var totalRadians = 0;
|
|
|
|
var backupVectors = this.copy();
|
|
|
|
var maxYDistance = 0;
|
|
|
|
for (var i = 0; i < Math.PI * 2; i += grain) {
|
|
|
|
multiplier++;
|
|
|
|
for (var j = 0; j < this.vectors.length; j++) {
|
|
this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]);
|
|
}
|
|
|
|
var distances = this.distances();
|
|
|
|
if (distances.y > maxYDistance) {
|
|
maxYDistance = distances.y;
|
|
totalRadians = multiplier * grain;
|
|
}
|
|
}
|
|
|
|
this.vectors = backupVectors;
|
|
|
|
// console.log("distance: " + maxYDistance + " radians : " + totalRadians);
|
|
|
|
var maxRotationMatrix = new GameLib.API.Matrix4().rotationMatrixX(totalRadians);
|
|
|
|
for (var k = 0; k < this.vectors.length; k++) {
|
|
this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
|
|
}
|
|
|
|
// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
|
|
|
|
};
|
|
|
|
|
|
GameLib.API.Quaternion.Points.prototype.lookAt = function (at, up) {
|
|
|
|
var polyCenter = this.average();
|
|
|
|
console.log("poly center : " + JSON.stringify(polyCenter));
|
|
|
|
var lookAtMatrix = new GameLib.API.Matrix4().lookAt(polyCenter, at, up);
|
|
|
|
lookAtMatrix.rows[0] = new GameLib.API.Quaternion(1, 0, 0, 0);
|
|
lookAtMatrix.rows[1] = new GameLib.API.Quaternion(0, 0, 1, 0);
|
|
lookAtMatrix.rows[2] = new GameLib.API.Quaternion(0, 1, 0, 0);
|
|
|
|
console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2));
|
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i]));
|
|
this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]);
|
|
console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i]));
|
|
}
|
|
};
|
|
|
|
GameLib.API.Quaternion.Points.prototype.distances = function () {
|
|
|
|
var minX = this.vectors[0].x;
|
|
var minY = this.vectors[0].y;
|
|
var minZ = this.vectors[0].z;
|
|
|
|
var maxX = this.vectors[0].x;
|
|
var maxY = this.vectors[0].y;
|
|
var maxZ = this.vectors[0].z;
|
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
if (this.vectors[i].x < minX) {
|
|
minX = this.vectors[i].x;
|
|
}
|
|
if (this.vectors[i].y < minY) {
|
|
minY = this.vectors[i].y;
|
|
}
|
|
if (this.vectors[i].z < minZ) {
|
|
minZ = this.vectors[i].z;
|
|
}
|
|
|
|
if (this.vectors[i].x > maxX) {
|
|
maxX = this.vectors[i].x;
|
|
}
|
|
if (this.vectors[i].y > maxY) {
|
|
maxY = this.vectors[i].y;
|
|
}
|
|
if (this.vectors[i].z > maxZ) {
|
|
maxZ = this.vectors[i].z;
|
|
}
|
|
}
|
|
|
|
return new GameLib.API.Vector3(
|
|
Math.abs(maxX - minX),
|
|
Math.abs(maxY - minY),
|
|
Math.abs(maxY - minZ)
|
|
)
|
|
};
|
|
|
|
GameLib.API.Quaternion.Points.prototype.average = function () {
|
|
var averageX = 0;
|
|
var averageY = 0;
|
|
var averageZ = 0;
|
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
averageX += this.vectors[i].x;
|
|
averageY += this.vectors[i].y;
|
|
averageZ += this.vectors[i].z;
|
|
}
|
|
|
|
return new GameLib.API.Vector3(
|
|
averageX / this.vectors.length,
|
|
averageY / this.vectors.length,
|
|
averageZ / this.vectors.length
|
|
);
|
|
};
|
|
|
|
GameLib.API.Quaternion.Points.prototype.negate = function () {
|
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
this.vectors[i].x *= -1;
|
|
this.vectors[i].y *= -1;
|
|
this.vectors[i].z *= -1;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
|
|
GameLib.API.Quaternion.Points.prototype.toOrigin = function () {
|
|
|
|
var distanceFromOrigin = this.average().negate();
|
|
|
|
for (var i = 0; i < this.vectors.length; i++) {
|
|
this.vectors[i].translate(distanceFromOrigin);
|
|
}
|
|
}; |