@drawcall/charta 0.1.20 → 0.1.21
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/dist/grass/index.d.ts.map +1 -1
- package/dist/grass/index.js +10 -11
- package/dist/interpreter.d.ts +6 -4
- package/dist/interpreter.d.ts.map +1 -1
- package/dist/interpreter.js +32 -12
- package/dist/locations.d.ts.map +1 -1
- package/dist/locations.js +4 -6
- package/dist/pillars/index.d.ts.map +1 -1
- package/dist/pillars/index.js +24 -27
- package/dist/place/index.d.ts.map +1 -1
- package/dist/place/index.js +22 -20
- package/dist/schemas.d.ts +18 -0
- package/dist/schemas.d.ts.map +1 -1
- package/dist/tiles/geometry.d.ts +14 -9
- package/dist/tiles/geometry.d.ts.map +1 -1
- package/dist/tiles/geometry.js +3 -10
- package/dist/tiles/index.d.ts +4 -2
- package/dist/tiles/index.d.ts.map +1 -1
- package/dist/tiles/index.js +11 -2
- package/dist/walls/index.d.ts.map +1 -1
- package/dist/walls/index.js +12 -9
- package/dist/water/index.d.ts +8 -5
- package/dist/water/index.d.ts.map +1 -1
- package/dist/water/index.js +13 -12
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/grass/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,aAAa,EACb,QAAQ,EAMT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAO9E,MAAM,MAAM,YAAY,GAAG,oBAAoB,GAAG;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,qBAAa,SAAU,SAAQ,aAAa;gBAExC,WAAW,EAAE,WAAW,EACxB,QAAQ,GAAE,QAAkC,EAC5C,IAAI,GAAE,YAAiB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/grass/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,aAAa,EACb,QAAQ,EAMT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAO9E,MAAM,MAAM,YAAY,GAAG,oBAAoB,GAAG;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,qBAAa,SAAU,SAAQ,aAAa;gBAExC,WAAW,EAAE,WAAW,EACxB,QAAQ,GAAE,QAAkC,EAC5C,IAAI,GAAE,YAAiB;CAyP1B"}
|
package/dist/grass/index.js
CHANGED
|
@@ -15,7 +15,7 @@ export class GrassMesh extends InstancedMesh {
|
|
|
15
15
|
for (let row = 0; row < rows; row++) {
|
|
16
16
|
for (let col = 0; col < cols; col++) {
|
|
17
17
|
// getCalls validates the schema and reports errors
|
|
18
|
-
interpreter.getCalls(
|
|
18
|
+
interpreter.getCalls({ row, col }, { grass: grassSchema });
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
return;
|
|
@@ -31,7 +31,7 @@ export class GrassMesh extends InstancedMesh {
|
|
|
31
31
|
for (let row = 0; row < rows; row++) {
|
|
32
32
|
for (let col = 0; col < cols; col++) {
|
|
33
33
|
const grassParsed = interpreter
|
|
34
|
-
.getCalls(
|
|
34
|
+
.getCalls({ row, col }, { grass: grassSchema })
|
|
35
35
|
.at(-1)?.[1];
|
|
36
36
|
if (!grassParsed)
|
|
37
37
|
continue;
|
|
@@ -42,7 +42,7 @@ export class GrassMesh extends InstancedMesh {
|
|
|
42
42
|
const step = cellSize / subN;
|
|
43
43
|
const jitterAmp = step * 0.35;
|
|
44
44
|
// top surface stack index = total number of ground/ceiling - 1
|
|
45
|
-
const topStackIndex = Math.max(0, interpreter.countCalls(
|
|
45
|
+
const topStackIndex = Math.max(0, interpreter.countCalls({ row, col }, (c) => c.name === "ground" || c.name === "ceiling") - 1);
|
|
46
46
|
perCell[row][col] = {
|
|
47
47
|
subN,
|
|
48
48
|
jitterAmp,
|
|
@@ -101,8 +101,7 @@ export class GrassMesh extends InstancedMesh {
|
|
|
101
101
|
const nb = neighbors;
|
|
102
102
|
const step = cellSize / subN;
|
|
103
103
|
// Cell center
|
|
104
|
-
const cx
|
|
105
|
-
const cz = (row - rows / 2 + 0.5) * cellSize;
|
|
104
|
+
const { x: cx, z: cz } = interpreter.gridToWorld({ row, col });
|
|
106
105
|
for (let gz = 0; gz < subN; gz++) {
|
|
107
106
|
for (let gx = 0; gx < subN; gx++) {
|
|
108
107
|
// Optimization: Check stochastic rejection early using simplified fade check
|
|
@@ -144,16 +143,16 @@ export class GrassMesh extends InstancedMesh {
|
|
|
144
143
|
if (Math.random() >= f)
|
|
145
144
|
continue;
|
|
146
145
|
// --- Instance is accepted ---
|
|
147
|
-
// Position
|
|
148
|
-
const
|
|
149
|
-
const
|
|
146
|
+
// Position (offset from cell center)
|
|
147
|
+
const offsetX = -cellSize * 0.5 + (gx + 0.5) * step;
|
|
148
|
+
const offsetZ = -cellSize * 0.5 + (gz + 0.5) * step;
|
|
150
149
|
const jx = (Math.random() * 2 - 1) * jitterAmp;
|
|
151
150
|
const jz = (Math.random() * 2 - 1) * jitterAmp;
|
|
152
|
-
const px = cx +
|
|
153
|
-
const pz = cz +
|
|
151
|
+
const px = cx + offsetX + jx;
|
|
152
|
+
const pz = cz + offsetZ + jz;
|
|
154
153
|
let baseY = 0;
|
|
155
154
|
if (tilesGeometry) {
|
|
156
|
-
baseY = tilesGeometry.
|
|
155
|
+
baseY = tilesGeometry.getHeightAt({ row, col, offsetX: offsetX + jx, offsetZ: offsetZ + jz }, { stackIndex: topStackIndex });
|
|
157
156
|
}
|
|
158
157
|
tmpPos.set(px, baseY, pz);
|
|
159
158
|
// Scale
|
package/dist/interpreter.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { output, ZodObject } from 'zod';
|
|
2
2
|
import { Call } from './parser.js';
|
|
3
3
|
import { ChartaError, ErrorLocation } from './errors.js';
|
|
4
|
-
import { cellSizeSchema } from './schemas.js';
|
|
4
|
+
import { cellSizeSchema, GridCoord, WorldCoord } from './schemas.js';
|
|
5
|
+
export type { GridCoord, WorldCoord };
|
|
5
6
|
export { cellSizeSchema as cellSizeFunctionParams };
|
|
6
7
|
export type InterpreterOptions = {
|
|
7
8
|
throwOnError?: boolean;
|
|
@@ -19,13 +20,14 @@ export declare class Interpreter {
|
|
|
19
20
|
private readonly sourceLines;
|
|
20
21
|
getSource(): string;
|
|
21
22
|
getLineTextForRow(row: number): string;
|
|
22
|
-
|
|
23
|
+
gridToWorld(coord: GridCoord): WorldCoord;
|
|
24
|
+
worldToGrid(coord: WorldCoord): GridCoord;
|
|
23
25
|
getRows(): number;
|
|
24
26
|
getCols(): number;
|
|
25
|
-
countCalls(
|
|
27
|
+
countCalls(coord: GridCoord | undefined, filter: string | ((call: Call) => boolean), startAt?: number, endAtExcl?: number): number;
|
|
26
28
|
getCalls<T extends {
|
|
27
29
|
[Key in string]: ZodObject<any>;
|
|
28
|
-
}>(
|
|
30
|
+
}>(coord: GridCoord | undefined, callSchemas: T): Array<{
|
|
29
31
|
[Key in keyof T]: [Key, output<T[Key]>, number, {
|
|
30
32
|
line: number;
|
|
31
33
|
column: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../src/interpreter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAa,MAAM,KAAK,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"interpreter.d.ts","sourceRoot":"","sources":["../src/interpreter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAa,MAAM,KAAK,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEpE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,CAAA;AAErC,OAAO,EAAE,cAAc,IAAI,sBAAsB,EAAE,CAAA;AAEnD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,qBAAa,WAAW;IAKpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,YAAY,CAAS;gBAGV,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,EACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAK,EAChC,MAAM,EAAE,MAAM,EAC/B,OAAO,GAAE,kBAAuB;IAelC,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAOrC,SAAS,IAAI,WAAW,EAAE;IAI1B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IAEtC,SAAS,IAAI,MAAM;IAInB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAMtC,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU;IAUzC,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS;IAsBzC,OAAO,IAAI,MAAM;IAKjB,OAAO,IAAI,MAAM;IAKjB,UAAU,CACR,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,EAC1C,OAAO,GAAE,MAAU,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM;IAgBT,QAAQ,CAAC,CAAC,SAAS;SAAG,GAAG,IAAI,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC;KAAE,EACpD,KAAK,EAAE,SAAS,GAAG,SAAS,EAC5B,WAAW,EAAE,CAAC,GACb,KAAK,CACN;SACG,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KACpG,CAAC,MAAM,CAAC,CAAC,CACX;IA0GD,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,uBAAuB;IAa/B,gBAAgB,CAAC,CAAC,EAAE,WAAW,EAAE;QAAE,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;KAAE,EAAE,IAAI,GAAE,MAAyB,GAAG,CAAC,GAAG,SAAS;IAWlH,QAAQ,CAAC,CAAC,EACR,WAAW,EAAE;QAAE,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;KAAE,EAC7C,IAAI,GAAE,MAAyB,EAC/B,GAAG,CAAC,EAAE,aAAa,GAClB,CAAC,GAAG,SAAS;IAmBhB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAIxC,WAAW,IAAI,MAAM;CAStB"}
|
package/dist/interpreter.js
CHANGED
|
@@ -40,11 +40,31 @@ export class Interpreter {
|
|
|
40
40
|
const lineNumber = row + 2;
|
|
41
41
|
return this.sourceLines[lineNumber - 1] ?? '';
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
gridToWorld(coord) {
|
|
44
44
|
const cellSize = this.getCellSize();
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
return
|
|
45
|
+
const cx = (coord.col - this.getCols() / 2 + 0.5) * cellSize;
|
|
46
|
+
const cz = (coord.row - this.getRows() / 2 + 0.5) * cellSize;
|
|
47
|
+
return {
|
|
48
|
+
x: cx + (coord.offsetX ?? 0),
|
|
49
|
+
z: cz + (coord.offsetZ ?? 0),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
worldToGrid(coord) {
|
|
53
|
+
const cellSize = this.getCellSize();
|
|
54
|
+
const cols = this.getCols();
|
|
55
|
+
const rows = this.getRows();
|
|
56
|
+
const rawCol = coord.x / cellSize + cols / 2 - 0.5;
|
|
57
|
+
const rawRow = coord.z / cellSize + rows / 2 - 0.5;
|
|
58
|
+
const col = Math.floor(rawCol);
|
|
59
|
+
const row = Math.floor(rawRow);
|
|
60
|
+
const cellCenterX = (col - cols / 2 + 0.5) * cellSize;
|
|
61
|
+
const cellCenterZ = (row - rows / 2 + 0.5) * cellSize;
|
|
62
|
+
return {
|
|
63
|
+
row,
|
|
64
|
+
col,
|
|
65
|
+
offsetX: coord.x - cellCenterX,
|
|
66
|
+
offsetZ: coord.z - cellCenterZ,
|
|
67
|
+
};
|
|
48
68
|
}
|
|
49
69
|
getRows() {
|
|
50
70
|
// Exclude meta row
|
|
@@ -54,9 +74,9 @@ export class Interpreter {
|
|
|
54
74
|
// Use first grid row, if present
|
|
55
75
|
return this.ast.length > 1 ? this.ast[1].length : 0;
|
|
56
76
|
}
|
|
57
|
-
countCalls(
|
|
77
|
+
countCalls(coord, filter, startAt = 0, endAtExcl) {
|
|
58
78
|
let sum = 0;
|
|
59
|
-
const calls =
|
|
79
|
+
const calls = coord == null ? this.ast[0][0] : this.ast[coord.row + 1][coord.col];
|
|
60
80
|
const length = Math.min(endAtExcl ?? Infinity, calls.length);
|
|
61
81
|
for (let i = startAt; i < length; i++) {
|
|
62
82
|
if (typeof filter === 'string' && calls[i].name != filter) {
|
|
@@ -69,28 +89,28 @@ export class Interpreter {
|
|
|
69
89
|
}
|
|
70
90
|
return sum;
|
|
71
91
|
}
|
|
72
|
-
getCalls(
|
|
92
|
+
getCalls(coord, callSchemas) {
|
|
73
93
|
let calls;
|
|
74
94
|
const normalizedSource = this.normalizedSource;
|
|
75
95
|
const sourceLines = this.sourceLines;
|
|
76
96
|
let lineNumber = 1;
|
|
77
97
|
let lineText = sourceLines[0] ?? '';
|
|
78
98
|
let callStartColumns = [];
|
|
79
|
-
if (
|
|
99
|
+
if (coord == null) {
|
|
80
100
|
calls = this.ast[0][0];
|
|
81
101
|
callStartColumns = this.computeCallStartColumns(lineText);
|
|
82
102
|
}
|
|
83
103
|
else {
|
|
84
|
-
const row =
|
|
85
|
-
const col =
|
|
104
|
+
const row = coord.row + 1;
|
|
105
|
+
const col = coord.col;
|
|
86
106
|
if (row >= this.ast.length || col >= this.ast[row].length) {
|
|
87
|
-
const lineNumber =
|
|
107
|
+
const lineNumber = coord.row + 2;
|
|
88
108
|
const lineText = sourceLines[lineNumber - 1] ?? '';
|
|
89
109
|
this.reportError(new ChartaError(`index ${col}/${row} cannot be used to index the ast (${this.ast.length}/${this.ast[Math.min(1, this.ast.length - 1)].length})`, normalizedSource, { line: lineNumber, column: 1, lineText }));
|
|
90
110
|
return []; // Return empty if index invalid
|
|
91
111
|
}
|
|
92
112
|
calls = this.ast[row][col];
|
|
93
|
-
lineNumber =
|
|
113
|
+
lineNumber = coord.row + 2;
|
|
94
114
|
lineText = sourceLines[lineNumber - 1] ?? '';
|
|
95
115
|
const [cellStart, cellEnd] = this.getCellBounds(lineText, col);
|
|
96
116
|
const cellText = lineText.slice(cellStart, cellEnd);
|
package/dist/locations.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locations.d.ts","sourceRoot":"","sources":["../src/locations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAG9C,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,CAAA;AAEzB,qBAAa,SAAS;IACpB,SAAgB,cAAc,uBAA6B;gBAE/C,WAAW,EAAE,WAAW;
|
|
1
|
+
{"version":3,"file":"locations.d.ts","sourceRoot":"","sources":["../src/locations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAG9C,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,CAAA;AAEzB,qBAAa,SAAS;IACpB,SAAgB,cAAc,uBAA6B;gBAE/C,WAAW,EAAE,WAAW;IA8BpC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO;CAOzD"}
|
package/dist/locations.js
CHANGED
|
@@ -12,7 +12,7 @@ export class Locations {
|
|
|
12
12
|
const isLayer = (c) => c.name === 'ground' || c.name === 'ceiling';
|
|
13
13
|
for (let row = 0; row < rows; row++) {
|
|
14
14
|
for (let col = 0; col < cols; col++) {
|
|
15
|
-
const entries = interpreter.getCalls(
|
|
15
|
+
const entries = interpreter.getCalls({ row, col }, { location: locationSchema });
|
|
16
16
|
for (const [, parsed, callIdx, loc] of entries) {
|
|
17
17
|
const name = parsed.name;
|
|
18
18
|
if (this.worldPositions.has(name)) {
|
|
@@ -21,12 +21,10 @@ export class Locations {
|
|
|
21
21
|
}
|
|
22
22
|
const offsetX = parsed.offsetX ?? 0;
|
|
23
23
|
const offsetZ = parsed.offsetZ ?? 0;
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const z = cz + offsetZ;
|
|
27
|
-
const layersBefore = interpreter.countCalls([row, col], isLayer, 0, callIdx);
|
|
24
|
+
const { x, z } = interpreter.gridToWorld({ row, col, offsetX, offsetZ });
|
|
25
|
+
const layersBefore = interpreter.countCalls({ row, col }, isLayer, 0, callIdx);
|
|
28
26
|
const stackIndex = layersBefore > 0 ? layersBefore - 1 : 0;
|
|
29
|
-
const y = tilesGeometry?.
|
|
27
|
+
const y = tilesGeometry?.getHeightAt({ row, col, offsetX, offsetZ }, { stackIndex }) ?? 0;
|
|
30
28
|
this.worldPositions.set(name, new Vector3(x, y, z));
|
|
31
29
|
}
|
|
32
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pillars/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEb,QAAQ,EAMT,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAQ/C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,GAAG,YAAY,CAAA;AAYhF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAC/B,WAAW,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAkC,EAAE,OAAO,GAAE,iBAAsB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pillars/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EAEb,QAAQ,EAMT,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAQ/C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,GAAG,YAAY,CAAA;AAYhF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,qBAAa,UAAW,SAAQ,aAAa;gBAC/B,WAAW,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAkC,EAAE,OAAO,GAAE,iBAAsB;CA+LpH"}
|
package/dist/pillars/index.js
CHANGED
|
@@ -28,31 +28,30 @@ export class PillarMesh extends InstancedMesh {
|
|
|
28
28
|
return idx;
|
|
29
29
|
};
|
|
30
30
|
function resolveCornerPosition(row, col, corner) {
|
|
31
|
-
const [cx, cz] = interpreter.getWorldCellCenter(row, col);
|
|
32
31
|
const half = cellSize * 0.5;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const lineNumber = row + 2;
|
|
44
|
-
const lineText = interpreter.getLineTextForRow(row);
|
|
45
|
-
const pos = lineText.indexOf('pillar(');
|
|
46
|
-
const columnNumber = pos >= 0 ? pos + 1 : 1;
|
|
47
|
-
interpreter.reportError(new ChartaError(`pillar at ${row}/${col}: invalid corner "${corner}", expected one of topleft, topright, bottomright, bottomleft`, interpreter.getSource(), { line: lineNumber, column: columnNumber, lineText }));
|
|
48
|
-
return undefined;
|
|
49
|
-
}
|
|
32
|
+
const offsets = {
|
|
33
|
+
topleft: [-half, -half],
|
|
34
|
+
topright: [half, -half],
|
|
35
|
+
bottomright: [half, half],
|
|
36
|
+
bottomleft: [-half, half],
|
|
37
|
+
};
|
|
38
|
+
const offset = offsets[corner];
|
|
39
|
+
if (offset) {
|
|
40
|
+
const { x, z } = interpreter.gridToWorld({ row, col, offsetX: offset[0], offsetZ: offset[1] });
|
|
41
|
+
return [x, z];
|
|
50
42
|
}
|
|
43
|
+
// Invalid corner
|
|
44
|
+
const lineNumber = row + 2;
|
|
45
|
+
const lineText = interpreter.getLineTextForRow(row);
|
|
46
|
+
const pos = lineText.indexOf('pillar(');
|
|
47
|
+
const columnNumber = pos >= 0 ? pos + 1 : 1;
|
|
48
|
+
interpreter.reportError(new ChartaError(`pillar at ${row}/${col}: invalid corner "${corner}", expected one of topleft, topright, bottomright, bottomleft`, interpreter.getSource(), { line: lineNumber, column: columnNumber, lineText }));
|
|
49
|
+
return undefined;
|
|
51
50
|
}
|
|
52
51
|
// Validation loop runs in both modes
|
|
53
52
|
for (let row = 0; row < rows; row++) {
|
|
54
53
|
for (let col = 0; col < cols; col++) {
|
|
55
|
-
const entries = interpreter.getCalls(
|
|
54
|
+
const entries = interpreter.getCalls({ row, col }, {
|
|
56
55
|
pillar: pillarSchema,
|
|
57
56
|
});
|
|
58
57
|
for (const [, parsed, idx, loc] of entries) {
|
|
@@ -62,9 +61,7 @@ export class PillarMesh extends InstancedMesh {
|
|
|
62
61
|
if (!cornerPos)
|
|
63
62
|
continue;
|
|
64
63
|
const [px, pz] = cornerPos;
|
|
65
|
-
const
|
|
66
|
-
const offsetX = px - cx;
|
|
67
|
-
const offsetZ = pz - cz;
|
|
64
|
+
const { offsetX, offsetZ } = interpreter.worldToGrid({ x: px, z: pz });
|
|
68
65
|
// Validate texture reference (runs in both modes)
|
|
69
66
|
const textureId = getTextureId(parsed.texture, loc);
|
|
70
67
|
// Derive default layers relative to call position (like walls)
|
|
@@ -74,7 +71,7 @@ export class PillarMesh extends InstancedMesh {
|
|
|
74
71
|
// Validate layer existence (runs in both modes)
|
|
75
72
|
let bottomStackIndex;
|
|
76
73
|
if (bottomY == null) {
|
|
77
|
-
const layersBefore = interpreter.countCalls(
|
|
74
|
+
const layersBefore = interpreter.countCalls({ row, col }, isLayer, 0, idx);
|
|
78
75
|
bottomStackIndex = layersBefore - 1;
|
|
79
76
|
if (bottomStackIndex < 0) {
|
|
80
77
|
interpreter.reportError(new ChartaError(`pillar at ${row}/${col}: missing bottomY and no preceding layer`, interpreter.getSource(), loc));
|
|
@@ -85,24 +82,24 @@ export class PillarMesh extends InstancedMesh {
|
|
|
85
82
|
const tilesGeometry = interpreter.getAsset(TilesGeometry, 'tilesGeometry', loc);
|
|
86
83
|
if (!tilesGeometry)
|
|
87
84
|
continue;
|
|
88
|
-
bottomY = tilesGeometry.
|
|
85
|
+
bottomY = tilesGeometry.getHeightAt({ row, col, offsetX, offsetZ }, { stackIndex: bottomStackIndex });
|
|
89
86
|
}
|
|
90
87
|
}
|
|
91
88
|
let topStackIndex;
|
|
92
89
|
if (topY == null) {
|
|
93
|
-
const layersAfter = interpreter.countCalls(
|
|
90
|
+
const layersAfter = interpreter.countCalls({ row, col }, isLayer, idx + 1);
|
|
94
91
|
if (layersAfter <= 0) {
|
|
95
92
|
interpreter.reportError(new ChartaError(`pillar at ${row}/${col}: missing topY and no subsequent layer`, interpreter.getSource(), loc));
|
|
96
93
|
continue;
|
|
97
94
|
}
|
|
98
95
|
// Height sampling only in non-validateOnly mode
|
|
99
96
|
if (!options.validateOnly) {
|
|
100
|
-
const layersBefore = interpreter.countCalls(
|
|
97
|
+
const layersBefore = interpreter.countCalls({ row, col }, isLayer, 0, idx);
|
|
101
98
|
topStackIndex = layersBefore;
|
|
102
99
|
const tilesGeometry = interpreter.getAsset(TilesGeometry, 'tilesGeometry', loc);
|
|
103
100
|
if (!tilesGeometry)
|
|
104
101
|
continue;
|
|
105
|
-
topY = tilesGeometry.
|
|
102
|
+
topY = tilesGeometry.getHeightAt({ row, col, offsetX, offsetZ }, { stackIndex: topStackIndex });
|
|
106
103
|
}
|
|
107
104
|
}
|
|
108
105
|
// Only collect pillar data in non-validateOnly mode
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/place/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAQ,MAAM,OAAO,CAAA;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAO/C,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;AAEvD,MAAM,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE;IACvC,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,UAAU,CAAA;IACpB,KAAK,EAAE,OAAO,CAAA;IACd,WAAW,EAAE,WAAW,CAAA;IACxB,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;IAC5D,IAAI,EAAE,MAAM,CAAA;CACb,KAAK,IAAI,CAAA;AAKV,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAOvD;AAED,qBAAa,kBAAkB;aAIX,UAAU,EAAE,OAAO;IACnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAJpC,SAAgB,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAK;gBAG3B,UAAU,EAAE,OAAO,EAClB,iBAAiB,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,QAAQ;IAG5E,GAAG,CAAC,MAAM,EAAE,OAAO;IAKZ,KAAK,IAAI,QAAQ;CAGzB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAA;CACjC,CAAA;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAgB,aAAa,kCAAwC;gBAEzD,WAAW,EAAE,WAAW,EAAE,iBAAiB,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAE,iBAAsB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/place/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAQ,MAAM,OAAO,CAAA;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAO/C,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAA;AAEvD,MAAM,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE;IACvC,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,UAAU,CAAA;IACpB,KAAK,EAAE,OAAO,CAAA;IACd,WAAW,EAAE,WAAW,CAAA;IACxB,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;IAC5D,IAAI,EAAE,MAAM,CAAA;CACb,KAAK,IAAI,CAAA;AAKV,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAOvD;AAED,qBAAa,kBAAkB;aAIX,UAAU,EAAE,OAAO;IACnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAJpC,SAAgB,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAK;gBAG3B,UAAU,EAAE,OAAO,EAClB,iBAAiB,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,QAAQ;IAG5E,GAAG,CAAC,MAAM,EAAE,OAAO;IAKZ,KAAK,IAAI,QAAQ;CAGzB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,sBAAsB,CAAC,EAAE,OAAO,CAAA;CACjC,CAAA;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAgB,aAAa,kCAAwC;gBAEzD,WAAW,EAAE,WAAW,EAAE,iBAAiB,CAAC,EAAE,QAAQ,EAAE,IAAI,GAAE,iBAAsB;IAkPhG,OAAO;CAOR"}
|
package/dist/place/index.js
CHANGED
|
@@ -61,18 +61,17 @@ export class PlaceGroup extends Group {
|
|
|
61
61
|
const scale = Math.min(sFactorX ?? sFactorZ ?? 1, sFactorZ ?? sFactorX ?? 1);
|
|
62
62
|
return new Vector3(scale, scale, scale);
|
|
63
63
|
};
|
|
64
|
-
const computeTransform = (
|
|
64
|
+
const computeTransform = (worldX, worldZ, cell, transformOpts) => {
|
|
65
65
|
const normal = new Vector3();
|
|
66
|
-
const offsetX =
|
|
67
|
-
const offsetZ = pz - cell.center[1];
|
|
66
|
+
const { offsetX, offsetZ } = interpreter.worldToGrid({ x: worldX, z: worldZ });
|
|
68
67
|
let py = 0;
|
|
69
68
|
if (transformOpts.useFixedY) {
|
|
70
69
|
py = transformOpts.fixedY;
|
|
71
70
|
}
|
|
72
71
|
else {
|
|
73
|
-
py = tilesGeometry.
|
|
72
|
+
py = tilesGeometry.getHeightAt({ row: cell.row, col: cell.col, offsetX, offsetZ }, { stackIndex: transformOpts.layerIndex, normalTarget: normal });
|
|
74
73
|
}
|
|
75
|
-
const pos = new Vector3(
|
|
74
|
+
const pos = new Vector3(worldX, py, worldZ);
|
|
76
75
|
const quat = new Quaternion();
|
|
77
76
|
if (transformOpts.alignMode === 'normal' && !transformOpts.useFixedY) {
|
|
78
77
|
const qAlign = new Quaternion().setFromUnitVectors(new Vector3(0, 1, 0), normal);
|
|
@@ -90,19 +89,18 @@ export class PlaceGroup extends Group {
|
|
|
90
89
|
for (let row = 0; row < rows; row++) {
|
|
91
90
|
for (let col = 0; col < cols; col++) {
|
|
92
91
|
// getCalls validates the schema and reports errors
|
|
93
|
-
const scatterEntries = interpreter.getCalls(
|
|
94
|
-
const placeEntries = interpreter.getCalls(
|
|
92
|
+
const scatterEntries = interpreter.getCalls({ row, col }, { scatter: scatterSchema });
|
|
93
|
+
const placeEntries = interpreter.getCalls({ row, col }, { place: placeSchema });
|
|
95
94
|
if (scatterEntries.length === 0 && placeEntries.length === 0)
|
|
96
95
|
continue;
|
|
97
|
-
const cx
|
|
98
|
-
const cz = (row - rows / 2 + 0.5) * cellSize;
|
|
96
|
+
const { x: cx, z: cz } = interpreter.gridToWorld({ row, col });
|
|
99
97
|
const half = cellSize * 0.5;
|
|
100
98
|
// Collect location points in this cell for collision/footprint validation
|
|
101
|
-
const locationEntries = interpreter.getCalls(
|
|
102
|
-
const locationPoints = locationEntries.map(([, parsed]) =>
|
|
103
|
-
x
|
|
104
|
-
|
|
105
|
-
})
|
|
99
|
+
const locationEntries = interpreter.getCalls({ row, col }, { location: locationSchema });
|
|
100
|
+
const locationPoints = locationEntries.map(([, parsed]) => {
|
|
101
|
+
const { x, z } = interpreter.gridToWorld({ row, col, offsetX: parsed.offsetX, offsetZ: parsed.offsetZ });
|
|
102
|
+
return { x, z };
|
|
103
|
+
});
|
|
106
104
|
// scatter: randomized distribution
|
|
107
105
|
for (const [, parsed, callIdx, loc] of scatterEntries) {
|
|
108
106
|
const prefabName = `${parsed.model}Prefab`;
|
|
@@ -115,7 +113,7 @@ export class PlaceGroup extends Group {
|
|
|
115
113
|
this.batchBuilders.set(parsed.model, batchBuilder);
|
|
116
114
|
const usualSize = new Vector3();
|
|
117
115
|
usualSize.copy(batchBuilder.prefabSize);
|
|
118
|
-
const layerIndex = interpreter.countCalls(
|
|
116
|
+
const layerIndex = interpreter.countCalls({ row, col }, (c) => c.name === 'ground' || c.name === 'ceiling', 0, callIdx) - 1;
|
|
119
117
|
const base = hashStringToUint32(parsed.model);
|
|
120
118
|
const seed = hashNumbersToUint32(base, row, col);
|
|
121
119
|
const rng = createRng(seed);
|
|
@@ -143,7 +141,7 @@ export class PlaceGroup extends Group {
|
|
|
143
141
|
const px = cx + ox;
|
|
144
142
|
const pz = cz + oz;
|
|
145
143
|
const yaw = yawMin === yawMax ? yawMin : yawMin + (yawMax - yawMin) * rng();
|
|
146
|
-
const { pos, quat, scl } = computeTransform(px, pz, { row, col
|
|
144
|
+
const { pos, quat, scl } = computeTransform(px, pz, { row, col }, {
|
|
147
145
|
alignMode,
|
|
148
146
|
yaw,
|
|
149
147
|
useFixedY: useFixedY,
|
|
@@ -174,8 +172,12 @@ export class PlaceGroup extends Group {
|
|
|
174
172
|
if (!batchBuilder)
|
|
175
173
|
continue;
|
|
176
174
|
const usualSize = batchBuilder.prefabSize;
|
|
177
|
-
const px
|
|
178
|
-
|
|
175
|
+
const { x: px, z: pz } = interpreter.gridToWorld({
|
|
176
|
+
row,
|
|
177
|
+
col,
|
|
178
|
+
offsetX: parsed.offsetX,
|
|
179
|
+
offsetZ: parsed.offsetZ,
|
|
180
|
+
});
|
|
179
181
|
// Compute scale for footprint validation (needed for both validateOnly and normal mode)
|
|
180
182
|
const scale = computeScale(usualSize, parsed.sizeX, parsed.sizeZ);
|
|
181
183
|
const halfX = (usualSize.x * scale.x) / 2;
|
|
@@ -190,10 +192,10 @@ export class PlaceGroup extends Group {
|
|
|
190
192
|
if (validateOnly)
|
|
191
193
|
continue;
|
|
192
194
|
this.batchBuilders.set(parsed.model, batchBuilder);
|
|
193
|
-
const layerIndex = interpreter.countCalls(
|
|
195
|
+
const layerIndex = interpreter.countCalls({ row, col }, (c) => c.name === 'ground' || c.name === 'ceiling', 0, callIdx) - 1;
|
|
194
196
|
const yaw = parsed.yaw ?? 0;
|
|
195
197
|
const alignMode = (parsed.align ?? 'up').toLowerCase();
|
|
196
|
-
const { pos, quat, scl } = computeTransform(px, pz, { row, col
|
|
198
|
+
const { pos, quat, scl } = computeTransform(px, pz, { row, col }, {
|
|
197
199
|
alignMode,
|
|
198
200
|
yaw,
|
|
199
201
|
useFixedY: parsed.bottomY != null,
|
package/dist/schemas.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
import { coerce } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Grid coordinate with optional offset from cell center.
|
|
4
|
+
* row/col are integer indices into the grid.
|
|
5
|
+
* offsetX/offsetZ are in meters from the cell center.
|
|
6
|
+
*/
|
|
7
|
+
export type GridCoord = {
|
|
8
|
+
row: number;
|
|
9
|
+
col: number;
|
|
10
|
+
offsetX?: number;
|
|
11
|
+
offsetZ?: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* World coordinate in meters (top-down X/Z plane).
|
|
15
|
+
*/
|
|
16
|
+
export type WorldCoord = {
|
|
17
|
+
x: number;
|
|
18
|
+
z: number;
|
|
19
|
+
};
|
|
2
20
|
export declare const alignEnum: import("zod").ZodEnum<{
|
|
3
21
|
up: "up";
|
|
4
22
|
normal: "normal";
|
package/dist/schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAmC,MAAM,KAAK,CAAA;AAM7D,eAAO,MAAM,SAAS;;;EAA4B,CAAA;AAClD,eAAO,MAAM,UAAU;;;;;EAAgE,CAAA;AACvF,eAAO,MAAM,WAAW;;;;;EAA8C,CAAA;AAMtE,eAAO,MAAM,cAAc;;gCAAoC,CAAA;AAC/D,eAAO,MAAM,cAAc;;gCAA6B,CAAA;AACxD,eAAO,MAAM,iBAAiB;;;gCAA6C,CAAA;AAC3E,eAAO,MAAM,eAAe;;;gCAA6C,CAAA;AAMzE,eAAO,MAAM,YAAY;;;gCAAoD,CAAA;AAC7E,eAAO,MAAM,aAAa;;;gCAAoD,CAAA;AAC9E,eAAO,MAAM,WAAW;;gCAAiC,CAAA;AAMzD,eAAO,MAAM,UAAU;;;;;;;;;;gCAKrB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;gCAKvB,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;gCAMrB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;gCAOvB,CAAA;AAMF,eAAO,MAAM,cAAc;;;;gCAIzB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;gCAStB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;gCAcxB,CAAA;AAMF,eAAO,MAAM,WAAW;;;;gCAItB,CAAA;AAMF;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAET"}
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAmC,MAAM,KAAK,CAAA;AAM7D;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV,CAAA;AAMD,eAAO,MAAM,SAAS;;;EAA4B,CAAA;AAClD,eAAO,MAAM,UAAU;;;;;EAAgE,CAAA;AACvF,eAAO,MAAM,WAAW;;;;;EAA8C,CAAA;AAMtE,eAAO,MAAM,cAAc;;gCAAoC,CAAA;AAC/D,eAAO,MAAM,cAAc;;gCAA6B,CAAA;AACxD,eAAO,MAAM,iBAAiB;;;gCAA6C,CAAA;AAC3E,eAAO,MAAM,eAAe;;;gCAA6C,CAAA;AAMzE,eAAO,MAAM,YAAY;;;gCAAoD,CAAA;AAC7E,eAAO,MAAM,aAAa;;;gCAAoD,CAAA;AAC9E,eAAO,MAAM,WAAW;;gCAAiC,CAAA;AAMzD,eAAO,MAAM,UAAU;;;;;;;;;;gCAKrB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;gCAKvB,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;gCAMrB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;gCAOvB,CAAA;AAMF,eAAO,MAAM,cAAc;;;;gCAIzB,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;;;;;gCAStB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;gCAcxB,CAAA;AAMF,eAAO,MAAM,WAAW;;;;gCAItB,CAAA;AAMF;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAET"}
|
package/dist/tiles/geometry.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { BufferGeometry, Vector3 } from 'three';
|
|
2
|
+
import type { GridCoord } from '../schemas.js';
|
|
3
|
+
export type GetHeightAtOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* index in the tile stack
|
|
6
|
+
* use 0 for the lowest and Infinity for the highest
|
|
7
|
+
* @default infinity
|
|
8
|
+
*/
|
|
9
|
+
stackIndex?: number;
|
|
10
|
+
/**
|
|
11
|
+
* optional target vector that will receive the interpolated face normal at the queried point
|
|
12
|
+
*/
|
|
13
|
+
normalTarget?: Vector3;
|
|
14
|
+
};
|
|
2
15
|
export type Tile = {
|
|
3
16
|
type: string;
|
|
4
17
|
y: number;
|
|
@@ -30,15 +43,7 @@ export declare class TilesGeometry extends BufferGeometry {
|
|
|
30
43
|
bottom: Array<WallData>;
|
|
31
44
|
left: Array<WallData>;
|
|
32
45
|
}>>, mapSizeX: number, mapSizeZ: number);
|
|
33
|
-
|
|
34
|
-
* @param row tile grid row index (Z direction)
|
|
35
|
-
* @param col tile grid column index (X direction)
|
|
36
|
-
* @param stackIndex index in the tile stack
|
|
37
|
-
* @param offsetX world unit offset from tile center X
|
|
38
|
-
* @param offsetZ world unit offset from tile center Z
|
|
39
|
-
* @param normalTarget optional target vector that will receive the interpolated face normal at the queried point
|
|
40
|
-
*/
|
|
41
|
-
getHeight(row: number, col: number, stackIndex?: number, offsetX?: number, offsetZ?: number, normalTarget?: Vector3): number;
|
|
46
|
+
getHeightAt({ row, col, offsetX, offsetZ }: GridCoord, { normalTarget, stackIndex }?: GetHeightAtOptions): number;
|
|
42
47
|
private addVertex;
|
|
43
48
|
private getVertices;
|
|
44
49
|
private getConnectionVertexId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/tiles/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAMd,OAAO,EACR,MAAM,OAAO,CAAA;AAGd,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAoB3F,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAkQxD,qBAAa,aAAc,SAAQ,cAAc;IAe7C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;aAQN,QAAQ,EAAE,MAAM;aAChB,QAAQ,EAAE,MAAM;IAxBlC,SAAgB,SAAS,EAAE,MAAM,CAAA;IACjC,SAAgB,SAAS,EAAE,MAAM,CAAA;IAEjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoB;IAErD,OAAO,CAAC,SAAS,CAAI;IAErB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;IAChE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;gBAG7C,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAChC,KAAK,EAAE,KAAK,CAC3B,KAAK,CAAC;QACJ,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QACpB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QACtB,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QACvB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;KACtB,CAAC,CACH,EACe,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/tiles/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAMd,OAAO,EACR,MAAM,OAAO,CAAA;AAGd,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAoB3F,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAkQxD,qBAAa,aAAc,SAAQ,cAAc;IAe7C,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;aAQN,QAAQ,EAAE,MAAM;aAChB,QAAQ,EAAE,MAAM;IAxBlC,SAAgB,SAAS,EAAE,MAAM,CAAA;IACjC,SAAgB,SAAS,EAAE,MAAM,CAAA;IAEjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoB;IAErD,OAAO,CAAC,SAAS,CAAI;IAErB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;IAChE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAmC;gBAG7C,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAChC,KAAK,EAAE,KAAK,CAC3B,KAAK,CAAC;QACJ,GAAG,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QACpB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QACtB,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;QACvB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;KACtB,CAAC,CACH,EACe,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM;IA0E3B,WAAW,CAChB,EAAE,GAAG,EAAE,GAAG,EAAE,OAAW,EAAE,OAAW,EAAE,EAAE,SAAS,EACjD,EAAE,YAAY,EAAE,UAAqB,EAAE,GAAE,kBAAuB;IAiFlE,OAAO,CAAC,SAAS;IAoGjB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,qBAAqB;CAiB9B"}
|
package/dist/tiles/geometry.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { BufferGeometry, Float32BufferAttribute, Uint16BufferAttribute, } from 'three';
|
|
2
2
|
import { isLayerConnectedToWall } from '../walls/index.js';
|
|
3
|
+
import { clamp } from 'three/src/math/MathUtils.js';
|
|
3
4
|
const MAX_AUTO_CONNECT_HEIGHT_DIFF_RATIO = 1 / 4;
|
|
4
5
|
const MAX_CONNECTION_HEIGHT_DIFF_RATIO = 8;
|
|
5
6
|
function isBetterConnection(newConnection, oldConnection, tileSize) {
|
|
@@ -293,20 +294,12 @@ export class TilesGeometry extends BufferGeometry {
|
|
|
293
294
|
this.computeVertexNormals();
|
|
294
295
|
this.computeTangents();
|
|
295
296
|
}
|
|
296
|
-
|
|
297
|
-
* @param row tile grid row index (Z direction)
|
|
298
|
-
* @param col tile grid column index (X direction)
|
|
299
|
-
* @param stackIndex index in the tile stack
|
|
300
|
-
* @param offsetX world unit offset from tile center X
|
|
301
|
-
* @param offsetZ world unit offset from tile center Z
|
|
302
|
-
* @param normalTarget optional target vector that will receive the interpolated face normal at the queried point
|
|
303
|
-
*/
|
|
304
|
-
getHeight(row, col, stackIndex, offsetX = 0, offsetZ = 0, normalTarget) {
|
|
297
|
+
getHeightAt({ row, col, offsetX = 0, offsetZ = 0 }, { normalTarget, stackIndex = Infinity } = {}) {
|
|
305
298
|
if (col < 0 || col >= this.tiles[0].length || row < 0 || row >= this.tiles.length) {
|
|
306
299
|
throw new Error(`Tile index out of bounds: (row=${row}, col=${col}). Grid size: ${this.tiles.length}x${this.tiles[0].length}`);
|
|
307
300
|
}
|
|
308
301
|
const vertices = this.getVertices(col, row);
|
|
309
|
-
const vertex1 = vertices[stackIndex
|
|
302
|
+
const vertex1 = vertices[clamp(stackIndex, 0, vertices.length - 1)];
|
|
310
303
|
if (vertex1 == null) {
|
|
311
304
|
throw new Error(`No vertex found at stack index "${stackIndex ?? 'any'}" for tile (row=${row}, col=${col}).`);
|
|
312
305
|
}
|
package/dist/tiles/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Material, Mesh } from 'three';
|
|
2
2
|
import { Interpreter } from '../interpreter.js';
|
|
3
|
-
import { TilesGeometry } from './geometry.js';
|
|
4
|
-
import { groundSchema, ceilingSchema } from '../schemas.js';
|
|
3
|
+
import { GetHeightAtOptions, TilesGeometry } from './geometry.js';
|
|
4
|
+
import { groundSchema, ceilingSchema, GridCoord } from '../schemas.js';
|
|
5
5
|
export { groundSchema, ceilingSchema };
|
|
6
6
|
export type TilesMeshOptions = {
|
|
7
7
|
/**
|
|
@@ -13,5 +13,7 @@ export type TilesMeshOptions = {
|
|
|
13
13
|
};
|
|
14
14
|
export declare class TilesMesh extends Mesh<TilesGeometry> {
|
|
15
15
|
constructor(interpreter: Interpreter, material?: Material, options?: TilesMeshOptions);
|
|
16
|
+
getHeightAt(coord: GridCoord, options?: GetHeightAtOptions): number;
|
|
17
|
+
dispose(): void;
|
|
16
18
|
}
|
|
17
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tiles/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,IAAI,EAOL,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAuB,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tiles/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EACR,IAAI,EAOL,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAuB,MAAM,eAAe,CAAA;AAItF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAc,SAAS,EAAE,MAAM,eAAe,CAAA;AAGlF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,CAAA;AAEtC,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;AAyCD,qBAAa,SAAU,SAAQ,IAAI,CAAC,aAAa,CAAC;gBACpC,WAAW,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAkC,EAAE,OAAO,GAAE,gBAAqB;IAyIlH,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAI1D,OAAO,IAAI,IAAI;CAMhB"}
|
package/dist/tiles/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mesh, Texture, MeshBasicMaterial, } from 'three';
|
|
1
|
+
import { Material, Mesh, Texture, MeshBasicMaterial, } from 'three';
|
|
2
2
|
import { TilesGeometry } from './geometry.js';
|
|
3
3
|
import { buildTilesMaterial } from './material.js';
|
|
4
4
|
import { ChartaError } from '../errors.js';
|
|
@@ -66,7 +66,7 @@ export class TilesMesh extends Mesh {
|
|
|
66
66
|
for (let row = 0; row < rows; row++) {
|
|
67
67
|
for (let col = 0; col < cols; col++) {
|
|
68
68
|
// Collect and validate all entries for this cell
|
|
69
|
-
const calls = Array.from(interpreter.getCalls(
|
|
69
|
+
const calls = Array.from(interpreter.getCalls({ row, col }, {
|
|
70
70
|
ground: groundSchema,
|
|
71
71
|
ceiling: ceilingSchema,
|
|
72
72
|
wall: wallSchema,
|
|
@@ -138,4 +138,13 @@ export class TilesMesh extends Mesh {
|
|
|
138
138
|
setupBVH(this.geometry);
|
|
139
139
|
this.raycast = acceleratedRaycast;
|
|
140
140
|
}
|
|
141
|
+
getHeightAt(coord, options) {
|
|
142
|
+
return this.geometry.getHeightAt(coord, options);
|
|
143
|
+
}
|
|
144
|
+
dispose() {
|
|
145
|
+
this.geometry.dispose();
|
|
146
|
+
if (this.material instanceof Material) {
|
|
147
|
+
this.material.dispose();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
141
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/walls/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAER,IAAI,EAGJ,YAAY,EAEZ,YAAY,EAOb,MAAM,OAAO,CAAA;AAEd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EAAe,aAAa,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAGL,UAAU,EACV,YAAY,EACZ,UAAU,EACX,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,CAAA;AAK/C,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,YAAY,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,UAAU,EAAE,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;CAed,CAAA;AAEV,eAAO,MAAM,+BAA+B,QAAQ,CAAA;AAEpD,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACxD,MAAM,EAAE,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,EACtD,GAAG,EAAE,aAAa;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/walls/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAER,IAAI,EAGJ,YAAY,EAEZ,YAAY,EAOb,MAAM,OAAO,CAAA;AAEd,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EAAe,aAAa,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAGL,UAAU,EACV,YAAY,EACZ,UAAU,EACX,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,CAAA;AAK/C,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,YAAY,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,UAAU,EAAE,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;CAed,CAAA;AAEV,eAAO,MAAM,+BAA+B,QAAQ,CAAA;AAEpD,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,aAAa,GAAG,SAAS,EACxC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACxD,MAAM,EAAE,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,WAAW,CAAC,EACtD,GAAG,EAAE,aAAa;YAwFO,YAAY;UACd,YAAY;;;cA8DpC;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,qBAAa,QAAS,SAAQ,IAAI;gBACpB,WAAW,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAkC,EAAE,OAAO,GAAE,eAAoB;CAkTlH;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAGrG"}
|
package/dist/walls/index.js
CHANGED
|
@@ -43,14 +43,17 @@ export function computeWallVerticalBounds(interpreter, tilesGeometry, row, col,
|
|
|
43
43
|
neighborCol--;
|
|
44
44
|
else if (parsed.dir === 'right')
|
|
45
45
|
neighborCol++;
|
|
46
|
-
const [worldCellCenterX, worldCellCenterZ] = interpreter.getWorldCellCenter(row, col);
|
|
47
46
|
const localWallX = ('xOffset' in config ? config.xOffset : 0) * cellSize;
|
|
48
47
|
const localWallZ = ('zOffset' in config ? config.zOffset : 0) * cellSize;
|
|
49
|
-
const worldWallX
|
|
50
|
-
|
|
48
|
+
const { x: worldWallX, z: worldWallZ } = interpreter.gridToWorld({
|
|
49
|
+
row,
|
|
50
|
+
col,
|
|
51
|
+
offsetX: localWallX,
|
|
52
|
+
offsetZ: localWallZ,
|
|
53
|
+
});
|
|
51
54
|
// Determine layer context
|
|
52
|
-
const layersBefore = interpreter.countCalls(
|
|
53
|
-
const layersAfter = interpreter.countCalls(
|
|
55
|
+
const layersBefore = interpreter.countCalls({ row, col }, isLayer, 0, wallIdx);
|
|
56
|
+
const layersAfter = interpreter.countCalls({ row, col }, isLayer, wallIdx + 1);
|
|
54
57
|
const resolveLayer = (explicitY, isTop) => {
|
|
55
58
|
// Case 1: No explicit height -> connect to adjacent layer in current cell
|
|
56
59
|
if (explicitY === undefined) {
|
|
@@ -73,7 +76,7 @@ export function computeWallVerticalBounds(interpreter, tilesGeometry, row, col,
|
|
|
73
76
|
const checkCell = (r, c) => {
|
|
74
77
|
if (r < 0 || r >= rows || c < 0 || c >= cols)
|
|
75
78
|
return;
|
|
76
|
-
const calls = interpreter.getCalls(
|
|
79
|
+
const calls = interpreter.getCalls({ row: r, col: c }, { ground: groundSchema, ceiling: ceilingSchema });
|
|
77
80
|
for (let i = 0; i < calls.length; i++) {
|
|
78
81
|
const [, { y: layerY }] = calls[i];
|
|
79
82
|
const diff = Math.abs(layerY - explicitY);
|
|
@@ -120,7 +123,7 @@ export function computeWallVerticalBounds(interpreter, tilesGeometry, row, col,
|
|
|
120
123
|
if (bottomLayer) {
|
|
121
124
|
const offX = sX + (col - bottomLayer.col) * cellSize;
|
|
122
125
|
const offZ = sZ + (row - bottomLayer.row) * cellSize;
|
|
123
|
-
yStart[k] = tilesGeometry.
|
|
126
|
+
yStart[k] = tilesGeometry.getHeightAt({ row: bottomLayer.row, col: bottomLayer.col, offsetX: offX, offsetZ: offZ }, { stackIndex: bottomLayer.layerIdx });
|
|
124
127
|
}
|
|
125
128
|
else {
|
|
126
129
|
yStart[k] = parsed.bottomY;
|
|
@@ -129,7 +132,7 @@ export function computeWallVerticalBounds(interpreter, tilesGeometry, row, col,
|
|
|
129
132
|
if (topLayer) {
|
|
130
133
|
const offX = sX + (col - topLayer.col) * cellSize;
|
|
131
134
|
const offZ = sZ + (row - topLayer.row) * cellSize;
|
|
132
|
-
yEnd[k] = tilesGeometry.
|
|
135
|
+
yEnd[k] = tilesGeometry.getHeightAt({ row: topLayer.row, col: topLayer.col, offsetX: offX, offsetZ: offZ }, { stackIndex: topLayer.layerIdx });
|
|
133
136
|
}
|
|
134
137
|
else {
|
|
135
138
|
yEnd[k] = parsed.topY;
|
|
@@ -176,7 +179,7 @@ export class WallMesh extends Mesh {
|
|
|
176
179
|
// Validation loop runs in both modes
|
|
177
180
|
for (let row = 0; row < rows; row++) {
|
|
178
181
|
for (let col = 0; col < cols; col++) {
|
|
179
|
-
const entries = interpreter.getCalls(
|
|
182
|
+
const entries = interpreter.getCalls({ row, col }, {
|
|
180
183
|
wall: wallSchema,
|
|
181
184
|
window: windowSchema,
|
|
182
185
|
door: doorSchema,
|
package/dist/water/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { Mesh } from
|
|
2
|
-
import { Interpreter } from
|
|
1
|
+
import { Mesh } from 'three';
|
|
2
|
+
import { Interpreter } from '../interpreter.js';
|
|
3
|
+
import { GetHeightAtOptions, TilesGeometry } from '../tiles/geometry.js';
|
|
4
|
+
import { GridCoord } from '../schemas.js';
|
|
3
5
|
export type WaterMeshOptions = {
|
|
4
6
|
/**
|
|
5
7
|
* Validate-only mode: validates water calls but skips geometry creation.
|
|
@@ -7,10 +9,11 @@ export type WaterMeshOptions = {
|
|
|
7
9
|
*/
|
|
8
10
|
validateOnly?: boolean;
|
|
9
11
|
};
|
|
10
|
-
export declare class WaterMesh extends Mesh {
|
|
12
|
+
export declare class WaterMesh extends Mesh<TilesGeometry> {
|
|
11
13
|
constructor(interpreter: Interpreter, options?: WaterMeshOptions);
|
|
14
|
+
getHeightAt(coord: GridCoord, options?: GetHeightAtOptions): number;
|
|
12
15
|
dispose(): void;
|
|
13
16
|
}
|
|
14
|
-
export * from
|
|
15
|
-
export * from
|
|
17
|
+
export * from './texture.js';
|
|
18
|
+
export * from './material.js';
|
|
16
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/water/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAY,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/water/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAY,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAa,MAAM,sBAAsB,CAAA;AACnF,OAAO,EAAE,SAAS,EAAe,MAAM,eAAe,CAAA;AAGtD,MAAM,MAAM,gBAAgB,GAAG;IAC7B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,CAAA;AAED,qBAAa,SAAU,SAAQ,IAAI,CAAC,aAAa,CAAC;gBACpC,WAAW,EAAE,WAAW,EAAE,OAAO,GAAE,gBAAqB;IAsDpE,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAI1D,OAAO,IAAI,IAAI;CAMhB;AAED,cAAc,cAAc,CAAA;AAC5B,cAAc,eAAe,CAAA"}
|
package/dist/water/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Mesh, Material } from
|
|
2
|
-
import { TilesGeometry } from
|
|
3
|
-
import { waterSchema } from
|
|
4
|
-
import { setupBVH, acceleratedRaycast } from
|
|
1
|
+
import { Mesh, Material } from 'three';
|
|
2
|
+
import { TilesGeometry } from '../tiles/geometry.js';
|
|
3
|
+
import { waterSchema } from '../schemas.js';
|
|
4
|
+
import { setupBVH, acceleratedRaycast } from '../utils/bvh.js';
|
|
5
5
|
export class WaterMesh extends Mesh {
|
|
6
6
|
constructor(interpreter, options = {}) {
|
|
7
7
|
const rows = interpreter.getRows();
|
|
@@ -9,20 +9,18 @@ export class WaterMesh extends Mesh {
|
|
|
9
9
|
// Build tiles only in non-validateOnly mode (expensive allocation)
|
|
10
10
|
let tiles;
|
|
11
11
|
if (!options.validateOnly) {
|
|
12
|
-
tiles = new Array(rows)
|
|
13
|
-
.fill(undefined)
|
|
14
|
-
.map(() => new Array(cols).fill(undefined).map(() => []));
|
|
12
|
+
tiles = new Array(rows).fill(undefined).map(() => new Array(cols).fill(undefined).map(() => []));
|
|
15
13
|
}
|
|
16
14
|
// Validation loop runs in both modes
|
|
17
15
|
for (let row = 0; row < rows; row++) {
|
|
18
16
|
for (let col = 0; col < cols; col++) {
|
|
19
|
-
const entries = interpreter.getCalls(
|
|
17
|
+
const entries = interpreter.getCalls({ row, col }, { water: waterSchema });
|
|
20
18
|
// Only build tile stack in non-validateOnly mode
|
|
21
19
|
if (!options.validateOnly) {
|
|
22
20
|
const stack = [];
|
|
23
21
|
for (const [, parsed] of entries) {
|
|
24
22
|
stack.push({
|
|
25
|
-
type:
|
|
23
|
+
type: 'water',
|
|
26
24
|
y: parsed.y,
|
|
27
25
|
textureId: 0,
|
|
28
26
|
row,
|
|
@@ -42,7 +40,7 @@ export class WaterMesh extends Mesh {
|
|
|
42
40
|
const mapSizeX = cols * cellSize;
|
|
43
41
|
const mapSizeZ = rows * cellSize;
|
|
44
42
|
const geometry = new TilesGeometry(tiles, [], mapSizeX, mapSizeZ);
|
|
45
|
-
interpreter.setAsset(
|
|
43
|
+
interpreter.setAsset('waterGeometry', geometry);
|
|
46
44
|
super(geometry);
|
|
47
45
|
this.renderOrder = 1;
|
|
48
46
|
this.frustumCulled = true;
|
|
@@ -50,6 +48,9 @@ export class WaterMesh extends Mesh {
|
|
|
50
48
|
setupBVH(this.geometry);
|
|
51
49
|
this.raycast = acceleratedRaycast;
|
|
52
50
|
}
|
|
51
|
+
getHeightAt(coord, options) {
|
|
52
|
+
return this.geometry.getHeightAt(coord, options);
|
|
53
|
+
}
|
|
53
54
|
dispose() {
|
|
54
55
|
this.geometry.dispose();
|
|
55
56
|
if (this.material instanceof Material) {
|
|
@@ -57,5 +58,5 @@ export class WaterMesh extends Mesh {
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
export * from
|
|
61
|
-
export * from
|
|
61
|
+
export * from './texture.js';
|
|
62
|
+
export * from './material.js';
|