hypercube-compute 2.0.0
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/LICENSE +21 -0
- package/README.md +140 -0
- package/demo/index.html +78 -0
- package/demo/package-lock.json +1016 -0
- package/demo/package.json +15 -0
- package/demo/src/main.ts +153 -0
- package/demo/vite.config.ts +9 -0
- package/dist/index.d.mts +321 -0
- package/dist/index.d.ts +321 -0
- package/dist/index.js +1392 -0
- package/dist/index.mjs +1351 -0
- package/docs/assets/index-BLyglqQr.js +1 -0
- package/docs/index.html +78 -0
- package/package.json +29 -0
- package/src/Triade.ts +45 -0
- package/src/addons/ocean-simulation/OceanEngine.ts +208 -0
- package/src/addons/ocean-simulation/OceanSimulatorAddon.ts +145 -0
- package/src/addons/ocean-simulation/OceanWebGLRenderer.ts +258 -0
- package/src/addons/ocean-simulation/OceanWorld.ts +280 -0
- package/src/core/TriadeCubeV2.ts +58 -0
- package/src/core/TriadeGrid.ts +119 -0
- package/src/core/TriadeMasterBuffer.ts +37 -0
- package/src/engines/AerodynamicsEngine.ts +134 -0
- package/src/engines/EcosystemEngineO1.ts +73 -0
- package/src/engines/GameOfLifeEngine.ts +61 -0
- package/src/engines/HeatmapEngine.ts +60 -0
- package/src/engines/ITriadeEngine.ts +29 -0
- package/src/index.ts +26 -0
- package/src/io/CanvasAdapter.ts +41 -0
- package/src/io/WebGLAdapter.ts +129 -0
- package/src/templates/BlankEngine.ts +48 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
export class WebGLAdapter {
|
|
2
|
+
private gl: WebGL2RenderingContext;
|
|
3
|
+
private texture: WebGLTexture;
|
|
4
|
+
private program: WebGLProgram;
|
|
5
|
+
public readonly mapSize: number;
|
|
6
|
+
|
|
7
|
+
constructor(canvas: HTMLCanvasElement, mapSize: number) {
|
|
8
|
+
this.mapSize = mapSize;
|
|
9
|
+
const gl = canvas.getContext('webgl2');
|
|
10
|
+
if (!gl) {
|
|
11
|
+
throw new Error("WebGL2 n'est pas supporté par ce navigateur.");
|
|
12
|
+
}
|
|
13
|
+
this.gl = gl;
|
|
14
|
+
|
|
15
|
+
// --- SHADERS ---
|
|
16
|
+
// Vertex Shader : quad simple couvrant tout le canvas
|
|
17
|
+
const vsSource = `#version 300 es
|
|
18
|
+
in vec2 a_position;
|
|
19
|
+
out vec2 v_uv;
|
|
20
|
+
void main() {
|
|
21
|
+
v_uv = a_position * 0.5 + 0.5; // conversion -1,1 vers 0,1
|
|
22
|
+
v_uv.y = 1.0 - v_uv.y; // Flip Y
|
|
23
|
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
24
|
+
}`;
|
|
25
|
+
|
|
26
|
+
// Fragment Shader : Lit la FloatTexture et applique un gradient "Heatmap"
|
|
27
|
+
const fsSource = `#version 300 es
|
|
28
|
+
precision highp float;
|
|
29
|
+
precision highp sampler2D;
|
|
30
|
+
|
|
31
|
+
in vec2 v_uv;
|
|
32
|
+
uniform sampler2D u_tensor;
|
|
33
|
+
out vec4 outColor;
|
|
34
|
+
|
|
35
|
+
// Palette simple: froid (bleu) -> chaud (rouge)
|
|
36
|
+
vec3 heatMap(float t) {
|
|
37
|
+
return clamp(vec3(1.5*t, 2.0*t - 0.5, 0.5 - t*1.5), 0.0, 1.0);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
void main() {
|
|
41
|
+
// Lecture du Float32Array exact depuis la VRAM Triade
|
|
42
|
+
float val = texture(u_tensor, v_uv).r;
|
|
43
|
+
|
|
44
|
+
// Affichage avec la palette
|
|
45
|
+
vec3 color = mix(vec3(0.05, 0.07, 0.1), vec3(0.0, 0.8, 1.0), clamp(val, 0.0, 1.0)); // Custom Cyan/Dark mapping
|
|
46
|
+
if (val > 1.0) color = vec3(1.0, 1.0, 1.0); // Saturation
|
|
47
|
+
|
|
48
|
+
outColor = vec4(color, 1.0);
|
|
49
|
+
}`;
|
|
50
|
+
|
|
51
|
+
this.program = this.createProgram(vsSource, fsSource);
|
|
52
|
+
this.gl.useProgram(this.program);
|
|
53
|
+
|
|
54
|
+
// --- QUAD GEOMETRY ---
|
|
55
|
+
const positionBuffer = this.gl.createBuffer();
|
|
56
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, positionBuffer);
|
|
57
|
+
const positions = new Float32Array([
|
|
58
|
+
-1, -1, 1, -1, -1, 1,
|
|
59
|
+
-1, 1, 1, -1, 1, 1,
|
|
60
|
+
]);
|
|
61
|
+
this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
|
|
62
|
+
|
|
63
|
+
const posLoc = this.gl.getAttribLocation(this.program, "a_position");
|
|
64
|
+
this.gl.enableVertexAttribArray(posLoc);
|
|
65
|
+
this.gl.vertexAttribPointer(posLoc, 2, this.gl.FLOAT, false, 0, 0);
|
|
66
|
+
|
|
67
|
+
// --- FLOAT TEXTURE O(1) BINDING ---
|
|
68
|
+
// Extension obligatoire pour les textures en virgule flottante
|
|
69
|
+
this.gl.getExtension("EXT_color_buffer_float");
|
|
70
|
+
this.gl.getExtension("OES_texture_float_linear");
|
|
71
|
+
|
|
72
|
+
this.texture = this.gl.createTexture()!;
|
|
73
|
+
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
|
|
74
|
+
|
|
75
|
+
// Configuration pour ne pas flouter ou filtrer (Rendu data brut)
|
|
76
|
+
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
|
|
77
|
+
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
|
|
78
|
+
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
|
|
79
|
+
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
|
|
80
|
+
|
|
81
|
+
// Alloue la texture Float32 en une seule passe sur la GPU
|
|
82
|
+
this.gl.texImage2D(
|
|
83
|
+
this.gl.TEXTURE_2D, 0, this.gl.R32F,
|
|
84
|
+
mapSize, mapSize, 0,
|
|
85
|
+
this.gl.RED, this.gl.FLOAT, null
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Propulse la Face Mémoire Triade directement dans la VRAM GPU.
|
|
91
|
+
* C'est l'opération la plus rapide sur navigateur (O(1) Data Upload).
|
|
92
|
+
*/
|
|
93
|
+
public renderFaceToWebGL(faceData: Float32Array) {
|
|
94
|
+
this.gl.useProgram(this.program);
|
|
95
|
+
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
|
|
96
|
+
|
|
97
|
+
// UPLOAD GPU DIRECT : Push du Float32Array vers le WebGL Shader
|
|
98
|
+
this.gl.texSubImage2D(
|
|
99
|
+
this.gl.TEXTURE_2D, 0, 0, 0,
|
|
100
|
+
this.mapSize, this.mapSize,
|
|
101
|
+
this.gl.RED, this.gl.FLOAT, faceData
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// Dessine la Frame
|
|
105
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private createProgram(vsSource: string, fsSource: string): WebGLProgram {
|
|
109
|
+
const vs = this.gl.createShader(this.gl.VERTEX_SHADER)!;
|
|
110
|
+
this.gl.shaderSource(vs, vsSource);
|
|
111
|
+
this.gl.compileShader(vs);
|
|
112
|
+
|
|
113
|
+
const fs = this.gl.createShader(this.gl.FRAGMENT_SHADER)!;
|
|
114
|
+
this.gl.shaderSource(fs, fsSource);
|
|
115
|
+
this.gl.compileShader(fs);
|
|
116
|
+
|
|
117
|
+
const prog = this.gl.createProgram()!;
|
|
118
|
+
this.gl.attachShader(prog, vs);
|
|
119
|
+
this.gl.attachShader(prog, fs);
|
|
120
|
+
this.gl.linkProgram(prog);
|
|
121
|
+
|
|
122
|
+
if (!this.gl.getProgramParameter(prog, this.gl.LINK_STATUS)) {
|
|
123
|
+
console.error(this.gl.getProgramInfoLog(prog));
|
|
124
|
+
throw new Error("Erreur de compilation WebGL");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return prog;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ITriadeEngine, FlatTensorView } from '../engines/ITriadeEngine';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @AI_BOILERPLATE This is the standard template for creating a new O(1) physics/math engine.
|
|
5
|
+
* Rename the class and implement the specific logic inside compute().
|
|
6
|
+
*/
|
|
7
|
+
export class BlankEngine implements ITriadeEngine {
|
|
8
|
+
get name(): string {
|
|
9
|
+
return 'My-Blank-Engine'; // Always use explicit semantic naming
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Called at every simulation tick.
|
|
14
|
+
* @param faces Array of Float32Array (VRAM Memory mapping of the TriadeCube)
|
|
15
|
+
* Face[0] is typically the main Output buffer or State A
|
|
16
|
+
* Face[1] is typically the Secondary buffer or State B (Wait/Swap)
|
|
17
|
+
* @param mapSize The N x N resolution of the chunk
|
|
18
|
+
*/
|
|
19
|
+
compute(faces: FlatTensorView[], mapSize: number): void {
|
|
20
|
+
const length = mapSize * mapSize;
|
|
21
|
+
|
|
22
|
+
// --- VERBOSE O(1) ERROR HANDLING CHECK ---
|
|
23
|
+
// Verify we have enough allocated faces to compute our algorithm
|
|
24
|
+
if (faces.length < 2) {
|
|
25
|
+
throw new Error(`[Triade BlankEngine] Insufficient faces. Required 2, but only got ${faces.length}. Ensure your Cube allocation specifies numFaces >= 2.`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const faceIn = faces[0];
|
|
29
|
+
const faceOut = faces[1];
|
|
30
|
+
|
|
31
|
+
// --- THE HOT LOOP (Zero Allocation Zone) ---
|
|
32
|
+
// Avoid 'map', 'forEach', or 'new Object' creation in this loop!
|
|
33
|
+
for (let i = 0; i < length; i++) {
|
|
34
|
+
// Read
|
|
35
|
+
const state = faceIn[i];
|
|
36
|
+
|
|
37
|
+
// DO MATH... (Example: cellular logic or fluid propagation)
|
|
38
|
+
let nextState = state;
|
|
39
|
+
|
|
40
|
+
// Write to the output buffer
|
|
41
|
+
faceOut[i] = nextState;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// --- BUFFER SWAP ---
|
|
45
|
+
// Copy the computed state back to the main reading face (if required by algorithm)
|
|
46
|
+
faceIn.set(faceOut);
|
|
47
|
+
}
|
|
48
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"outDir": "./dist",
|
|
13
|
+
"lib": [
|
|
14
|
+
"ES2022",
|
|
15
|
+
"DOM",
|
|
16
|
+
"DOM.Iterable"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"include": [
|
|
20
|
+
"src/**/*"
|
|
21
|
+
],
|
|
22
|
+
"exclude": [
|
|
23
|
+
"node_modules",
|
|
24
|
+
"dist"
|
|
25
|
+
]
|
|
26
|
+
}
|