Skip to content

Commit

Permalink
Attempt at fixing matrix operation for absolute vs incremental changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
brcolow committed Dec 25, 2024
1 parent ae2f32b commit 902cd22
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 5 deletions.
18 changes: 14 additions & 4 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { interpolate, turboColormapData } from "./colormap.js"
import { bowyerWatson, Vertex } from "./delaunay.js"
import { Mat4, Quat, Vector3 } from "./math.js"
import { Mat4, Quat, Vector3, Vector4 } from "./math.js"
import { getNumberOfStations, MoodyReport, SurfacePlate, roundTo } from "./moody.js"
import WebGLDebugUtils from "./webgl-debug.js"

Expand Down Expand Up @@ -264,12 +264,17 @@ let buffers = null
let showLines = true
let showHeatmap = true
let lightingOn = true
// Saves the absolute transformations applied to the table already by user actions (from the start state that roughly centers the table view).
let tableRotationMatrix = Mat4.create()
let tableScaleMatrix = Mat4.create()
let tableTranslateMatrix = Mat4.create()
// The view matrix is set when a new table is created via initialize3DTableGraphic - it does not change between frames.
let viewMatrix = Mat4.create()
// The projection matrix is set when a new table is created via initialize3DTableGraphic and if the canvas is resized.
let projectionMatrix = Mat4.create()

let tableModelMatrix = Mat4.create()

/**
* Converts a canvas-relative position (mouse coordinates) to clip space coordinates
* normalized by the maximum dimension of the canvas's bounding rectangle.
Expand Down Expand Up @@ -398,7 +403,7 @@ function initialize3DTableGraphic(moodyReport) {
}

document.onmouseup = () => {
startVectorMapped = null
startVectorMapped = null
tableRotationMatrix = Mat4.create()
}

Expand All @@ -418,7 +423,7 @@ function initialize3DTableGraphic(moodyReport) {
rotationQuat = new Quat(startVectorMapped.dot(currentVectorMapped), axis[0], -axis[1], 0)
}

tableRotationMatrix = Mat4.create()
// tableRotationMatrix = Mat4.create()
// We want rotation to be centered on the center of the table.
tableRotationMatrix.translate([(boundingBoxCache[zMultiplier].maxX - boundingBoxCache[zMultiplier].minX) / 2,
(boundingBoxCache[zMultiplier].maxY - boundingBoxCache[zMultiplier].minY) / 2,
Expand All @@ -427,6 +432,8 @@ function initialize3DTableGraphic(moodyReport) {
tableRotationMatrix.translate([-((boundingBoxCache[zMultiplier].maxX - boundingBoxCache[zMultiplier].minX) / 2),
-((boundingBoxCache[zMultiplier].maxY - boundingBoxCache[zMultiplier].minY) / 2),
-((boundingBoxCache[zMultiplier].maxZ - boundingBoxCache[zMultiplier].minZ) / 2)])
startVectorMapped = mapToSphere(event.clientX, event.clientY, canvas)

}
}

Expand Down Expand Up @@ -531,6 +538,9 @@ function initialize3DTableGraphic(moodyReport) {
now = updateFps(now)

drawTableSurface(moodyReport, gl, programInfo, buffers, texture)
tableRotationMatrix = Mat4.create()
tableScaleMatrix = Mat4.create()
tableTranslateMatrix = Mat4.create()
requestAnimationFrame(render)
}
requestAnimationFrame(render)
Expand Down Expand Up @@ -572,7 +582,7 @@ function drawTableSurface(moodyReport, gl, programInfo, buffers, texture) {
// We must set the model matrix to identity here because we are using relative (incremental) transforms.
// We need to make it so that all of our event handlers only mess with currentTransformMatrix, and then that
// will be applied to the model matrix.
const tableModelMatrix = Mat4.create()
// const tableModelMatrix = Mat4.create()
tableModelMatrix.multiply(tableScaleMatrix)
tableModelMatrix.multiply(tableTranslateMatrix)
tableModelMatrix.multiply(tableRotationMatrix)
Expand Down
93 changes: 92 additions & 1 deletion math.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class Vector3 extends Float32Array {
}
}

// Creates a new (0, 0, 0) vector.
static create() {
return new Vector3()
}

equals(b) {
return Vector3.equals(this, this, b)
}
Expand Down Expand Up @@ -158,8 +163,94 @@ class Vector3 extends Float32Array {
get magnitude() {
return Vector3.magnitude(this)
}

// Method to transform the vector with a 4x4 matrix
transformMat4(matrix) {
return Vector3.transformMat4(new Vector3(), this, matrix)
}

// Static method to transform a vector with a 4x4 matrix
static transformMat4(out, a, matrix) {
if (matrix.length !== 16) {
throw new Error("Matrix must be a 4x4 (16 elements).")
}

const x = a.x
const y = a.y
const z = a.z

out[0] = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12]
out[1] = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13]
out[2] = matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14]

return out
}
}

class Vector4 extends Float32Array {
constructor(...values) {
switch (values.length) {
case 4:
super(values);
break;
case 3:
super([...values, 1]); // Default w to 1 if not provided
break;
case 2:
super([...values, 0, 1]); // Default z to 0, w to 1
break;
case 1: {
const v = values[0];
if (typeof v === 'number') {
super([v, v, v, 1]); // Default w to 1 for scalar initialization
} else {
super([...v, ...Array(4 - v.length).fill(1)]);
}
break;
}
default:
super(4); // Default to a zero vector of size 4
break;
}
}

// Creates a new (0, 0, 0, 0) vector.
static create() {
return new Vector4()
}

get w() { return this[0] }
get x() { return this[1] }
get y() { return this[2] }
get z() { return this[3] }

// Method to transform the vector with a 4x4 matrix
transformMat4(matrix) {
return Vector4.transformMat4(this, this, matrix);
}

// Static method to transform a vector with a 4x4 matrix
static transformMat4(out, a, matrix) {
if (matrix.length !== 16) {
throw new Error("Matrix must be a 4x4 (16 elements).");
}

const x = a[0], y = a[1], z = a[2], w = a[3];

out[0] = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12] * w;
out[1] = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13] * w;
out[2] = matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14] * w;
out[3] = matrix[3] * x + matrix[7] * y + matrix[11] * z + matrix[15] * w;

return out;
}

toString() {
return `[${this[0]}, ${this[1]}, ${this[2]}, ${this[3]}]`;
}
}


const IDENTITY_4X4 = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
Expand Down Expand Up @@ -620,4 +711,4 @@ class Quat extends Float32Array {
tmpVec3 = new Float32Array(3)
}

export { Mat4, Quat, Vector3 }
export { Mat4, Quat, Vector3, Vector4 }

0 comments on commit 902cd22

Please sign in to comment.