@vib3code/sdk 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +118 -0
- package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
- package/DOCS/CI_TESTING.md +38 -0
- package/DOCS/CLI_ONBOARDING.md +75 -0
- package/DOCS/CONTROL_REFERENCE.md +64 -0
- package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
- package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
- package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
- package/DOCS/ENV_SETUP.md +189 -0
- package/DOCS/EXPORT_FORMATS.md +417 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
- package/DOCS/LICENSING_TIERS.md +275 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
- package/DOCS/OBS_SETUP_GUIDE.md +98 -0
- package/DOCS/PROJECT_SETUP.md +66 -0
- package/DOCS/RENDERER_LIFECYCLE.md +40 -0
- package/DOCS/REPO_MANIFEST.md +121 -0
- package/DOCS/SESSION_014_PLAN.md +195 -0
- package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
- package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
- package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
- package/DOCS/SYSTEM_INVENTORY.md +520 -0
- package/DOCS/TELEMETRY_EXPORTS.md +34 -0
- package/DOCS/WEBGPU_STATUS.md +38 -0
- package/DOCS/XR_BENCHMARKS.md +608 -0
- package/LICENSE +21 -0
- package/README.md +426 -0
- package/docs/.nojekyll +0 -0
- package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/02-hyperspatial_ego_death.html +346 -0
- package/docs/03-post_cartesian_sublime.html +346 -0
- package/docs/04-crystalline_void_meditation.html +346 -0
- package/docs/05-quantum_decoherence_ballet.html +346 -0
- package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/07-hyperspatial_ego_death.html +346 -0
- package/docs/08-post_cartesian_sublime.html +346 -0
- package/docs/09-crystalline_void_meditation.html +346 -0
- package/docs/10-quantum_decoherence_ballet.html +346 -0
- package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
- package/docs/12-hyperspatial_ego_death.html +346 -0
- package/docs/13-post_cartesian_sublime.html +346 -0
- package/docs/index.html +794 -0
- package/docs/test-hub.html +441 -0
- package/docs/url-state.js +102 -0
- package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
- package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
- package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
- package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
- package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
- package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
- package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
- package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
- package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
- package/docs/vib3-exports/index.html +238 -0
- package/docs/webgpu-live.html +702 -0
- package/package.json +367 -0
- package/src/advanced/AIPresetGenerator.js +777 -0
- package/src/advanced/MIDIController.js +703 -0
- package/src/advanced/OffscreenWorker.js +1051 -0
- package/src/advanced/WebGPUCompute.js +1051 -0
- package/src/advanced/WebXRRenderer.js +680 -0
- package/src/agent/cli/AgentCLI.js +615 -0
- package/src/agent/cli/index.js +14 -0
- package/src/agent/index.js +73 -0
- package/src/agent/mcp/MCPServer.js +950 -0
- package/src/agent/mcp/index.js +9 -0
- package/src/agent/mcp/tools.js +548 -0
- package/src/agent/telemetry/EventStream.js +669 -0
- package/src/agent/telemetry/Instrumentation.js +618 -0
- package/src/agent/telemetry/TelemetryExporters.js +427 -0
- package/src/agent/telemetry/TelemetryService.js +464 -0
- package/src/agent/telemetry/index.js +52 -0
- package/src/benchmarks/BenchmarkRunner.js +381 -0
- package/src/benchmarks/MetricsCollector.js +299 -0
- package/src/benchmarks/index.js +9 -0
- package/src/benchmarks/scenes.js +259 -0
- package/src/cli/index.js +675 -0
- package/src/config/ApiConfig.js +88 -0
- package/src/core/CanvasManager.js +217 -0
- package/src/core/ErrorReporter.js +117 -0
- package/src/core/ParameterMapper.js +333 -0
- package/src/core/Parameters.js +396 -0
- package/src/core/RendererContracts.js +200 -0
- package/src/core/UnifiedResourceManager.js +370 -0
- package/src/core/VIB3Engine.js +636 -0
- package/src/core/renderers/FacetedRendererAdapter.js +32 -0
- package/src/core/renderers/HolographicRendererAdapter.js +29 -0
- package/src/core/renderers/QuantumRendererAdapter.js +29 -0
- package/src/core/renderers/RendererLifecycleManager.js +63 -0
- package/src/creative/ColorPresetsSystem.js +980 -0
- package/src/creative/ParameterTimeline.js +1061 -0
- package/src/creative/PostProcessingPipeline.js +1113 -0
- package/src/creative/TransitionAnimator.js +683 -0
- package/src/export/CSSExporter.js +226 -0
- package/src/export/CardGeneratorBase.js +279 -0
- package/src/export/ExportManager.js +580 -0
- package/src/export/FacetedCardGenerator.js +279 -0
- package/src/export/HolographicCardGenerator.js +543 -0
- package/src/export/LottieExporter.js +552 -0
- package/src/export/QuantumCardGenerator.js +315 -0
- package/src/export/SVGExporter.js +519 -0
- package/src/export/ShaderExporter.js +903 -0
- package/src/export/TradingCardGenerator.js +3055 -0
- package/src/export/TradingCardManager.js +181 -0
- package/src/export/VIB3PackageExporter.js +559 -0
- package/src/export/index.js +14 -0
- package/src/export/systems/TradingCardSystemFaceted.js +494 -0
- package/src/export/systems/TradingCardSystemHolographic.js +452 -0
- package/src/export/systems/TradingCardSystemQuantum.js +411 -0
- package/src/faceted/FacetedSystem.js +963 -0
- package/src/features/CollectionManager.js +433 -0
- package/src/gallery/CollectionManager.js +240 -0
- package/src/gallery/GallerySystem.js +485 -0
- package/src/geometry/GeometryFactory.js +314 -0
- package/src/geometry/GeometryLibrary.js +72 -0
- package/src/geometry/buffers/BufferBuilder.js +338 -0
- package/src/geometry/buffers/index.js +18 -0
- package/src/geometry/generators/Crystal.js +420 -0
- package/src/geometry/generators/Fractal.js +298 -0
- package/src/geometry/generators/KleinBottle.js +197 -0
- package/src/geometry/generators/Sphere.js +192 -0
- package/src/geometry/generators/Tesseract.js +160 -0
- package/src/geometry/generators/Tetrahedron.js +225 -0
- package/src/geometry/generators/Torus.js +304 -0
- package/src/geometry/generators/Wave.js +341 -0
- package/src/geometry/index.js +142 -0
- package/src/geometry/warp/HypersphereCore.js +211 -0
- package/src/geometry/warp/HypertetraCore.js +386 -0
- package/src/geometry/warp/index.js +57 -0
- package/src/holograms/HolographicVisualizer.js +1073 -0
- package/src/holograms/RealHolographicSystem.js +966 -0
- package/src/holograms/variantRegistry.js +69 -0
- package/src/integrations/FigmaPlugin.js +854 -0
- package/src/integrations/OBSMode.js +754 -0
- package/src/integrations/ThreeJsPackage.js +660 -0
- package/src/integrations/TouchDesignerExport.js +552 -0
- package/src/integrations/frameworks/Vib3React.js +591 -0
- package/src/integrations/frameworks/Vib3Svelte.js +654 -0
- package/src/integrations/frameworks/Vib3Vue.js +628 -0
- package/src/llm/LLMParameterInterface.js +240 -0
- package/src/llm/LLMParameterUI.js +577 -0
- package/src/math/Mat4x4.js +708 -0
- package/src/math/Projection.js +341 -0
- package/src/math/Rotor4D.js +637 -0
- package/src/math/Vec4.js +476 -0
- package/src/math/constants.js +164 -0
- package/src/math/index.js +68 -0
- package/src/math/projections.js +54 -0
- package/src/math/rotations.js +196 -0
- package/src/quantum/QuantumEngine.js +906 -0
- package/src/quantum/QuantumVisualizer.js +1103 -0
- package/src/reactivity/ReactivityConfig.js +499 -0
- package/src/reactivity/ReactivityManager.js +586 -0
- package/src/reactivity/SpatialInputSystem.js +1783 -0
- package/src/reactivity/index.js +93 -0
- package/src/render/CommandBuffer.js +465 -0
- package/src/render/MultiCanvasBridge.js +340 -0
- package/src/render/RenderCommand.js +514 -0
- package/src/render/RenderResourceRegistry.js +523 -0
- package/src/render/RenderState.js +552 -0
- package/src/render/RenderTarget.js +512 -0
- package/src/render/ShaderLoader.js +253 -0
- package/src/render/ShaderProgram.js +599 -0
- package/src/render/UnifiedRenderBridge.js +496 -0
- package/src/render/backends/WebGLBackend.js +1108 -0
- package/src/render/backends/WebGPUBackend.js +1409 -0
- package/src/render/commands/CommandBufferExecutor.js +607 -0
- package/src/render/commands/RenderCommandBuffer.js +661 -0
- package/src/render/commands/index.js +17 -0
- package/src/render/index.js +367 -0
- package/src/scene/Disposable.js +498 -0
- package/src/scene/MemoryPool.js +618 -0
- package/src/scene/Node4D.js +697 -0
- package/src/scene/ResourceManager.js +599 -0
- package/src/scene/Scene4D.js +540 -0
- package/src/scene/index.js +98 -0
- package/src/schemas/error.schema.json +84 -0
- package/src/schemas/extension.schema.json +88 -0
- package/src/schemas/index.js +214 -0
- package/src/schemas/parameters.schema.json +142 -0
- package/src/schemas/tool-pack.schema.json +44 -0
- package/src/schemas/tool-response.schema.json +127 -0
- package/src/shaders/common/fullscreen.vert.glsl +5 -0
- package/src/shaders/common/fullscreen.vert.wgsl +17 -0
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +85 -0
- package/src/shaders/common/rotation4d.wgsl +86 -0
- package/src/shaders/common/uniforms.glsl +44 -0
- package/src/shaders/common/uniforms.wgsl +48 -0
- package/src/shaders/faceted/faceted.frag.glsl +129 -0
- package/src/shaders/faceted/faceted.frag.wgsl +164 -0
- package/src/shaders/holographic/holographic.frag.glsl +406 -0
- package/src/shaders/holographic/holographic.frag.wgsl +185 -0
- package/src/shaders/quantum/quantum.frag.glsl +513 -0
- package/src/shaders/quantum/quantum.frag.wgsl +361 -0
- package/src/testing/ParallelTestFramework.js +519 -0
- package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
- package/src/testing/exportFormats.test.js +8 -0
- package/src/testing/projections.test.js +14 -0
- package/src/testing/rotations.test.js +37 -0
- package/src/ui/InteractivityMenu.js +516 -0
- package/src/ui/StatusManager.js +96 -0
- package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
- package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
- package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
- package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
- package/src/variations/VariationManager.js +431 -0
- package/src/viewer/AudioReactivity.js +505 -0
- package/src/viewer/CardBending.js +481 -0
- package/src/viewer/GalleryUI.js +832 -0
- package/src/viewer/ReactivityManager.js +590 -0
- package/src/viewer/TradingCardExporter.js +600 -0
- package/src/viewer/ViewerPortal.js +374 -0
- package/src/viewer/index.js +12 -0
- package/src/wasm/WasmLoader.js +296 -0
- package/src/wasm/index.js +132 -0
- package/tools/agentic/mcpTools.js +88 -0
- package/tools/cli/agent-cli.js +92 -0
- package/tools/export/formats.js +24 -0
- package/tools/math/rotation-baseline.mjs +64 -0
- package/tools/shader-sync-verify.js +937 -0
- package/tools/telemetry/manifestPipeline.js +141 -0
- package/tools/telemetry/telemetryEvents.js +35 -0
- package/types/adaptive-sdk.d.ts +185 -0
- package/types/advanced/AIPresetGenerator.d.ts +81 -0
- package/types/advanced/MIDIController.d.ts +100 -0
- package/types/advanced/OffscreenWorker.d.ts +82 -0
- package/types/advanced/WebGPUCompute.d.ts +52 -0
- package/types/advanced/WebXRRenderer.d.ts +77 -0
- package/types/advanced/index.d.ts +46 -0
- package/types/core/ErrorReporter.d.ts +50 -0
- package/types/core/VIB3Engine.d.ts +204 -0
- package/types/creative/ColorPresetsSystem.d.ts +91 -0
- package/types/creative/ParameterTimeline.d.ts +74 -0
- package/types/creative/PostProcessingPipeline.d.ts +109 -0
- package/types/creative/TransitionAnimator.d.ts +71 -0
- package/types/creative/index.d.ts +35 -0
- package/types/integrations/FigmaPlugin.d.ts +46 -0
- package/types/integrations/OBSMode.d.ts +74 -0
- package/types/integrations/ThreeJsPackage.d.ts +62 -0
- package/types/integrations/TouchDesignerExport.d.ts +36 -0
- package/types/integrations/Vib3React.d.ts +74 -0
- package/types/integrations/Vib3Svelte.d.ts +63 -0
- package/types/integrations/Vib3Vue.d.ts +55 -0
- package/types/integrations/index.d.ts +52 -0
- package/types/reactivity/SpatialInputSystem.d.ts +173 -0
- package/types/reactivity/index.d.ts +394 -0
- package/types/render/CommandBuffer.d.ts +169 -0
- package/types/render/RenderCommand.d.ts +312 -0
- package/types/render/RenderState.d.ts +279 -0
- package/types/render/RenderTarget.d.ts +254 -0
- package/types/render/ShaderProgram.d.ts +277 -0
- package/types/render/UnifiedRenderBridge.d.ts +143 -0
- package/types/render/WebGLBackend.d.ts +168 -0
- package/types/render/WebGPUBackend.d.ts +186 -0
- package/types/render/index.d.ts +141 -0
|
@@ -0,0 +1,708 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mat4x4 - 4x4 Matrix Class
|
|
3
|
+
*
|
|
4
|
+
* Column-major layout for WebGL/GPU compatibility.
|
|
5
|
+
* Used for 4D transformations including all 6 rotation planes.
|
|
6
|
+
*
|
|
7
|
+
* Memory layout (column-major):
|
|
8
|
+
* | m[0] m[4] m[8] m[12] |
|
|
9
|
+
* | m[1] m[5] m[9] m[13] |
|
|
10
|
+
* | m[2] m[6] m[10] m[14] |
|
|
11
|
+
* | m[3] m[7] m[11] m[15] |
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const rotXW = Mat4x4.rotationXW(Math.PI / 4);
|
|
15
|
+
* const transformed = rotXW.multiplyVec4(vec4);
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { Vec4 } from './Vec4.js';
|
|
19
|
+
|
|
20
|
+
export class Mat4x4 {
|
|
21
|
+
/**
|
|
22
|
+
* Create a new 4x4 matrix
|
|
23
|
+
* Default is identity matrix
|
|
24
|
+
* @param {Float32Array|number[]} [elements] - 16 elements in column-major order
|
|
25
|
+
*/
|
|
26
|
+
constructor(elements = null) {
|
|
27
|
+
this.data = new Float32Array(16);
|
|
28
|
+
|
|
29
|
+
if (elements) {
|
|
30
|
+
if (elements.length !== 16) {
|
|
31
|
+
throw new Error('Mat4x4 requires exactly 16 elements');
|
|
32
|
+
}
|
|
33
|
+
this.data.set(elements);
|
|
34
|
+
} else {
|
|
35
|
+
// Default to identity
|
|
36
|
+
this.data[0] = 1;
|
|
37
|
+
this.data[5] = 1;
|
|
38
|
+
this.data[10] = 1;
|
|
39
|
+
this.data[15] = 1;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Create identity matrix
|
|
45
|
+
* @returns {Mat4x4}
|
|
46
|
+
*/
|
|
47
|
+
static identity() {
|
|
48
|
+
return new Mat4x4([
|
|
49
|
+
1, 0, 0, 0,
|
|
50
|
+
0, 1, 0, 0,
|
|
51
|
+
0, 0, 1, 0,
|
|
52
|
+
0, 0, 0, 1
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Create zero matrix
|
|
58
|
+
* @returns {Mat4x4}
|
|
59
|
+
*/
|
|
60
|
+
static zero() {
|
|
61
|
+
return new Mat4x4(new Float32Array(16));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Clone this matrix
|
|
66
|
+
* @returns {Mat4x4}
|
|
67
|
+
*/
|
|
68
|
+
clone() {
|
|
69
|
+
return new Mat4x4(this.data);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Copy from another matrix
|
|
74
|
+
* @param {Mat4x4} m
|
|
75
|
+
* @returns {Mat4x4} this
|
|
76
|
+
*/
|
|
77
|
+
copy(m) {
|
|
78
|
+
this.data.set(m.data);
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get element at row, column
|
|
84
|
+
* @param {number} row - 0-3
|
|
85
|
+
* @param {number} col - 0-3
|
|
86
|
+
* @returns {number}
|
|
87
|
+
*/
|
|
88
|
+
get(row, col) {
|
|
89
|
+
return this.data[col * 4 + row];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Set element at row, column
|
|
94
|
+
* @param {number} row - 0-3
|
|
95
|
+
* @param {number} col - 0-3
|
|
96
|
+
* @param {number} value
|
|
97
|
+
* @returns {Mat4x4} this
|
|
98
|
+
*/
|
|
99
|
+
set(row, col, value) {
|
|
100
|
+
this.data[col * 4 + row] = value;
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get column as Vec4
|
|
106
|
+
* @param {number} col - 0-3
|
|
107
|
+
* @returns {Vec4}
|
|
108
|
+
*/
|
|
109
|
+
getColumn(col) {
|
|
110
|
+
const i = col * 4;
|
|
111
|
+
return new Vec4(this.data[i], this.data[i + 1], this.data[i + 2], this.data[i + 3]);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Set column from Vec4
|
|
116
|
+
* @param {number} col - 0-3
|
|
117
|
+
* @param {Vec4} v
|
|
118
|
+
* @returns {Mat4x4} this
|
|
119
|
+
*/
|
|
120
|
+
setColumn(col, v) {
|
|
121
|
+
const i = col * 4;
|
|
122
|
+
this.data[i] = v.x;
|
|
123
|
+
this.data[i + 1] = v.y;
|
|
124
|
+
this.data[i + 2] = v.z;
|
|
125
|
+
this.data[i + 3] = v.w;
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get row as Vec4
|
|
131
|
+
* @param {number} row - 0-3
|
|
132
|
+
* @returns {Vec4}
|
|
133
|
+
*/
|
|
134
|
+
getRow(row) {
|
|
135
|
+
return new Vec4(
|
|
136
|
+
this.data[row],
|
|
137
|
+
this.data[row + 4],
|
|
138
|
+
this.data[row + 8],
|
|
139
|
+
this.data[row + 12]
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Set row from Vec4
|
|
145
|
+
* @param {number} row - 0-3
|
|
146
|
+
* @param {Vec4} v
|
|
147
|
+
* @returns {Mat4x4} this
|
|
148
|
+
*/
|
|
149
|
+
setRow(row, v) {
|
|
150
|
+
this.data[row] = v.x;
|
|
151
|
+
this.data[row + 4] = v.y;
|
|
152
|
+
this.data[row + 8] = v.z;
|
|
153
|
+
this.data[row + 12] = v.w;
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Multiply two matrices
|
|
159
|
+
* @param {Mat4x4} m - Right operand
|
|
160
|
+
* @returns {Mat4x4} New matrix = this * m
|
|
161
|
+
*/
|
|
162
|
+
multiply(m) {
|
|
163
|
+
const a = this.data;
|
|
164
|
+
const b = m.data;
|
|
165
|
+
const result = new Float32Array(16);
|
|
166
|
+
|
|
167
|
+
for (let col = 0; col < 4; col++) {
|
|
168
|
+
for (let row = 0; row < 4; row++) {
|
|
169
|
+
let sum = 0;
|
|
170
|
+
for (let k = 0; k < 4; k++) {
|
|
171
|
+
sum += a[k * 4 + row] * b[col * 4 + k];
|
|
172
|
+
}
|
|
173
|
+
result[col * 4 + row] = sum;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return new Mat4x4(result);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Multiply in place (this = this * m)
|
|
182
|
+
* @param {Mat4x4} m
|
|
183
|
+
* @returns {Mat4x4} this
|
|
184
|
+
*/
|
|
185
|
+
multiplyInPlace(m) {
|
|
186
|
+
const result = this.multiply(m);
|
|
187
|
+
this.data.set(result.data);
|
|
188
|
+
return this;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Pre-multiply (this = m * this)
|
|
193
|
+
* @param {Mat4x4} m
|
|
194
|
+
* @returns {Mat4x4} this
|
|
195
|
+
*/
|
|
196
|
+
preMultiplyInPlace(m) {
|
|
197
|
+
const result = m.multiply(this);
|
|
198
|
+
this.data.set(result.data);
|
|
199
|
+
return this;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Transform a Vec4 by this matrix
|
|
204
|
+
* @param {Vec4} v
|
|
205
|
+
* @returns {Vec4} Transformed vector
|
|
206
|
+
*/
|
|
207
|
+
multiplyVec4(v) {
|
|
208
|
+
const m = this.data;
|
|
209
|
+
return new Vec4(
|
|
210
|
+
m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12] * v.w,
|
|
211
|
+
m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13] * v.w,
|
|
212
|
+
m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14] * v.w,
|
|
213
|
+
m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15] * v.w
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Transform array of Vec4s by this matrix
|
|
219
|
+
* @param {Vec4[]} vectors
|
|
220
|
+
* @returns {Vec4[]} Transformed vectors
|
|
221
|
+
*/
|
|
222
|
+
multiplyVec4Array(vectors) {
|
|
223
|
+
return vectors.map(v => this.multiplyVec4(v));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Transform a Float32Array of packed vec4s (x,y,z,w,x,y,z,w,...)
|
|
228
|
+
* @param {Float32Array} packed - Input packed vectors
|
|
229
|
+
* @param {Float32Array} [output] - Optional output buffer
|
|
230
|
+
* @returns {Float32Array} Transformed packed vectors
|
|
231
|
+
*/
|
|
232
|
+
multiplyPackedVec4(packed, output = null) {
|
|
233
|
+
const count = packed.length / 4;
|
|
234
|
+
const result = output || new Float32Array(packed.length);
|
|
235
|
+
const m = this.data;
|
|
236
|
+
|
|
237
|
+
for (let i = 0; i < count; i++) {
|
|
238
|
+
const offset = i * 4;
|
|
239
|
+
const x = packed[offset];
|
|
240
|
+
const y = packed[offset + 1];
|
|
241
|
+
const z = packed[offset + 2];
|
|
242
|
+
const w = packed[offset + 3];
|
|
243
|
+
|
|
244
|
+
result[offset] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
|
|
245
|
+
result[offset + 1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
|
|
246
|
+
result[offset + 2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
|
|
247
|
+
result[offset + 3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return result;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Add another matrix
|
|
255
|
+
* @param {Mat4x4} m
|
|
256
|
+
* @returns {Mat4x4} New matrix
|
|
257
|
+
*/
|
|
258
|
+
add(m) {
|
|
259
|
+
const result = new Float32Array(16);
|
|
260
|
+
for (let i = 0; i < 16; i++) {
|
|
261
|
+
result[i] = this.data[i] + m.data[i];
|
|
262
|
+
}
|
|
263
|
+
return new Mat4x4(result);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Multiply by scalar
|
|
268
|
+
* @param {number} s
|
|
269
|
+
* @returns {Mat4x4} New matrix
|
|
270
|
+
*/
|
|
271
|
+
scale(s) {
|
|
272
|
+
const result = new Float32Array(16);
|
|
273
|
+
for (let i = 0; i < 16; i++) {
|
|
274
|
+
result[i] = this.data[i] * s;
|
|
275
|
+
}
|
|
276
|
+
return new Mat4x4(result);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Transpose matrix
|
|
281
|
+
* @returns {Mat4x4} New transposed matrix
|
|
282
|
+
*/
|
|
283
|
+
transpose() {
|
|
284
|
+
const m = this.data;
|
|
285
|
+
return new Mat4x4([
|
|
286
|
+
m[0], m[4], m[8], m[12],
|
|
287
|
+
m[1], m[5], m[9], m[13],
|
|
288
|
+
m[2], m[6], m[10], m[14],
|
|
289
|
+
m[3], m[7], m[11], m[15]
|
|
290
|
+
]);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Transpose in place
|
|
295
|
+
* @returns {Mat4x4} this
|
|
296
|
+
*/
|
|
297
|
+
transposeInPlace() {
|
|
298
|
+
const m = this.data;
|
|
299
|
+
let tmp;
|
|
300
|
+
|
|
301
|
+
tmp = m[1]; m[1] = m[4]; m[4] = tmp;
|
|
302
|
+
tmp = m[2]; m[2] = m[8]; m[8] = tmp;
|
|
303
|
+
tmp = m[3]; m[3] = m[12]; m[12] = tmp;
|
|
304
|
+
tmp = m[6]; m[6] = m[9]; m[9] = tmp;
|
|
305
|
+
tmp = m[7]; m[7] = m[13]; m[13] = tmp;
|
|
306
|
+
tmp = m[11]; m[11] = m[14]; m[14] = tmp;
|
|
307
|
+
|
|
308
|
+
return this;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Calculate determinant
|
|
313
|
+
* @returns {number}
|
|
314
|
+
*/
|
|
315
|
+
determinant() {
|
|
316
|
+
const m = this.data;
|
|
317
|
+
|
|
318
|
+
const a00 = m[0], a01 = m[4], a02 = m[8], a03 = m[12];
|
|
319
|
+
const a10 = m[1], a11 = m[5], a12 = m[9], a13 = m[13];
|
|
320
|
+
const a20 = m[2], a21 = m[6], a22 = m[10], a23 = m[14];
|
|
321
|
+
const a30 = m[3], a31 = m[7], a32 = m[11], a33 = m[15];
|
|
322
|
+
|
|
323
|
+
const b00 = a00 * a11 - a01 * a10;
|
|
324
|
+
const b01 = a00 * a12 - a02 * a10;
|
|
325
|
+
const b02 = a00 * a13 - a03 * a10;
|
|
326
|
+
const b03 = a01 * a12 - a02 * a11;
|
|
327
|
+
const b04 = a01 * a13 - a03 * a11;
|
|
328
|
+
const b05 = a02 * a13 - a03 * a12;
|
|
329
|
+
const b06 = a20 * a31 - a21 * a30;
|
|
330
|
+
const b07 = a20 * a32 - a22 * a30;
|
|
331
|
+
const b08 = a20 * a33 - a23 * a30;
|
|
332
|
+
const b09 = a21 * a32 - a22 * a31;
|
|
333
|
+
const b10 = a21 * a33 - a23 * a31;
|
|
334
|
+
const b11 = a22 * a33 - a23 * a32;
|
|
335
|
+
|
|
336
|
+
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Calculate inverse matrix
|
|
341
|
+
* @returns {Mat4x4|null} Inverse matrix or null if singular
|
|
342
|
+
*/
|
|
343
|
+
inverse() {
|
|
344
|
+
const m = this.data;
|
|
345
|
+
const inv = new Float32Array(16);
|
|
346
|
+
|
|
347
|
+
inv[0] = m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] +
|
|
348
|
+
m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10];
|
|
349
|
+
|
|
350
|
+
inv[4] = -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] -
|
|
351
|
+
m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10];
|
|
352
|
+
|
|
353
|
+
inv[8] = m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] +
|
|
354
|
+
m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9];
|
|
355
|
+
|
|
356
|
+
inv[12] = -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] -
|
|
357
|
+
m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9];
|
|
358
|
+
|
|
359
|
+
inv[1] = -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] -
|
|
360
|
+
m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10];
|
|
361
|
+
|
|
362
|
+
inv[5] = m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] +
|
|
363
|
+
m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10];
|
|
364
|
+
|
|
365
|
+
inv[9] = -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] -
|
|
366
|
+
m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9];
|
|
367
|
+
|
|
368
|
+
inv[13] = m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] +
|
|
369
|
+
m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9];
|
|
370
|
+
|
|
371
|
+
inv[2] = m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] +
|
|
372
|
+
m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6];
|
|
373
|
+
|
|
374
|
+
inv[6] = -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] -
|
|
375
|
+
m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6];
|
|
376
|
+
|
|
377
|
+
inv[10] = m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] +
|
|
378
|
+
m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5];
|
|
379
|
+
|
|
380
|
+
inv[14] = -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] -
|
|
381
|
+
m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5];
|
|
382
|
+
|
|
383
|
+
inv[3] = -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] -
|
|
384
|
+
m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6];
|
|
385
|
+
|
|
386
|
+
inv[7] = m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] +
|
|
387
|
+
m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6];
|
|
388
|
+
|
|
389
|
+
inv[11] = -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] -
|
|
390
|
+
m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5];
|
|
391
|
+
|
|
392
|
+
inv[15] = m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] +
|
|
393
|
+
m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5];
|
|
394
|
+
|
|
395
|
+
const det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
|
396
|
+
|
|
397
|
+
if (Math.abs(det) < 1e-10) {
|
|
398
|
+
return null; // Singular matrix
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const invDet = 1 / det;
|
|
402
|
+
for (let i = 0; i < 16; i++) {
|
|
403
|
+
inv[i] *= invDet;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return new Mat4x4(inv);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Check if approximately equal to another matrix
|
|
411
|
+
* @param {Mat4x4} m
|
|
412
|
+
* @param {number} epsilon
|
|
413
|
+
* @returns {boolean}
|
|
414
|
+
*/
|
|
415
|
+
equals(m, epsilon = 1e-6) {
|
|
416
|
+
for (let i = 0; i < 16; i++) {
|
|
417
|
+
if (Math.abs(this.data[i] - m.data[i]) > epsilon) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return true;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Check if this is identity matrix
|
|
426
|
+
* @param {number} epsilon
|
|
427
|
+
* @returns {boolean}
|
|
428
|
+
*/
|
|
429
|
+
isIdentity(epsilon = 1e-6) {
|
|
430
|
+
return this.equals(Mat4x4.identity(), epsilon);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Check if orthogonal (rotation matrix)
|
|
435
|
+
* @param {number} epsilon
|
|
436
|
+
* @returns {boolean}
|
|
437
|
+
*/
|
|
438
|
+
isOrthogonal(epsilon = 1e-6) {
|
|
439
|
+
const product = this.multiply(this.transpose());
|
|
440
|
+
return product.isIdentity(epsilon);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Get the Float32Array for GPU upload
|
|
445
|
+
* @returns {Float32Array}
|
|
446
|
+
*/
|
|
447
|
+
toFloat32Array() {
|
|
448
|
+
return new Float32Array(this.data);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Convert to 2D array (row-major for readability)
|
|
453
|
+
* @returns {number[][]}
|
|
454
|
+
*/
|
|
455
|
+
toArray2D() {
|
|
456
|
+
return [
|
|
457
|
+
[this.data[0], this.data[4], this.data[8], this.data[12]],
|
|
458
|
+
[this.data[1], this.data[5], this.data[9], this.data[13]],
|
|
459
|
+
[this.data[2], this.data[6], this.data[10], this.data[14]],
|
|
460
|
+
[this.data[3], this.data[7], this.data[11], this.data[15]]
|
|
461
|
+
];
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* String representation
|
|
466
|
+
* @param {number} precision
|
|
467
|
+
* @returns {string}
|
|
468
|
+
*/
|
|
469
|
+
toString(precision = 3) {
|
|
470
|
+
const rows = this.toArray2D();
|
|
471
|
+
return rows.map(row =>
|
|
472
|
+
'| ' + row.map(v => v.toFixed(precision).padStart(8)).join(' ') + ' |'
|
|
473
|
+
).join('\n');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* JSON representation
|
|
478
|
+
* @returns {object}
|
|
479
|
+
*/
|
|
480
|
+
toJSON() {
|
|
481
|
+
return { data: Array.from(this.data), columnMajor: true };
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Create from JSON
|
|
486
|
+
* @param {object} json
|
|
487
|
+
* @returns {Mat4x4}
|
|
488
|
+
*/
|
|
489
|
+
static fromJSON(json) {
|
|
490
|
+
return new Mat4x4(json.data);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// ========== ROTATION MATRICES FOR ALL 6 PLANES ==========
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Create XY plane rotation matrix (standard Z-axis rotation in 3D)
|
|
497
|
+
* @param {number} angle - Rotation angle in radians
|
|
498
|
+
* @returns {Mat4x4}
|
|
499
|
+
*/
|
|
500
|
+
static rotationXY(angle) {
|
|
501
|
+
const c = Math.cos(angle);
|
|
502
|
+
const s = Math.sin(angle);
|
|
503
|
+
return new Mat4x4([
|
|
504
|
+
c, s, 0, 0,
|
|
505
|
+
-s, c, 0, 0,
|
|
506
|
+
0, 0, 1, 0,
|
|
507
|
+
0, 0, 0, 1
|
|
508
|
+
]);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Create XZ plane rotation matrix (standard Y-axis rotation in 3D)
|
|
513
|
+
* @param {number} angle - Rotation angle in radians
|
|
514
|
+
* @returns {Mat4x4}
|
|
515
|
+
*/
|
|
516
|
+
static rotationXZ(angle) {
|
|
517
|
+
const c = Math.cos(angle);
|
|
518
|
+
const s = Math.sin(angle);
|
|
519
|
+
return new Mat4x4([
|
|
520
|
+
c, 0, -s, 0,
|
|
521
|
+
0, 1, 0, 0,
|
|
522
|
+
s, 0, c, 0,
|
|
523
|
+
0, 0, 0, 1
|
|
524
|
+
]);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Create YZ plane rotation matrix (standard X-axis rotation in 3D)
|
|
529
|
+
* @param {number} angle - Rotation angle in radians
|
|
530
|
+
* @returns {Mat4x4}
|
|
531
|
+
*/
|
|
532
|
+
static rotationYZ(angle) {
|
|
533
|
+
const c = Math.cos(angle);
|
|
534
|
+
const s = Math.sin(angle);
|
|
535
|
+
return new Mat4x4([
|
|
536
|
+
1, 0, 0, 0,
|
|
537
|
+
0, c, s, 0,
|
|
538
|
+
0, -s, c, 0,
|
|
539
|
+
0, 0, 0, 1
|
|
540
|
+
]);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Create XW plane rotation matrix (4D hyperspace rotation)
|
|
545
|
+
* Creates "inside-out" effect when w approaches viewer
|
|
546
|
+
* @param {number} angle - Rotation angle in radians
|
|
547
|
+
* @returns {Mat4x4}
|
|
548
|
+
*/
|
|
549
|
+
static rotationXW(angle) {
|
|
550
|
+
const c = Math.cos(angle);
|
|
551
|
+
const s = Math.sin(angle);
|
|
552
|
+
return new Mat4x4([
|
|
553
|
+
c, 0, 0, s,
|
|
554
|
+
0, 1, 0, 0,
|
|
555
|
+
0, 0, 1, 0,
|
|
556
|
+
-s, 0, 0, c
|
|
557
|
+
]);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Create YW plane rotation matrix (4D hyperspace rotation)
|
|
562
|
+
* @param {number} angle - Rotation angle in radians
|
|
563
|
+
* @returns {Mat4x4}
|
|
564
|
+
*/
|
|
565
|
+
static rotationYW(angle) {
|
|
566
|
+
const c = Math.cos(angle);
|
|
567
|
+
const s = Math.sin(angle);
|
|
568
|
+
return new Mat4x4([
|
|
569
|
+
1, 0, 0, 0,
|
|
570
|
+
0, c, 0, s,
|
|
571
|
+
0, 0, 1, 0,
|
|
572
|
+
0, -s, 0, c
|
|
573
|
+
]);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Create ZW plane rotation matrix (4D hyperspace rotation)
|
|
578
|
+
* @param {number} angle - Rotation angle in radians
|
|
579
|
+
* @returns {Mat4x4}
|
|
580
|
+
*/
|
|
581
|
+
static rotationZW(angle) {
|
|
582
|
+
const c = Math.cos(angle);
|
|
583
|
+
const s = Math.sin(angle);
|
|
584
|
+
return new Mat4x4([
|
|
585
|
+
1, 0, 0, 0,
|
|
586
|
+
0, 1, 0, 0,
|
|
587
|
+
0, 0, c, s,
|
|
588
|
+
0, 0, -s, c
|
|
589
|
+
]);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Create rotation matrix from plane name and angle
|
|
594
|
+
* @param {string} plane - One of 'XY', 'XZ', 'YZ', 'XW', 'YW', 'ZW'
|
|
595
|
+
* @param {number} angle - Rotation angle in radians
|
|
596
|
+
* @returns {Mat4x4}
|
|
597
|
+
*/
|
|
598
|
+
static rotation(plane, angle) {
|
|
599
|
+
switch (plane.toUpperCase()) {
|
|
600
|
+
case 'XY': return Mat4x4.rotationXY(angle);
|
|
601
|
+
case 'XZ': return Mat4x4.rotationXZ(angle);
|
|
602
|
+
case 'YZ': return Mat4x4.rotationYZ(angle);
|
|
603
|
+
case 'XW': return Mat4x4.rotationXW(angle);
|
|
604
|
+
case 'YW': return Mat4x4.rotationYW(angle);
|
|
605
|
+
case 'ZW': return Mat4x4.rotationZW(angle);
|
|
606
|
+
default:
|
|
607
|
+
throw new Error(`Invalid rotation plane: ${plane}`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Create combined rotation matrix from all 6 angles
|
|
613
|
+
* Order: XY, XZ, YZ, XW, YW, ZW
|
|
614
|
+
*
|
|
615
|
+
* @param {object} angles - Rotation angles
|
|
616
|
+
* @param {number} [angles.xy=0] - XY plane rotation
|
|
617
|
+
* @param {number} [angles.xz=0] - XZ plane rotation
|
|
618
|
+
* @param {number} [angles.yz=0] - YZ plane rotation
|
|
619
|
+
* @param {number} [angles.xw=0] - XW plane rotation
|
|
620
|
+
* @param {number} [angles.yw=0] - YW plane rotation
|
|
621
|
+
* @param {number} [angles.zw=0] - ZW plane rotation
|
|
622
|
+
* @returns {Mat4x4}
|
|
623
|
+
*/
|
|
624
|
+
static rotationFromAngles(angles) {
|
|
625
|
+
let result = Mat4x4.identity();
|
|
626
|
+
|
|
627
|
+
if (angles.xy) result = result.multiply(Mat4x4.rotationXY(angles.xy));
|
|
628
|
+
if (angles.xz) result = result.multiply(Mat4x4.rotationXZ(angles.xz));
|
|
629
|
+
if (angles.yz) result = result.multiply(Mat4x4.rotationYZ(angles.yz));
|
|
630
|
+
if (angles.xw) result = result.multiply(Mat4x4.rotationXW(angles.xw));
|
|
631
|
+
if (angles.yw) result = result.multiply(Mat4x4.rotationYW(angles.yw));
|
|
632
|
+
if (angles.zw) result = result.multiply(Mat4x4.rotationZW(angles.zw));
|
|
633
|
+
|
|
634
|
+
return result;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Create rotation matrix from parameter format (rot4dXY, rot4dXZ, etc.)
|
|
639
|
+
* @param {object} params - Parameters object
|
|
640
|
+
* @returns {Mat4x4}
|
|
641
|
+
*/
|
|
642
|
+
static rotationFromParameters(params) {
|
|
643
|
+
return Mat4x4.rotationFromAngles({
|
|
644
|
+
xy: params.rot4dXY || 0,
|
|
645
|
+
xz: params.rot4dXZ || 0,
|
|
646
|
+
yz: params.rot4dYZ || 0,
|
|
647
|
+
xw: params.rot4dXW || 0,
|
|
648
|
+
yw: params.rot4dYW || 0,
|
|
649
|
+
zw: params.rot4dZW || 0
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// ========== OTHER TRANSFORMATIONS ==========
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Create uniform scale matrix
|
|
657
|
+
* @param {number} s - Scale factor
|
|
658
|
+
* @returns {Mat4x4}
|
|
659
|
+
*/
|
|
660
|
+
static uniformScale(s) {
|
|
661
|
+
return new Mat4x4([
|
|
662
|
+
s, 0, 0, 0,
|
|
663
|
+
0, s, 0, 0,
|
|
664
|
+
0, 0, s, 0,
|
|
665
|
+
0, 0, 0, s
|
|
666
|
+
]);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Create non-uniform scale matrix
|
|
671
|
+
* @param {number} sx
|
|
672
|
+
* @param {number} sy
|
|
673
|
+
* @param {number} sz
|
|
674
|
+
* @param {number} sw
|
|
675
|
+
* @returns {Mat4x4}
|
|
676
|
+
*/
|
|
677
|
+
static scale(sx, sy, sz, sw = 1) {
|
|
678
|
+
return new Mat4x4([
|
|
679
|
+
sx, 0, 0, 0,
|
|
680
|
+
0, sy, 0, 0,
|
|
681
|
+
0, 0, sz, 0,
|
|
682
|
+
0, 0, 0, sw
|
|
683
|
+
]);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Create translation matrix (affine, in 5D homogeneous coordinates conceptually)
|
|
688
|
+
* Note: For 4D translation, we'd need 5x5 matrices
|
|
689
|
+
* This creates a shear that approximates translation for small displacements
|
|
690
|
+
* @param {number} tx
|
|
691
|
+
* @param {number} ty
|
|
692
|
+
* @param {number} tz
|
|
693
|
+
* @param {number} tw
|
|
694
|
+
* @returns {Mat4x4}
|
|
695
|
+
*/
|
|
696
|
+
static translation(tx, ty, tz, tw = 0) {
|
|
697
|
+
// For true 4D translation, you need 5D homogeneous coordinates
|
|
698
|
+
// This is a placeholder that adds the translation to the W column
|
|
699
|
+
return new Mat4x4([
|
|
700
|
+
1, 0, 0, 0,
|
|
701
|
+
0, 1, 0, 0,
|
|
702
|
+
0, 0, 1, 0,
|
|
703
|
+
tx, ty, tz, 1 + tw
|
|
704
|
+
]);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
export default Mat4x4;
|