@certe/atmos-terrain 0.1.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.
Files changed (60) hide show
  1. package/LICENCE +674 -0
  2. package/README.md +155 -0
  3. package/dist/chunk-key.d.ts +10 -0
  4. package/dist/chunk-key.d.ts.map +1 -0
  5. package/dist/chunk-key.js +27 -0
  6. package/dist/chunk-key.js.map +1 -0
  7. package/dist/chunk.d.ts +36 -0
  8. package/dist/chunk.d.ts.map +1 -0
  9. package/dist/chunk.js +128 -0
  10. package/dist/chunk.js.map +1 -0
  11. package/dist/density-field.d.ts +34 -0
  12. package/dist/density-field.d.ts.map +1 -0
  13. package/dist/density-field.js +68 -0
  14. package/dist/density-field.js.map +1 -0
  15. package/dist/index.d.ts +15 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +22 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lod-chunk.d.ts +20 -0
  20. package/dist/lod-chunk.d.ts.map +1 -0
  21. package/dist/lod-chunk.js +256 -0
  22. package/dist/lod-chunk.js.map +1 -0
  23. package/dist/lod-extract.d.ts +21 -0
  24. package/dist/lod-extract.d.ts.map +1 -0
  25. package/dist/lod-extract.js +178 -0
  26. package/dist/lod-extract.js.map +1 -0
  27. package/dist/marching-cubes-tables.d.ts +28 -0
  28. package/dist/marching-cubes-tables.d.ts.map +1 -0
  29. package/dist/marching-cubes-tables.js +344 -0
  30. package/dist/marching-cubes-tables.js.map +1 -0
  31. package/dist/marching-cubes.d.ts +17 -0
  32. package/dist/marching-cubes.d.ts.map +1 -0
  33. package/dist/marching-cubes.js +200 -0
  34. package/dist/marching-cubes.js.map +1 -0
  35. package/dist/register-builtins.d.ts +2 -0
  36. package/dist/register-builtins.d.ts.map +1 -0
  37. package/dist/register-builtins.js +34 -0
  38. package/dist/register-builtins.js.map +1 -0
  39. package/dist/terrain-editor.d.ts +15 -0
  40. package/dist/terrain-editor.d.ts.map +1 -0
  41. package/dist/terrain-editor.js +85 -0
  42. package/dist/terrain-editor.js.map +1 -0
  43. package/dist/terrain-normals.d.ts +13 -0
  44. package/dist/terrain-normals.d.ts.map +1 -0
  45. package/dist/terrain-normals.js +96 -0
  46. package/dist/terrain-normals.js.map +1 -0
  47. package/dist/terrain-volume.d.ts +42 -0
  48. package/dist/terrain-volume.d.ts.map +1 -0
  49. package/dist/terrain-volume.js +146 -0
  50. package/dist/terrain-volume.js.map +1 -0
  51. package/dist/terrain-world.d.ts +67 -0
  52. package/dist/terrain-world.d.ts.map +1 -0
  53. package/dist/terrain-world.js +344 -0
  54. package/dist/terrain-world.js.map +1 -0
  55. package/dist/types.d.ts +65 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +23 -0
  58. package/dist/types.js.map +1 -0
  59. package/package.json +29 -0
  60. package/src/index.ts +42 -0
@@ -0,0 +1,200 @@
1
+ import { EDGE_TABLE, TRI_TABLE, CORNER_OFFSETS, EDGE_CORNERS } from './marching-cubes-tables.js';
2
+ /** Stride in floats: pos(3) + normal(3) + uv(2) */
3
+ const STRIDE = 8;
4
+ /**
5
+ * Extract an isosurface from a flat density grid using marching cubes.
6
+ *
7
+ * @param densityGrid Flat Float32Array of (size+1)^3 density values,
8
+ * indexed as z*(s+1)*(s+1) + y*(s+1) + x. Positive = air, negative = solid.
9
+ * @param size Number of voxels per axis (grid has size+1 samples per axis).
10
+ * @param voxelSize World-space size of each voxel.
11
+ * @param isoLevel Density threshold (default 0).
12
+ * @param outVertices Pre-allocated vertex buffer (caller-owned).
13
+ * @param outIndices Pre-allocated index buffer (caller-owned).
14
+ * @returns MeshData with counts; vertices have placeholder normals (0,1,0) and triplanar UVs.
15
+ */
16
+ export function extractSurface(densityGrid, size, voxelSize, isoLevel, outVertices, outIndices) {
17
+ const s1 = size + 1;
18
+ const s1s1 = s1 * s1;
19
+ // Edge vertex caches: one index per edge in each direction.
20
+ // X-edges: size edges per row, s1 rows per slice, s1 slices = size * s1 * s1
21
+ // Y-edges: s1 * size * s1
22
+ // Z-edges: s1 * s1 * size
23
+ const xEdge = new Int32Array(size * s1 * s1).fill(-1);
24
+ const yEdge = new Int32Array(s1 * size * s1).fill(-1);
25
+ const zEdge = new Int32Array(s1 * s1 * size).fill(-1);
26
+ let vertCount = 0;
27
+ let idxCount = 0;
28
+ // Scratch for 8 corner densities and 12 edge vertex indices
29
+ const cornerDensity = new Float32Array(8);
30
+ const edgeVerts = new Int32Array(12);
31
+ for (let z = 0; z < size; z++) {
32
+ for (let y = 0; y < size; y++) {
33
+ for (let x = 0; x < size; x++) {
34
+ // Gather 8 corner densities
35
+ let cubeIndex = 0;
36
+ for (let c = 0; c < 8; c++) {
37
+ const co = CORNER_OFFSETS[c];
38
+ const gx = x + co[0];
39
+ const gy = y + co[1];
40
+ const gz = z + co[2];
41
+ const d = densityGrid[gz * s1s1 + gy * s1 + gx];
42
+ cornerDensity[c] = d;
43
+ if (d < isoLevel)
44
+ cubeIndex |= (1 << c);
45
+ }
46
+ const edgeBits = EDGE_TABLE[cubeIndex];
47
+ if (edgeBits === 0)
48
+ continue;
49
+ // For each active edge, compute or retrieve the interpolated vertex
50
+ for (let e = 0; e < 12; e++) {
51
+ if ((edgeBits & (1 << e)) === 0) {
52
+ edgeVerts[e] = -1;
53
+ continue;
54
+ }
55
+ const ec = EDGE_CORNERS[e];
56
+ const c0 = ec[0];
57
+ const c1 = ec[1];
58
+ // Look up in directional cache
59
+ const cached = getCachedEdge(e, x, y, z, s1, size, xEdge, yEdge, zEdge);
60
+ if (cached >= 0) {
61
+ edgeVerts[e] = cached;
62
+ continue;
63
+ }
64
+ // Interpolate
65
+ const d0 = cornerDensity[c0];
66
+ const d1 = cornerDensity[c1];
67
+ const denom = d0 - d1;
68
+ const t = Math.abs(denom) < 1e-10 ? 0.5 : (d0 - isoLevel) / denom;
69
+ const co0 = CORNER_OFFSETS[c0];
70
+ const co1 = CORNER_OFFSETS[c1];
71
+ const px = (x + co0[0] + t * (co1[0] - co0[0])) * voxelSize;
72
+ const py = (y + co0[1] + t * (co1[1] - co0[1])) * voxelSize;
73
+ const pz = (z + co0[2] + t * (co1[2] - co0[2])) * voxelSize;
74
+ // Triplanar UVs (will be replaced by normals pass, using dominant axis)
75
+ const o = vertCount * STRIDE;
76
+ outVertices[o] = px;
77
+ outVertices[o + 1] = py;
78
+ outVertices[o + 2] = pz;
79
+ // Placeholder normal (0, 1, 0) — replaced by terrain-normals pass
80
+ outVertices[o + 3] = 0;
81
+ outVertices[o + 4] = 1;
82
+ outVertices[o + 5] = 0;
83
+ // Triplanar UV placeholder (will be computed after normals)
84
+ outVertices[o + 6] = 0;
85
+ outVertices[o + 7] = 0;
86
+ edgeVerts[e] = vertCount;
87
+ setCachedEdge(e, x, y, z, s1, size, xEdge, yEdge, zEdge, vertCount);
88
+ vertCount++;
89
+ }
90
+ // Emit triangles
91
+ const triBase = cubeIndex * 16;
92
+ for (let t = 0; t < 15; t += 3) {
93
+ const e0 = TRI_TABLE[triBase + t];
94
+ if (e0 === -1)
95
+ break;
96
+ const e1 = TRI_TABLE[triBase + t + 1];
97
+ const e2 = TRI_TABLE[triBase + t + 2];
98
+ outIndices[idxCount++] = edgeVerts[e0];
99
+ outIndices[idxCount++] = edgeVerts[e1];
100
+ outIndices[idxCount++] = edgeVerts[e2];
101
+ }
102
+ }
103
+ }
104
+ }
105
+ return {
106
+ vertices: outVertices,
107
+ indices: outIndices,
108
+ vertexCount: vertCount,
109
+ indexCount: idxCount,
110
+ };
111
+ }
112
+ /** Compute triplanar UVs for vertices based on their normals. */
113
+ export function computeTriplanarUVs(vertices, vertexCount, uvScale = 1) {
114
+ for (let i = 0; i < vertexCount; i++) {
115
+ const o = i * STRIDE;
116
+ const px = vertices[o];
117
+ const py = vertices[o + 1];
118
+ const pz = vertices[o + 2];
119
+ const nx = Math.abs(vertices[o + 3]);
120
+ const ny = Math.abs(vertices[o + 4]);
121
+ const nz = Math.abs(vertices[o + 5]);
122
+ // Choose dominant axis for UV projection
123
+ if (nx >= ny && nx >= nz) {
124
+ // X-dominant: project onto YZ
125
+ vertices[o + 6] = pz * uvScale;
126
+ vertices[o + 7] = py * uvScale;
127
+ }
128
+ else if (ny >= nz) {
129
+ // Y-dominant: project onto XZ
130
+ vertices[o + 6] = px * uvScale;
131
+ vertices[o + 7] = pz * uvScale;
132
+ }
133
+ else {
134
+ // Z-dominant: project onto XY
135
+ vertices[o + 6] = px * uvScale;
136
+ vertices[o + 7] = py * uvScale;
137
+ }
138
+ }
139
+ }
140
+ // --- Edge cache helpers ---
141
+ // Edges are categorized by direction:
142
+ // Edges 0,2,4,6 → X direction (along x-axis)
143
+ // Edges 8,9,10,11 → Y direction (along y-axis)
144
+ // Edges 1,3,5,7 → Z direction (along z-axis)
145
+ // (Derived from which axis differs between the two corners.)
146
+ function edgeDirection(e) {
147
+ // X-edges: 0(0→1), 2(3→2), 4(4→5), 6(7→6) — x changes
148
+ // Z-edges: 1(1→2), 3(0→3), 5(5→6), 7(4→7) — z changes
149
+ // Y-edges: 8(0→4), 9(1→5), 10(2→6), 11(3→7) — y changes
150
+ if (e === 0 || e === 2 || e === 4 || e === 6)
151
+ return 0; // X
152
+ if (e === 1 || e === 3 || e === 5 || e === 7)
153
+ return 2; // Z
154
+ return 1; // Y (8,9,10,11)
155
+ }
156
+ /**
157
+ * Return the canonical grid origin of an edge: the endpoint with the
158
+ * smaller coordinate value along the edge's direction.
159
+ * This ensures two adjacent cubes sharing the same physical edge
160
+ * always compute the same cache key.
161
+ */
162
+ function edgeOrigin(e, x, y, z) {
163
+ const ec = EDGE_CORNERS[e];
164
+ const co0 = CORNER_OFFSETS[ec[0]];
165
+ const co1 = CORNER_OFFSETS[ec[1]];
166
+ const dir = edgeDirection(e);
167
+ // Pick the corner with the lower value along the edge direction
168
+ const co = co0[dir] <= co1[dir] ? co0 : co1;
169
+ return [x + co[0], y + co[1], z + co[2]];
170
+ }
171
+ function getCachedEdge(e, x, y, z, s1, size, xEdge, yEdge, zEdge) {
172
+ const [ox, oy, oz] = edgeOrigin(e, x, y, z);
173
+ const dir = edgeDirection(e);
174
+ if (dir === 0) {
175
+ // X-edge: index = oz * s1 * size + oy * size + ox
176
+ return xEdge[oz * s1 * size + oy * size + ox];
177
+ }
178
+ else if (dir === 1) {
179
+ // Y-edge: index = oz * s1 * s1 + oy * s1 + ox (but oy ranges [0..size-1])
180
+ return yEdge[oz * size * s1 + oy * s1 + ox];
181
+ }
182
+ else {
183
+ // Z-edge: index = oz * s1 * s1 + oy * s1 + ox
184
+ return zEdge[oz * s1 * s1 + oy * s1 + ox];
185
+ }
186
+ }
187
+ function setCachedEdge(e, x, y, z, s1, size, xEdge, yEdge, zEdge, vertexIndex) {
188
+ const [ox, oy, oz] = edgeOrigin(e, x, y, z);
189
+ const dir = edgeDirection(e);
190
+ if (dir === 0) {
191
+ xEdge[oz * s1 * size + oy * size + ox] = vertexIndex;
192
+ }
193
+ else if (dir === 1) {
194
+ yEdge[oz * size * s1 + oy * s1 + ox] = vertexIndex;
195
+ }
196
+ else {
197
+ zEdge[oz * s1 * s1 + oy * s1 + ox] = vertexIndex;
198
+ }
199
+ }
200
+ //# sourceMappingURL=marching-cubes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"marching-cubes.js","sourceRoot":"","sources":["../src/marching-cubes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function registerTerrainBuiltins(): void;
2
+ //# sourceMappingURL=register-builtins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-builtins.d.ts","sourceRoot":"","sources":["../src/register-builtins.ts"],"names":[],"mappings":"AAIA,wBAAgB,uBAAuB,IAAI,IAAI,CA8B9C"}
@@ -0,0 +1,34 @@
1
+ import { registerComponent } from '@certe/atmos-core';
2
+ import { TerrainVolume } from './terrain-volume.js';
3
+ import { TerrainWorld } from './terrain-world.js';
4
+ export function registerTerrainBuiltins() {
5
+ registerComponent(TerrainVolume, {
6
+ name: 'TerrainVolume',
7
+ properties: [
8
+ { key: 'chunksX', type: 'number', min: 1, max: 32, step: 1 },
9
+ { key: 'chunksY', type: 'number', min: 1, max: 32, step: 1 },
10
+ { key: 'chunksZ', type: 'number', min: 1, max: 32, step: 1 },
11
+ { key: 'config.chunkSize', type: 'number', min: 4, max: 64, step: 1 },
12
+ { key: 'config.voxelSize', type: 'number', min: 0.1, max: 10, step: 0.1 },
13
+ { key: 'config.isoLevel', type: 'number', min: -10, max: 10, step: 0.01 },
14
+ { key: 'config.smoothNormals', type: 'boolean' },
15
+ ],
16
+ });
17
+ registerComponent(TerrainWorld, {
18
+ name: 'TerrainWorld',
19
+ properties: [
20
+ { key: 'loadRadius', type: 'number', min: 1, max: 16, step: 1 },
21
+ { key: 'unloadRadius', type: 'number', min: 2, max: 24, step: 1 },
22
+ { key: 'maxBuildsPerFrame', type: 'number', min: 1, max: 16, step: 1 },
23
+ { key: 'buildBudgetMs', type: 'number', min: 1, max: 32, step: 1 },
24
+ { key: 'config.chunkSize', type: 'number', min: 4, max: 64, step: 1 },
25
+ { key: 'config.voxelSize', type: 'number', min: 0.1, max: 10, step: 0.1 },
26
+ { key: 'config.isoLevel', type: 'number', min: -10, max: 10, step: 0.01 },
27
+ { key: 'config.smoothNormals', type: 'boolean' },
28
+ { key: 'cameraTarget', type: 'gameObjectRef' },
29
+ { key: 'lodConfig.lodDistances.0', type: 'number', min: 1, max: 16, step: 1 },
30
+ { key: 'lodConfig.lodDistances.1', type: 'number', min: 2, max: 24, step: 1 },
31
+ ],
32
+ });
33
+ }
34
+ //# sourceMappingURL=register-builtins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-builtins.js","sourceRoot":"","sources":["../src/register-builtins.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { TerrainChunk } from './chunk.js';
2
+ import type { TerrainEdit } from './types.js';
3
+ /**
4
+ * Apply a terrain edit to a set of chunks.
5
+ * Modifies density grid values in affected chunks and returns
6
+ * the set of dirty chunk keys that need re-meshing.
7
+ *
8
+ * @param edit The edit operation to apply
9
+ * @param chunks Map of chunk key → TerrainChunk
10
+ * @param chunkSize Voxels per chunk axis
11
+ * @param voxelSize World-space size of each voxel
12
+ * @returns Set of chunk keys whose density grids were modified
13
+ */
14
+ export declare function applyEdit(edit: TerrainEdit, chunks: Map<number, TerrainChunk>, chunkSize: number, voxelSize: number): Set<number>;
15
+ //# sourceMappingURL=terrain-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain-editor.d.ts","sourceRoot":"","sources":["../src/terrain-editor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,GAAG,CAAC,MAAM,CAAC,CAmDb"}
@@ -0,0 +1,85 @@
1
+ import { chunkKey } from './chunk-key.js';
2
+ import { BrushShape } from './types.js';
3
+ /**
4
+ * Apply a terrain edit to a set of chunks.
5
+ * Modifies density grid values in affected chunks and returns
6
+ * the set of dirty chunk keys that need re-meshing.
7
+ *
8
+ * @param edit The edit operation to apply
9
+ * @param chunks Map of chunk key → TerrainChunk
10
+ * @param chunkSize Voxels per chunk axis
11
+ * @param voxelSize World-space size of each voxel
12
+ * @returns Set of chunk keys whose density grids were modified
13
+ */
14
+ export function applyEdit(edit, chunks, chunkSize, voxelSize) {
15
+ const dirty = new Set();
16
+ const chunkWorldSize = chunkSize * voxelSize;
17
+ const s1 = chunkSize + 1;
18
+ const s1s1 = s1 * s1;
19
+ // Determine which chunks the brush can affect
20
+ const minCX = Math.floor((edit.x - edit.radius) / chunkWorldSize);
21
+ const maxCX = Math.floor((edit.x + edit.radius) / chunkWorldSize);
22
+ const minCY = Math.floor((edit.y - edit.radius) / chunkWorldSize);
23
+ const maxCY = Math.floor((edit.y + edit.radius) / chunkWorldSize);
24
+ const minCZ = Math.floor((edit.z - edit.radius) / chunkWorldSize);
25
+ const maxCZ = Math.floor((edit.z + edit.radius) / chunkWorldSize);
26
+ for (let cz = minCZ; cz <= maxCZ; cz++) {
27
+ for (let cy = minCY; cy <= maxCY; cy++) {
28
+ for (let cx = minCX; cx <= maxCX; cx++) {
29
+ const key = chunkKey(cx, cy, cz);
30
+ const chunk = chunks.get(key);
31
+ if (!chunk)
32
+ continue;
33
+ const originX = cx * chunkWorldSize;
34
+ const originY = cy * chunkWorldSize;
35
+ const originZ = cz * chunkWorldSize;
36
+ let modified = false;
37
+ for (let z = 0; z <= chunkSize; z++) {
38
+ for (let y = 0; y <= chunkSize; y++) {
39
+ for (let x = 0; x <= chunkSize; x++) {
40
+ const wx = originX + x * voxelSize;
41
+ const wy = originY + y * voxelSize;
42
+ const wz = originZ + z * voxelSize;
43
+ const weight = brushWeight(edit, wx, wy, wz);
44
+ if (weight <= 0)
45
+ continue;
46
+ const idx = z * s1s1 + y * s1 + x;
47
+ chunk.densityGrid[idx] = chunk.densityGrid[idx] + edit.strength * weight;
48
+ modified = true;
49
+ }
50
+ }
51
+ }
52
+ if (modified) {
53
+ dirty.add(key);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ return dirty;
59
+ }
60
+ /** Compute brush influence weight at a world position (0 = no effect, 1 = full). */
61
+ function brushWeight(edit, wx, wy, wz) {
62
+ const dx = wx - edit.x;
63
+ const dy = wy - edit.y;
64
+ const dz = wz - edit.z;
65
+ let dist;
66
+ if (edit.shape === BrushShape.Sphere) {
67
+ dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
68
+ }
69
+ else {
70
+ // Cube: Chebyshev distance
71
+ dist = Math.max(Math.abs(dx), Math.abs(dy), Math.abs(dz));
72
+ }
73
+ if (dist > edit.radius)
74
+ return 0;
75
+ if (edit.falloff <= 0)
76
+ return 1;
77
+ // Smooth falloff: starts at (1 - falloff) * radius
78
+ const innerRadius = edit.radius * (1 - edit.falloff);
79
+ if (dist <= innerRadius)
80
+ return 1;
81
+ const t = (dist - innerRadius) / (edit.radius - innerRadius);
82
+ // Smoothstep
83
+ return 1 - t * t * (3 - 2 * t);
84
+ }
85
+ //# sourceMappingURL=terrain-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain-editor.js","sourceRoot":"","sources":["../src/terrain-editor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { DensityFn } from './types.js';
2
+ /**
3
+ * Compute smooth normals via central-difference gradient of the density field.
4
+ * Overwrites the normal slots (offsets 3,4,5) in the vertex buffer.
5
+ */
6
+ export declare function computeGradientNormals(vertices: Float32Array, vertexCount: number, densityFn: DensityFn, epsilon: number): void;
7
+ /**
8
+ * Compute face-weighted normals from triangle data.
9
+ * Each vertex normal is the normalized sum of the face normals of all
10
+ * triangles sharing that vertex, weighted by triangle area.
11
+ */
12
+ export declare function computeTriangleNormals(vertices: Float32Array, indices: Uint32Array, vertexCount: number, indexCount: number): void;
13
+ //# sourceMappingURL=terrain-normals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain-normals.d.ts","sourceRoot":"","sources":["../src/terrain-normals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAI5C;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,GACd,IAAI,CA4BN;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,WAAW,EACpB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,IAAI,CAsDN"}
@@ -0,0 +1,96 @@
1
+ const STRIDE = 8;
2
+ /**
3
+ * Compute smooth normals via central-difference gradient of the density field.
4
+ * Overwrites the normal slots (offsets 3,4,5) in the vertex buffer.
5
+ */
6
+ export function computeGradientNormals(vertices, vertexCount, densityFn, epsilon) {
7
+ for (let i = 0; i < vertexCount; i++) {
8
+ const o = i * STRIDE;
9
+ const px = vertices[o];
10
+ const py = vertices[o + 1];
11
+ const pz = vertices[o + 2];
12
+ // Central differences: gradient of density (positive = air)
13
+ // Normal points from solid toward air (in direction of increasing density)
14
+ let nx = densityFn(px + epsilon, py, pz) - densityFn(px - epsilon, py, pz);
15
+ let ny = densityFn(px, py + epsilon, pz) - densityFn(px, py - epsilon, pz);
16
+ let nz = densityFn(px, py, pz + epsilon) - densityFn(px, py, pz - epsilon);
17
+ // Normalize
18
+ const len = Math.sqrt(nx * nx + ny * ny + nz * nz);
19
+ if (len > 1e-10) {
20
+ const inv = 1 / len;
21
+ nx *= inv;
22
+ ny *= inv;
23
+ nz *= inv;
24
+ }
25
+ else {
26
+ nx = 0;
27
+ ny = 1;
28
+ nz = 0;
29
+ }
30
+ vertices[o + 3] = nx;
31
+ vertices[o + 4] = ny;
32
+ vertices[o + 5] = nz;
33
+ }
34
+ }
35
+ /**
36
+ * Compute face-weighted normals from triangle data.
37
+ * Each vertex normal is the normalized sum of the face normals of all
38
+ * triangles sharing that vertex, weighted by triangle area.
39
+ */
40
+ export function computeTriangleNormals(vertices, indices, vertexCount, indexCount) {
41
+ // Zero out normals
42
+ for (let i = 0; i < vertexCount; i++) {
43
+ const o = i * STRIDE;
44
+ vertices[o + 3] = 0;
45
+ vertices[o + 4] = 0;
46
+ vertices[o + 5] = 0;
47
+ }
48
+ // Accumulate face normals (area-weighted via cross product magnitude)
49
+ for (let t = 0; t < indexCount; t += 3) {
50
+ const i0 = indices[t];
51
+ const i1 = indices[t + 1];
52
+ const i2 = indices[t + 2];
53
+ const o0 = i0 * STRIDE;
54
+ const o1 = i1 * STRIDE;
55
+ const o2 = i2 * STRIDE;
56
+ const ax = vertices[o1] - vertices[o0];
57
+ const ay = vertices[o1 + 1] - vertices[o0 + 1];
58
+ const az = vertices[o1 + 2] - vertices[o0 + 2];
59
+ const bx = vertices[o2] - vertices[o0];
60
+ const by = vertices[o2 + 1] - vertices[o0 + 1];
61
+ const bz = vertices[o2 + 2] - vertices[o0 + 2];
62
+ // Cross product (area-weighted normal)
63
+ const nx = ay * bz - az * by;
64
+ const ny = az * bx - ax * bz;
65
+ const nz = ax * by - ay * bx;
66
+ vertices[o0 + 3] = vertices[o0 + 3] + nx;
67
+ vertices[o0 + 4] = vertices[o0 + 4] + ny;
68
+ vertices[o0 + 5] = vertices[o0 + 5] + nz;
69
+ vertices[o1 + 3] = vertices[o1 + 3] + nx;
70
+ vertices[o1 + 4] = vertices[o1 + 4] + ny;
71
+ vertices[o1 + 5] = vertices[o1 + 5] + nz;
72
+ vertices[o2 + 3] = vertices[o2 + 3] + nx;
73
+ vertices[o2 + 4] = vertices[o2 + 4] + ny;
74
+ vertices[o2 + 5] = vertices[o2 + 5] + nz;
75
+ }
76
+ // Normalize
77
+ for (let i = 0; i < vertexCount; i++) {
78
+ const o = i * STRIDE;
79
+ let nx = vertices[o + 3];
80
+ let ny = vertices[o + 4];
81
+ let nz = vertices[o + 5];
82
+ const len = Math.sqrt(nx * nx + ny * ny + nz * nz);
83
+ if (len > 1e-10) {
84
+ const inv = 1 / len;
85
+ vertices[o + 3] = nx * inv;
86
+ vertices[o + 4] = ny * inv;
87
+ vertices[o + 5] = nz * inv;
88
+ }
89
+ else {
90
+ vertices[o + 3] = 0;
91
+ vertices[o + 4] = 1;
92
+ vertices[o + 5] = 0;
93
+ }
94
+ }
95
+ }
96
+ //# sourceMappingURL=terrain-normals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain-normals.js","sourceRoot":"","sources":["../src/terrain-normals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { Component, Scene } from '@certe/atmos-core';
2
+ import type { Material } from '@certe/atmos-renderer';
3
+ import type { DensityFn, TerrainConfig, TerrainEdit } from './types.js';
4
+ /**
5
+ * Bounded terrain volume component.
6
+ * Manages an NxMxP grid of terrain chunks as child GameObjects with MeshRenderers.
7
+ */
8
+ export declare class TerrainVolume extends Component {
9
+ /** Number of chunks along each axis */
10
+ chunksX: number;
11
+ chunksY: number;
12
+ chunksZ: number;
13
+ config: TerrainConfig;
14
+ private _densityFn;
15
+ private _chunks;
16
+ private _chunkObjects;
17
+ private _rendererCtx;
18
+ private _scene;
19
+ private _material;
20
+ /** GOs kept alive for 1 overlap frame, then moved to _pendingRemoval. */
21
+ private _pendingDisable;
22
+ /** GOs with disabled MR, ready for scene removal + buffer destruction. */
23
+ private _pendingRemoval;
24
+ setDensityFn(fn: DensityFn): void;
25
+ init(device: GPUDevice, pipelineResources: import('@certe/atmos-renderer').PipelineResources, scene: Scene, material?: Material): void;
26
+ build(): void;
27
+ edit(op: TerrainEdit): void;
28
+ onDestroy(): void;
29
+ onRender(): void;
30
+ private _buildChunk;
31
+ private _rebuildChunkMesh;
32
+ /**
33
+ * Two-phase deferred removal:
34
+ * Phase 1: disable overlap GOs (were drawn alongside replacement last frame)
35
+ * Phase 2: destroy GOs that were disabled last frame (safe after submit)
36
+ */
37
+ private _flushRemovals;
38
+ private _createChunkObject;
39
+ private _destroyGO;
40
+ private _destroyAllChunks;
41
+ }
42
+ //# sourceMappingURL=terrain-volume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain-volume.d.ts","sourceRoot":"","sources":["../src/terrain-volume.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAc,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAuB,MAAM,uBAAuB,CAAC;AAI3E,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGxE;;;GAGG;AACH,qBAAa,aAAc,SAAQ,SAAS;IAC1C,uCAAuC;IACvC,OAAO,SAAK;IACZ,OAAO,SAAK;IACZ,OAAO,SAAK;IAEZ,MAAM,EAAE,aAAa,CAAiC;IAEtD,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAyB;IAC1C,yEAAyE;IACzE,OAAO,CAAC,eAAe,CAAoB;IAC3C,0EAA0E;IAC1E,OAAO,CAAC,eAAe,CAAoB;IAE3C,YAAY,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAIjC,IAAI,CACF,MAAM,EAAE,SAAS,EACjB,iBAAiB,EAAE,OAAO,uBAAuB,EAAE,iBAAiB,EACpE,KAAK,EAAE,KAAK,EACZ,QAAQ,CAAC,EAAE,QAAQ,GAClB,IAAI;IAMP,KAAK,IAAI,IAAI;IAcb,IAAI,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI;IAa3B,SAAS,IAAI,IAAI;IAIjB,QAAQ,IAAI,IAAI;IAIhB,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,iBAAiB;IAkBzB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,iBAAiB;CAW1B"}