@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,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection - 4D to 3D Projection Functions
|
|
3
|
+
*
|
|
4
|
+
* Various methods for projecting 4-dimensional geometry
|
|
5
|
+
* into 3-dimensional space for rendering.
|
|
6
|
+
*
|
|
7
|
+
* Projection Types:
|
|
8
|
+
* - Perspective: P = v.xyz / (d - v.w), creates depth-like 4D effect
|
|
9
|
+
* - Stereographic: P = v.xyz / (1 - v.w), conformal (preserves angles)
|
|
10
|
+
* - Orthographic: P = v.xyz, simple parallel projection
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const projected = Projection.perspective(vec4, 2.0);
|
|
14
|
+
* const conformal = Projection.stereographic(vec4);
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { Vec4 } from './Vec4.js';
|
|
18
|
+
|
|
19
|
+
const DEFAULT_EPSILON = 1e-5;
|
|
20
|
+
|
|
21
|
+
function clampDenominator(value, epsilon) {
|
|
22
|
+
if (Math.abs(value) < epsilon) {
|
|
23
|
+
return value >= 0 ? epsilon : -epsilon;
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class Projection {
|
|
29
|
+
/**
|
|
30
|
+
* Perspective projection from 4D to 3D
|
|
31
|
+
*
|
|
32
|
+
* Projects by dividing XYZ by (d - W), where d is the distance
|
|
33
|
+
* from the 4D camera to the projection hyperplane.
|
|
34
|
+
*
|
|
35
|
+
* Formula: P = (x, y, z) / (d - w)
|
|
36
|
+
*
|
|
37
|
+
* @param {Vec4} v - 4D point
|
|
38
|
+
* @param {number} d - Distance parameter (typically 1.5-5)
|
|
39
|
+
* @returns {Vec4} Projected point (w=0)
|
|
40
|
+
*/
|
|
41
|
+
static perspective(v, d = 2, options = {}) {
|
|
42
|
+
if (typeof d === 'object') {
|
|
43
|
+
options = d;
|
|
44
|
+
d = options.d ?? 2;
|
|
45
|
+
}
|
|
46
|
+
const epsilon = options.epsilon ?? DEFAULT_EPSILON;
|
|
47
|
+
const denom = clampDenominator(d - v.w, epsilon);
|
|
48
|
+
const scale = 1 / denom;
|
|
49
|
+
return new Vec4(v.x * scale, v.y * scale, v.z * scale, 0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Stereographic projection from 4D to 3D
|
|
54
|
+
*
|
|
55
|
+
* Projects from the 4D hypersphere to 3D space.
|
|
56
|
+
* This is conformal (preserves angles locally).
|
|
57
|
+
*
|
|
58
|
+
* Formula: P = (x, y, z) / (1 - w)
|
|
59
|
+
*
|
|
60
|
+
* The projection point is at (0, 0, 0, 1) - the "north pole"
|
|
61
|
+
*
|
|
62
|
+
* @param {Vec4} v - 4D point (ideally on unit hypersphere)
|
|
63
|
+
* @returns {Vec4} Projected point (w=0)
|
|
64
|
+
*/
|
|
65
|
+
static stereographic(v, options = {}) {
|
|
66
|
+
const epsilon = options.epsilon ?? DEFAULT_EPSILON;
|
|
67
|
+
const denom = clampDenominator(1 - v.w, epsilon);
|
|
68
|
+
const scale = 1 / denom;
|
|
69
|
+
return new Vec4(v.x * scale, v.y * scale, v.z * scale, 0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Inverse stereographic projection (3D to 4D hypersphere)
|
|
74
|
+
*
|
|
75
|
+
* Maps a 3D point back onto the unit 4D hypersphere
|
|
76
|
+
*
|
|
77
|
+
* @param {Vec4} v - 3D point (w component ignored)
|
|
78
|
+
* @returns {Vec4} Point on unit hypersphere
|
|
79
|
+
*/
|
|
80
|
+
static stereographicInverse(v) {
|
|
81
|
+
const r2 = v.x * v.x + v.y * v.y + v.z * v.z;
|
|
82
|
+
const denom = 1 + r2;
|
|
83
|
+
return new Vec4(
|
|
84
|
+
(2 * v.x) / denom,
|
|
85
|
+
(2 * v.y) / denom,
|
|
86
|
+
(2 * v.z) / denom,
|
|
87
|
+
(r2 - 1) / denom
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Orthographic projection from 4D to 3D
|
|
93
|
+
*
|
|
94
|
+
* Simply drops the W component.
|
|
95
|
+
* Parallel projection - no perspective distortion.
|
|
96
|
+
*
|
|
97
|
+
* @param {Vec4} v - 4D point
|
|
98
|
+
* @returns {Vec4} Projected point (w=0)
|
|
99
|
+
*/
|
|
100
|
+
static orthographic(v) {
|
|
101
|
+
return new Vec4(v.x, v.y, v.z, 0);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Oblique projection from 4D to 3D
|
|
106
|
+
*
|
|
107
|
+
* Projects with W component adding a sheared offset to XYZ.
|
|
108
|
+
* Creates a cavalier or cabinet-like projection effect.
|
|
109
|
+
*
|
|
110
|
+
* @param {Vec4} v - 4D point
|
|
111
|
+
* @param {number} shearX - X shear factor for W
|
|
112
|
+
* @param {number} shearY - Y shear factor for W
|
|
113
|
+
* @param {number} shearZ - Z shear factor for W
|
|
114
|
+
* @returns {Vec4} Projected point (w=0)
|
|
115
|
+
*/
|
|
116
|
+
static oblique(v, shearX = 0.5, shearY = 0.5, shearZ = 0) {
|
|
117
|
+
return new Vec4(
|
|
118
|
+
v.x + shearX * v.w,
|
|
119
|
+
v.y + shearY * v.w,
|
|
120
|
+
v.z + shearZ * v.w,
|
|
121
|
+
0
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Project array of Vec4s using perspective projection
|
|
127
|
+
* @param {Vec4[]} vectors
|
|
128
|
+
* @param {number} d
|
|
129
|
+
* @returns {Vec4[]}
|
|
130
|
+
*/
|
|
131
|
+
static perspectiveArray(vectors, d = 2, options = {}) {
|
|
132
|
+
return vectors.map(v => Projection.perspective(v, d, options));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Project array of Vec4s using stereographic projection
|
|
137
|
+
* @param {Vec4[]} vectors
|
|
138
|
+
* @returns {Vec4[]}
|
|
139
|
+
*/
|
|
140
|
+
static stereographicArray(vectors, options = {}) {
|
|
141
|
+
return vectors.map(v => Projection.stereographic(v, options));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Project array of Vec4s using orthographic projection
|
|
146
|
+
* @param {Vec4[]} vectors
|
|
147
|
+
* @returns {Vec4[]}
|
|
148
|
+
*/
|
|
149
|
+
static orthographicArray(vectors) {
|
|
150
|
+
return vectors.map(v => Projection.orthographic(v));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Project packed Float32Array using perspective projection
|
|
155
|
+
*
|
|
156
|
+
* @param {Float32Array} packed - Packed vec4s (x,y,z,w,...)
|
|
157
|
+
* @param {number} d - Distance parameter
|
|
158
|
+
* @param {Float32Array} [output] - Optional output buffer
|
|
159
|
+
* @returns {Float32Array} Projected points (as vec3s: x,y,z,...)
|
|
160
|
+
*/
|
|
161
|
+
static perspectivePacked(packed, d = 2, output = null, options = {}) {
|
|
162
|
+
const count = packed.length / 4;
|
|
163
|
+
const result = output || new Float32Array(count * 3);
|
|
164
|
+
const epsilon = options.epsilon ?? DEFAULT_EPSILON;
|
|
165
|
+
|
|
166
|
+
for (let i = 0; i < count; i++) {
|
|
167
|
+
const srcIdx = i * 4;
|
|
168
|
+
const dstIdx = i * 3;
|
|
169
|
+
|
|
170
|
+
const x = packed[srcIdx];
|
|
171
|
+
const y = packed[srcIdx + 1];
|
|
172
|
+
const z = packed[srcIdx + 2];
|
|
173
|
+
const w = packed[srcIdx + 3];
|
|
174
|
+
|
|
175
|
+
const denom = clampDenominator(d - w, epsilon);
|
|
176
|
+
const scale = 1 / denom;
|
|
177
|
+
result[dstIdx] = x * scale;
|
|
178
|
+
result[dstIdx + 1] = y * scale;
|
|
179
|
+
result[dstIdx + 2] = z * scale;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return result;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Project using named projection type
|
|
187
|
+
* @param {Vec4} v - 4D point
|
|
188
|
+
* @param {string} type - 'perspective', 'stereographic', 'orthographic', 'oblique'
|
|
189
|
+
* @param {object} options - Type-specific options
|
|
190
|
+
* @returns {Vec4}
|
|
191
|
+
*/
|
|
192
|
+
static project(v, type, options = {}) {
|
|
193
|
+
switch (type.toLowerCase()) {
|
|
194
|
+
case 'perspective':
|
|
195
|
+
return Projection.perspective(v, options.d || 2, options);
|
|
196
|
+
case 'stereographic':
|
|
197
|
+
return Projection.stereographic(v, options);
|
|
198
|
+
case 'orthographic':
|
|
199
|
+
return Projection.orthographic(v);
|
|
200
|
+
case 'oblique':
|
|
201
|
+
return Projection.oblique(v, options.shearX || 0.5, options.shearY || 0.5, options.shearZ || 0);
|
|
202
|
+
default:
|
|
203
|
+
throw new Error(`Unknown projection type: ${type}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Create a projection function with pre-set options
|
|
209
|
+
* @param {string} type - Projection type
|
|
210
|
+
* @param {object} options - Type-specific options
|
|
211
|
+
* @returns {function(Vec4): Vec4}
|
|
212
|
+
*/
|
|
213
|
+
static createProjector(type, options = {}) {
|
|
214
|
+
return (v) => Projection.project(v, type, options);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* SliceProjection - Cross-sectional slicing of 4D objects
|
|
220
|
+
*
|
|
221
|
+
* Instead of projecting, take a 3D cross-section of 4D geometry
|
|
222
|
+
* at a specific W value.
|
|
223
|
+
*/
|
|
224
|
+
export class SliceProjection {
|
|
225
|
+
/**
|
|
226
|
+
* Check if a 4D point is within slice tolerance of W plane
|
|
227
|
+
* @param {Vec4} v - 4D point
|
|
228
|
+
* @param {number} wPlane - W value of slice plane
|
|
229
|
+
* @param {number} tolerance - Slice thickness
|
|
230
|
+
* @returns {boolean}
|
|
231
|
+
*/
|
|
232
|
+
static isInSlice(v, wPlane = 0, tolerance = 0.1) {
|
|
233
|
+
return Math.abs(v.w - wPlane) <= tolerance;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Interpolate edge crossing through W slice plane
|
|
238
|
+
*
|
|
239
|
+
* Given two points on opposite sides of the slice plane,
|
|
240
|
+
* find where the edge crosses the plane.
|
|
241
|
+
*
|
|
242
|
+
* @param {Vec4} v1 - First point
|
|
243
|
+
* @param {Vec4} v2 - Second point
|
|
244
|
+
* @param {number} wPlane - W value of slice plane
|
|
245
|
+
* @returns {Vec4|null} Intersection point or null if no crossing
|
|
246
|
+
*/
|
|
247
|
+
static edgeCrossing(v1, v2, wPlane = 0) {
|
|
248
|
+
const w1 = v1.w - wPlane;
|
|
249
|
+
const w2 = v2.w - wPlane;
|
|
250
|
+
|
|
251
|
+
// Check if edge crosses plane
|
|
252
|
+
if (w1 * w2 > 0) {
|
|
253
|
+
return null; // Both on same side
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (Math.abs(w2 - w1) < 1e-10) {
|
|
257
|
+
return null; // Edge parallel to plane
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Linear interpolation to find crossing
|
|
261
|
+
const t = -w1 / (w2 - w1);
|
|
262
|
+
return v1.lerp(v2, t);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Filter points within slice tolerance
|
|
267
|
+
* @param {Vec4[]} points
|
|
268
|
+
* @param {number} wPlane
|
|
269
|
+
* @param {number} tolerance
|
|
270
|
+
* @returns {Vec4[]}
|
|
271
|
+
*/
|
|
272
|
+
static filterSlice(points, wPlane = 0, tolerance = 0.1) {
|
|
273
|
+
return points.filter(p => SliceProjection.isInSlice(p, wPlane, tolerance));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Create slice intersection of edges with W plane
|
|
278
|
+
*
|
|
279
|
+
* @param {Vec4[]} vertices - 4D vertices
|
|
280
|
+
* @param {number[][]} edges - Edge indices [[i, j], ...]
|
|
281
|
+
* @param {number} wPlane - W value of slice plane
|
|
282
|
+
* @returns {Vec4[]} Intersection points
|
|
283
|
+
*/
|
|
284
|
+
static sliceEdges(vertices, edges, wPlane = 0) {
|
|
285
|
+
const intersections = [];
|
|
286
|
+
|
|
287
|
+
for (const [i, j] of edges) {
|
|
288
|
+
const crossing = SliceProjection.edgeCrossing(vertices[i], vertices[j], wPlane);
|
|
289
|
+
if (crossing) {
|
|
290
|
+
intersections.push(crossing);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return intersections;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* AnimatedProjection - Time-varying projections
|
|
300
|
+
*/
|
|
301
|
+
export class AnimatedProjection {
|
|
302
|
+
/**
|
|
303
|
+
* Create an animated perspective projection
|
|
304
|
+
* D value oscillates between min and max
|
|
305
|
+
*
|
|
306
|
+
* @param {number} minD - Minimum D value
|
|
307
|
+
* @param {number} maxD - Maximum D value
|
|
308
|
+
* @param {number} period - Period in seconds
|
|
309
|
+
* @returns {function(Vec4, number): Vec4}
|
|
310
|
+
*/
|
|
311
|
+
static oscillatingPerspective(minD = 1.5, maxD = 4, period = 4) {
|
|
312
|
+
return (v, time) => {
|
|
313
|
+
const t = (Math.sin(time * Math.PI * 2 / period) + 1) / 2;
|
|
314
|
+
const d = minD + t * (maxD - minD);
|
|
315
|
+
return Projection.perspective(v, d);
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Create animated W-slice projection
|
|
321
|
+
* Slice plane oscillates through the 4D object
|
|
322
|
+
*
|
|
323
|
+
* @param {number} minW - Minimum W plane
|
|
324
|
+
* @param {number} maxW - Maximum W plane
|
|
325
|
+
* @param {number} period - Period in seconds
|
|
326
|
+
* @returns {function(Vec4, number): Vec4|null}
|
|
327
|
+
*/
|
|
328
|
+
static oscillatingSlice(minW = -1, maxW = 1, period = 4) {
|
|
329
|
+
const tolerance = 0.15;
|
|
330
|
+
return (v, time) => {
|
|
331
|
+
const t = (Math.sin(time * Math.PI * 2 / period) + 1) / 2;
|
|
332
|
+
const wPlane = minW + t * (maxW - minW);
|
|
333
|
+
if (SliceProjection.isInSlice(v, wPlane, tolerance)) {
|
|
334
|
+
return Projection.orthographic(v);
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export default Projection;
|