@drawcall/charta 0.1.8 → 0.1.10

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.
@@ -19,10 +19,10 @@ export class GrassMesh extends InstancedMesh {
19
19
  .fill(undefined)
20
20
  .map(() => new Array(cols).fill(null));
21
21
  let maxBlades = 0;
22
- for (let z = 0; z < rows; z++) {
23
- for (let x = 0; x < cols; x++) {
22
+ for (let row = 0; row < rows; row++) {
23
+ for (let col = 0; col < cols; col++) {
24
24
  const grassParsed = interpreter
25
- .getCalls([z, x], { grass: grassSchema })
25
+ .getCalls([row, col], { grass: grassSchema })
26
26
  .at(-1)?.[1];
27
27
  if (!grassParsed)
28
28
  continue;
@@ -33,8 +33,8 @@ export class GrassMesh extends InstancedMesh {
33
33
  const step = cellSize / subN;
34
34
  const jitterAmp = step * 0.35;
35
35
  // top surface stack index = total number of ground/ceiling - 1
36
- const topStackIndex = Math.max(0, interpreter.countCalls([z, x], (c) => c.name === "ground" || c.name === "ceiling") - 1);
37
- perCell[z][x] = {
36
+ const topStackIndex = Math.max(0, interpreter.countCalls([row, col], (c) => c.name === "ground" || c.name === "ceiling") - 1);
37
+ perCell[row][col] = {
38
38
  subN,
39
39
  jitterAmp,
40
40
  height,
@@ -46,23 +46,23 @@ export class GrassMesh extends InstancedMesh {
46
46
  }
47
47
  }
48
48
  // Compute neighbor flags
49
- function hasGrassCell(z, x) {
50
- return (!(z < 0 || x < 0 || z >= rows || x >= cols) && perCell[z][x] != null);
49
+ function hasGrassCell(row, col) {
50
+ return (!(row < 0 || col < 0 || row >= rows || col >= cols) && perCell[row][col] != null);
51
51
  }
52
- for (let z = 0; z < rows; z++) {
53
- for (let x = 0; x < cols; x++) {
54
- const cell = perCell[z][x];
52
+ for (let row = 0; row < rows; row++) {
53
+ for (let col = 0; col < cols; col++) {
54
+ const cell = perCell[row][col];
55
55
  if (!cell)
56
56
  continue;
57
57
  cell.neighbors = {
58
- top: !hasGrassCell(z - 1, x), // north
59
- right: !hasGrassCell(z, x + 1), // east
60
- bottom: !hasGrassCell(z + 1, x), // south
61
- left: !hasGrassCell(z, x - 1), // west
62
- topLeft: !hasGrassCell(z - 1, x - 1),
63
- topRight: !hasGrassCell(z - 1, x + 1),
64
- bottomRight: !hasGrassCell(z + 1, x + 1),
65
- bottomLeft: !hasGrassCell(z + 1, x - 1),
58
+ top: !hasGrassCell(row - 1, col), // north
59
+ right: !hasGrassCell(row, col + 1), // east
60
+ bottom: !hasGrassCell(row + 1, col), // south
61
+ left: !hasGrassCell(row, col - 1), // west
62
+ topLeft: !hasGrassCell(row - 1, col - 1),
63
+ topRight: !hasGrassCell(row - 1, col + 1),
64
+ bottomRight: !hasGrassCell(row + 1, col + 1),
65
+ bottomLeft: !hasGrassCell(row + 1, col - 1),
66
66
  };
67
67
  }
68
68
  }
@@ -83,17 +83,17 @@ export class GrassMesh extends InstancedMesh {
83
83
  const scale = new Vector3(1, 1, 1);
84
84
  const tilesGeometry = interpreter.getAsset(TilesGeometry, "tilesGeometry");
85
85
  // Single pass generation
86
- for (let z = 0; z < rows; z++) {
87
- for (let x = 0; x < cols; x++) {
88
- const cell = perCell[z][x];
86
+ for (let row = 0; row < rows; row++) {
87
+ for (let col = 0; col < cols; col++) {
88
+ const cell = perCell[row][col];
89
89
  if (!cell)
90
90
  continue;
91
91
  const { subN, jitterAmp, height, width, topStackIndex, neighbors } = cell;
92
92
  const nb = neighbors;
93
93
  const step = cellSize / subN;
94
94
  // Cell center
95
- const cx = (x - cols / 2 + 0.5) * cellSize;
96
- const cz = (z - rows / 2 + 0.5) * cellSize;
95
+ const cx = (col - cols / 2 + 0.5) * cellSize;
96
+ const cz = (row - rows / 2 + 0.5) * cellSize;
97
97
  for (let gz = 0; gz < subN; gz++) {
98
98
  for (let gx = 0; gx < subN; gx++) {
99
99
  // Optimization: Check stochastic rejection early using simplified fade check
@@ -144,7 +144,7 @@ export class GrassMesh extends InstancedMesh {
144
144
  const pz = cz + oz + jz;
145
145
  let baseY = 0;
146
146
  if (tilesGeometry) {
147
- baseY = tilesGeometry.getHeight(x, z, topStackIndex, px - cx, pz - cz);
147
+ baseY = tilesGeometry.getHeight(row, col, topStackIndex, px - cx, pz - cz);
148
148
  }
149
149
  tmpPos.set(px, baseY, pz);
150
150
  // Scale
package/dist/locations.js CHANGED
@@ -51,7 +51,7 @@ export class Locations {
51
51
  stackIndex = layersAfter > 0 ? 0 : 0;
52
52
  }
53
53
  const tilesGeometry = this.interpreter.getAsset(TilesGeometry, 'tilesGeometry');
54
- const y = tilesGeometry?.getHeight(col, row, stackIndex, 0, 0) ?? 0;
54
+ const y = tilesGeometry?.getHeight(row, col, stackIndex, 0, 0) ?? 0;
55
55
  target.set(x, y, z);
56
56
  return target;
57
57
  }
@@ -86,7 +86,7 @@ export class PillarMesh extends InstancedMesh {
86
86
  const tilesGeometry = interpreter.getAsset(TilesGeometry, 'tilesGeometry', loc);
87
87
  if (!tilesGeometry)
88
88
  continue;
89
- bottomY = tilesGeometry.getHeight(col, row, bottomStackIndex, offsetX, offsetZ);
89
+ bottomY = tilesGeometry.getHeight(row, col, bottomStackIndex, offsetX, offsetZ);
90
90
  }
91
91
  let topStackIndex;
92
92
  if (topY == null) {
@@ -100,7 +100,7 @@ export class PillarMesh extends InstancedMesh {
100
100
  const tilesGeometry = interpreter.getAsset(TilesGeometry, 'tilesGeometry', loc);
101
101
  if (!tilesGeometry)
102
102
  continue;
103
- topY = tilesGeometry.getHeight(col, row, topStackIndex, offsetX, offsetZ);
103
+ topY = tilesGeometry.getHeight(row, col, topStackIndex, offsetX, offsetZ);
104
104
  }
105
105
  // Support "negative pillars" by swapping
106
106
  if (topY < bottomY) {
@@ -77,7 +77,7 @@ export class PlaceGroup extends Group {
77
77
  py = opts.fixedY;
78
78
  }
79
79
  else {
80
- py = tilesGeometry.getHeight(cell.col, cell.row, opts.layerIndex, offsetX, offsetZ, normal);
80
+ py = tilesGeometry.getHeight(cell.row, cell.col, opts.layerIndex, offsetX, offsetZ, normal);
81
81
  }
82
82
  const pos = new Vector3(px, py, pz);
83
83
  const quat = new Quaternion();
@@ -111,22 +111,22 @@ export class PlaceGroup extends Group {
111
111
  const scale = Math.min(sFactorX ?? sFactorZ ?? 1, sFactorZ ?? sFactorX ?? 1);
112
112
  return new Vector3(scale, scale, scale);
113
113
  };
114
- for (let z = 0; z < rows; z++) {
115
- for (let x = 0; x < cols; x++) {
116
- const scatterEntries = interpreter.getCalls([z, x], {
114
+ for (let row = 0; row < rows; row++) {
115
+ for (let col = 0; col < cols; col++) {
116
+ const scatterEntries = interpreter.getCalls([row, col], {
117
117
  scatter: scatterSchema,
118
118
  });
119
- const placeEntries = interpreter.getCalls([z, x], {
119
+ const placeEntries = interpreter.getCalls([row, col], {
120
120
  place: placeSchema,
121
121
  });
122
122
  if (scatterEntries.length === 0 && placeEntries.length === 0)
123
123
  continue;
124
- const cx = (x - cols / 2 + 0.5) * cellSize;
125
- const cz = (z - rows / 2 + 0.5) * cellSize;
124
+ const cx = (col - cols / 2 + 0.5) * cellSize;
125
+ const cz = (row - rows / 2 + 0.5) * cellSize;
126
126
  const half = cellSize * 0.5;
127
127
  // scatter: randomized distribution, density is count for now
128
128
  for (const [, parsed, callIdx, loc] of scatterEntries) {
129
- const layerIndex = interpreter.countCalls([z, x], (c) => c.name === 'ground' || c.name === 'ceiling', 0, callIdx) - 1;
129
+ const layerIndex = interpreter.countCalls([row, col], (c) => c.name === 'ground' || c.name === 'ceiling', 0, callIdx) - 1;
130
130
  const prefabName = `${parsed.model}Prefab`;
131
131
  const batchBuilder = interpreter.getAsset(PrefabBatchBuilder, prefabName, loc);
132
132
  if (!batchBuilder)
@@ -135,7 +135,7 @@ export class PlaceGroup extends Group {
135
135
  const usualSize = new Vector3();
136
136
  usualSize.copy(batchBuilder.prefabSize);
137
137
  const base = hashStringToUint32(parsed.model);
138
- const seed = hashNumbersToUint32(base, z, x);
138
+ const seed = hashNumbersToUint32(base, row, col);
139
139
  const rng = createRng(seed);
140
140
  // area-based density: items per m^2
141
141
  // expected = density * area; stochastic rounding using seeded rng
@@ -161,7 +161,7 @@ export class PlaceGroup extends Group {
161
161
  const px = cx + ox;
162
162
  const pz = cz + oz;
163
163
  const yaw = yawMin === yawMax ? yawMin : yawMin + (yawMax - yawMin) * rng();
164
- const { pos, quat, scl } = computeTransform(px, pz, { row: z, col: x, center: [cx, cz] }, {
164
+ const { pos, quat, scl } = computeTransform(px, pz, { row, col, center: [cx, cz] }, {
165
165
  alignMode,
166
166
  yaw,
167
167
  useFixedY: useFixedY,
@@ -181,13 +181,13 @@ export class PlaceGroup extends Group {
181
181
  }
182
182
  // place: exact in-cell placement
183
183
  for (const [, parsed, callIdx, loc] of placeEntries) {
184
- const layerIndex = interpreter.countCalls([z, x], (c) => c.name === 'ground' || c.name === 'ceiling', 0, callIdx) - 1;
184
+ const layerIndex = interpreter.countCalls([row, col], (c) => c.name === 'ground' || c.name === 'ceiling', 0, callIdx) - 1;
185
185
  const px = cx + (parsed.offsetX ?? 0);
186
186
  const pz = cz + (parsed.offsetZ ?? 0);
187
187
  // In place command, yaw is exact, no min/max range
188
188
  const yaw = parsed.yaw ?? 0;
189
189
  const alignMode = (parsed.align ?? 'up').toLowerCase();
190
- const { pos, quat, scl } = computeTransform(px, pz, { row: z, col: x, center: [cx, cz] }, {
190
+ const { pos, quat, scl } = computeTransform(px, pz, { row, col, center: [cx, cz] }, {
191
191
  alignMode,
192
192
  yaw,
193
193
  useFixedY: parsed.bottomY != null,
@@ -3,8 +3,8 @@ export type Tile = {
3
3
  type: string;
4
4
  y: number;
5
5
  textureId: number;
6
- cellIndexX: number;
7
- cellIndexZ: number;
6
+ row: number;
7
+ col: number;
8
8
  };
9
9
  export type WallData = {
10
10
  topY: number;
@@ -31,14 +31,14 @@ export declare class TilesGeometry extends BufferGeometry {
31
31
  left: Array<WallData>;
32
32
  }>>, mapSizeX: number, mapSizeZ: number);
33
33
  /**
34
- * @param xIndex tile grid x index
35
- * @param zIndex tile grid z index
34
+ * @param row tile grid row index (Z direction)
35
+ * @param col tile grid column index (X direction)
36
36
  * @param stackIndex index in the tile stack
37
37
  * @param offsetX world unit offset from tile center X
38
38
  * @param offsetZ world unit offset from tile center Z
39
39
  * @param normalTarget optional target vector that will receive the interpolated face normal at the queried point
40
40
  */
41
- getHeight(xIndex: number, zIndex: number, stackIndex: number, offsetX: number, offsetZ: number, normalTarget?: Vector3): number;
41
+ getHeight(row: number, col: number, stackIndex?: number, offsetX?: number, offsetZ?: number, normalTarget?: Vector3): number;
42
42
  private addVertex;
43
43
  private getVertices;
44
44
  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,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAoBzG,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;IA0ElC;;;;;;;OAOG;IACI,SAAS,CACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,OAAO;IAmFxB,OAAO,CAAC,SAAS;IAoGjB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,qBAAqB;CAsB9B"}
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;IA0ElC;;;;;;;OAOG;IACI,SAAS,CACd,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,GAAE,MAAU,EACnB,OAAO,GAAE,MAAU,EACnB,YAAY,CAAC,EAAE,OAAO;IAqFxB,OAAO,CAAC,SAAS;IAoGjB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,qBAAqB;CAiB9B"}
@@ -67,8 +67,8 @@ function isBlockingWall(wall, tile, tileSize) {
67
67
  return isLayerConnectedToWall(wall.topY, wall.bottomY, tile.y, tileSize);
68
68
  }
69
69
  function getRelevantWallIndices(tile, vertexX, vertexZ, cellSizeX, cellSizeZ) {
70
- const centerX = computeMeter('x', tile.cellIndexX, cellSizeX);
71
- const centerZ = computeMeter('z', tile.cellIndexZ, cellSizeZ);
70
+ const centerX = computeMeter('x', tile.col, cellSizeX);
71
+ const centerZ = computeMeter('z', tile.row, cellSizeZ);
72
72
  const dx = vertexX - centerX;
73
73
  const dz = vertexZ - centerZ;
74
74
  const eps = 1e-3;
@@ -266,17 +266,17 @@ export class TilesGeometry extends BufferGeometry {
266
266
  .fill(undefined)
267
267
  .map(() => new Array(tiles[0].length * 2 + 1).fill(undefined).map(() => []));
268
268
  const indices = [];
269
- for (let tileIZ = 0; tileIZ < tiles.length; tileIZ++) {
270
- const tileRow = tiles[tileIZ];
271
- for (let tileIX = 0; tileIX < tileRow.length; tileIX++) {
272
- const tileStack = tileRow[tileIX];
273
- for (let tileIY = 0; tileIY < tileStack.length; tileIY++) {
274
- const centerVertexId = this.addVertex(tileIX, tileIZ, undefined, tileStack[tileIY]);
269
+ for (let row = 0; row < tiles.length; row++) {
270
+ const tileRow = tiles[row];
271
+ for (let col = 0; col < tileRow.length; col++) {
272
+ const tileStack = tileRow[col];
273
+ for (let stackIdx = 0; stackIdx < tileStack.length; stackIdx++) {
274
+ const centerVertexId = this.addVertex(col, row, undefined, tileStack[stackIdx]);
275
275
  for (let i = 0; i < 8; i += 2) {
276
276
  const a = centerVertexId;
277
- const b = this.getConnectionVertexId(tileIX, tileIY, tileIZ, (i + 0));
278
- const c = this.getConnectionVertexId(tileIX, tileIY, tileIZ, (i + 1));
279
- const d = this.getConnectionVertexId(tileIX, tileIY, tileIZ, ((i + 2) % 8));
277
+ const b = this.getConnectionVertexId(col, stackIdx, row, (i + 0));
278
+ const c = this.getConnectionVertexId(col, stackIdx, row, (i + 1));
279
+ const d = this.getConnectionVertexId(col, stackIdx, row, ((i + 2) % 8));
280
280
  // First triangle
281
281
  indices.push(a, c, b);
282
282
  // Second triangle
@@ -294,24 +294,24 @@ export class TilesGeometry extends BufferGeometry {
294
294
  this.computeTangents();
295
295
  }
296
296
  /**
297
- * @param xIndex tile grid x index
298
- * @param zIndex tile grid z index
297
+ * @param row tile grid row index (Z direction)
298
+ * @param col tile grid column index (X direction)
299
299
  * @param stackIndex index in the tile stack
300
300
  * @param offsetX world unit offset from tile center X
301
301
  * @param offsetZ world unit offset from tile center Z
302
302
  * @param normalTarget optional target vector that will receive the interpolated face normal at the queried point
303
303
  */
304
- getHeight(xIndex, zIndex, stackIndex, offsetX, offsetZ, normalTarget) {
305
- if (xIndex < 0 || xIndex >= this.tiles[0].length || zIndex < 0 || zIndex >= this.tiles.length) {
306
- throw new Error(`Tile index out of bounds: (${xIndex}, ${zIndex}). Grid size: ${this.tiles[0].length}x${this.tiles.length}`);
304
+ getHeight(row, col, stackIndex, offsetX = 0, offsetZ = 0, normalTarget) {
305
+ if (col < 0 || col >= this.tiles[0].length || row < 0 || row >= this.tiles.length) {
306
+ throw new Error(`Tile index out of bounds: (row=${row}, col=${col}). Grid size: ${this.tiles.length}x${this.tiles[0].length}`);
307
307
  }
308
- const vertices = this.getVertices(xIndex, zIndex);
309
- const vertex1 = vertices[stackIndex];
308
+ const vertices = this.getVertices(col, row);
309
+ const vertex1 = vertices[stackIndex ?? vertices.length - 1];
310
310
  if (vertex1 == null) {
311
- throw new Error(`No vertex found at stack index ${stackIndex} for tile (${xIndex}, ${zIndex}).`);
311
+ throw new Error(`No vertex found at stack index "${stackIndex ?? 'any'}" for tile (row=${row}, col=${col}).`);
312
312
  }
313
- const centerX = computeMeter('x', xIndex, this.cellSizeX) - this.mapSizeX / 2;
314
- const centerZ = computeMeter('z', zIndex, this.cellSizeZ) - this.mapSizeZ / 2;
313
+ const centerX = computeMeter('x', col, this.cellSizeX) - this.mapSizeX / 2;
314
+ const centerZ = computeMeter('z', row, this.cellSizeZ) - this.mapSizeZ / 2;
315
315
  const worldX = centerX + offsetX;
316
316
  const worldZ = centerZ + offsetZ;
317
317
  let tileOffsetX = offsetX;
@@ -331,10 +331,10 @@ export class TilesGeometry extends BufferGeometry {
331
331
  const directionVertex2 = triangleIndex;
332
332
  const directionVertex3 = ((triangleIndex + 1) % 8);
333
333
  const tile = vertex1.relatedTiles[0];
334
- const vertex2 = this.getVertices(xIndex, zIndex, directionVertex2).find((vertex) => vertex.relatedTiles.includes(tile));
335
- const vertex3 = this.getVertices(xIndex, zIndex, directionVertex3).find((vertex) => vertex.relatedTiles.includes(tile));
334
+ const vertex2 = this.getVertices(col, row, directionVertex2).find((vertex) => vertex.relatedTiles.includes(tile));
335
+ const vertex3 = this.getVertices(col, row, directionVertex3).find((vertex) => vertex.relatedTiles.includes(tile));
336
336
  if (vertex2 == null || vertex3 == null) {
337
- throw new Error(`Failed to find vertices for triangle at tile (${xIndex}, ${zIndex}) stack ${stackIndex} direction ${triangleIndex}.`);
337
+ throw new Error(`Failed to find vertices for triangle at tile (row=${row}, col=${col}) stack "${stackIndex ?? 'any'}" direction ${triangleIndex}.`);
338
338
  }
339
339
  const [x1, y1_pos, z1] = vertex1.position;
340
340
  const [x2, y2_pos, z2] = vertex2.position;
@@ -365,10 +365,10 @@ export class TilesGeometry extends BufferGeometry {
365
365
  }
366
366
  return w1 * y1_pos + w2 * y2_pos + w3 * y3_pos;
367
367
  }
368
- addVertex(cellIndexX, cellIndexZ, direction, tile, connections) {
368
+ addVertex(col, row, direction, tile, connections) {
369
369
  const id = this.idCounter++;
370
- const xMeter = computeMeter('x', cellIndexX, this.cellSizeX, direction);
371
- const zMeter = computeMeter('z', cellIndexZ, this.cellSizeZ, direction);
370
+ const xMeter = computeMeter('x', col, this.cellSizeX, direction);
371
+ const zMeter = computeMeter('z', row, this.cellSizeZ, direction);
372
372
  let filteredRelatedTiles;
373
373
  let relatedTiles;
374
374
  if (connections == null) {
@@ -380,7 +380,7 @@ export class TilesGeometry extends BufferGeometry {
380
380
  const removeCoordinateSet = new Set();
381
381
  let blockingTile;
382
382
  for (const relatedTile of relatedTiles) {
383
- const tileWalls = this.walls[relatedTile.cellIndexZ]?.[relatedTile.cellIndexX];
383
+ const tileWalls = this.walls[relatedTile.row]?.[relatedTile.col];
384
384
  if (!tileWalls)
385
385
  continue;
386
386
  const relevantIndices = getRelevantWallIndices(relatedTile, xMeter, zMeter, this.cellSizeX, this.cellSizeZ);
@@ -392,9 +392,9 @@ export class TilesGeometry extends BufferGeometry {
392
392
  if (hasBlockingWall) {
393
393
  causesBlocking = true;
394
394
  // Remove neighbor in direction i
395
- const nx = relatedTile.cellIndexX + directionXOffsetMap[(i * 2)] * 2;
396
- const nz = relatedTile.cellIndexZ + directionZOffsetMap[(i * 2)] * 2;
397
- removeCoordinateSet.add(`${nx},${nz}`);
395
+ const nc = relatedTile.col + directionXOffsetMap[(i * 2)] * 2;
396
+ const nr = relatedTile.row + directionZOffsetMap[(i * 2)] * 2;
397
+ removeCoordinateSet.add(`${nr},${nc}`);
398
398
  // Check secondary blocking (diagonal)
399
399
  const nextI = (i + 1) % 4;
400
400
  const nextDir = wallDirections[nextI];
@@ -402,9 +402,9 @@ export class TilesGeometry extends BufferGeometry {
402
402
  const hasNextBlockingWall = tileWalls[nextDir].some((wall) => isBlockingWall(wall, relatedTile, nextWallSize));
403
403
  if (hasNextBlockingWall) {
404
404
  const diagDir = (i * 2 + 1);
405
- const ndx = relatedTile.cellIndexX + directionXOffsetMap[diagDir] * 2;
406
- const ndz = relatedTile.cellIndexZ + directionZOffsetMap[diagDir] * 2;
407
- removeCoordinateSet.add(`${ndx},${ndz}`);
405
+ const ndc = relatedTile.col + directionXOffsetMap[diagDir] * 2;
406
+ const ndr = relatedTile.row + directionZOffsetMap[diagDir] * 2;
407
+ removeCoordinateSet.add(`${ndr},${ndc}`);
408
408
  }
409
409
  }
410
410
  }
@@ -412,7 +412,7 @@ export class TilesGeometry extends BufferGeometry {
412
412
  blockingTile = relatedTile;
413
413
  }
414
414
  }
415
- filteredRelatedTiles = computeConnectedTiles(blockingTile ?? tile, connections, (newTile) => !removeCoordinateSet.has(`${newTile.cellIndexX},${newTile.cellIndexZ}`));
415
+ filteredRelatedTiles = computeConnectedTiles(blockingTile ?? tile, connections, (newTile) => !removeCoordinateSet.has(`${newTile.row},${newTile.col}`));
416
416
  }
417
417
  const yMeter = filteredRelatedTiles.length === 0
418
418
  ? tile.y
@@ -427,7 +427,7 @@ export class TilesGeometry extends BufferGeometry {
427
427
  this.positions.push(...position);
428
428
  const uv = [xMeter, zMeter];
429
429
  this.uvs.push(...uv);
430
- this.getVertices(cellIndexX, cellIndexZ, direction).push({
430
+ this.getVertices(col, row, direction).push({
431
431
  position,
432
432
  textureStrength,
433
433
  uv,
@@ -436,27 +436,27 @@ export class TilesGeometry extends BufferGeometry {
436
436
  });
437
437
  return id;
438
438
  }
439
- getVertices(cellIndexX, cellIndexZ, direction) {
440
- let vertexIndexX = cellIndexX * 2 + 1;
441
- let vertexIndexZ = cellIndexZ * 2 + 1;
439
+ getVertices(col, row, direction) {
440
+ let vertexCol = col * 2 + 1;
441
+ let vertexRow = row * 2 + 1;
442
442
  if (direction != null) {
443
- vertexIndexX += directionXOffsetMap[direction] * 2;
444
- vertexIndexZ += directionZOffsetMap[direction] * 2;
443
+ vertexCol += directionXOffsetMap[direction] * 2;
444
+ vertexRow += directionZOffsetMap[direction] * 2;
445
445
  }
446
- return this.vertices[vertexIndexZ][vertexIndexX];
446
+ return this.vertices[vertexRow][vertexCol];
447
447
  }
448
- getConnectionVertexId(cellIndexX, cellIndeY, cellIndexZ, direction) {
449
- const tile = this.tiles[cellIndexZ][cellIndexX][cellIndeY];
450
- let vertexId = this.getVertices(cellIndexX, cellIndexZ, direction).find(({ relatedTiles: connectedTiles }) => connectedTiles.includes(tile))?.id;
448
+ getConnectionVertexId(col, stackIndex, row, direction) {
449
+ const tile = this.tiles[row][col][stackIndex];
450
+ let vertexId = this.getVertices(col, row, direction).find(({ relatedTiles: connectedTiles }) => connectedTiles.includes(tile))?.id;
451
451
  if (vertexId == null) {
452
452
  const connections = [];
453
453
  for (const [xOffset, zOffset] of directionXConnectionIndexOffsetMap[direction]) {
454
- connections.push(...(this.xConnections[zOffset + cellIndexZ]?.[xOffset + cellIndexX] ?? []));
454
+ connections.push(...(this.xConnections[zOffset + row]?.[xOffset + col] ?? []));
455
455
  }
456
456
  for (const [xOffset, zOffset] of directionZConnectionIndexOffsetMap[direction]) {
457
- connections.push(...(this.zConnections[zOffset + cellIndexZ]?.[xOffset + cellIndexX] ?? []));
457
+ connections.push(...(this.zConnections[zOffset + row]?.[xOffset + col] ?? []));
458
458
  }
459
- vertexId = this.addVertex(cellIndexX, cellIndexZ, direction, tile, connections);
459
+ vertexId = this.addVertex(col, row, direction, tile, connections);
460
460
  }
461
461
  return vertexId;
462
462
  }
@@ -1,6 +1,7 @@
1
1
  import { Material, Mesh } from 'three';
2
2
  import { Interpreter } from '../interpreter.js';
3
3
  import { coerce } from 'zod';
4
+ import { TilesGeometry } from './geometry.js';
4
5
  export declare const groundSchema: import("zod").ZodObject<{
5
6
  texture: import("zod").ZodString;
6
7
  y: coerce.ZodCoercedNumber<unknown>;
@@ -9,10 +10,8 @@ export declare const ceilingSchema: import("zod").ZodObject<{
9
10
  texture: import("zod").ZodString;
10
11
  y: coerce.ZodCoercedNumber<unknown>;
11
12
  }, import("zod/v4/core").$strip>;
12
- export type TilesMeshOptions = {
13
- materialSharpness?: number;
14
- };
15
- export declare class TilesMesh extends Mesh {
13
+ export type TilesMeshOptions = {};
14
+ export declare class TilesMesh extends Mesh<TilesGeometry> {
16
15
  constructor(interpreter: Interpreter, material?: Material, options?: TilesMeshOptions);
17
16
  }
18
17
  //# 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,MAAM,EAAkB,MAAM,KAAK,CAAA;AAO5C,eAAO,MAAM,YAAY;;;gCAAoD,CAAA;AAC7E,eAAO,MAAM,aAAa;;;gCAAoD,CAAA;AAE9E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,CAAA;AAyCD,qBAAa,SAAU,SAAQ,IAAI;gBACrB,WAAW,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAkC,EAAE,OAAO,GAAE,gBAAqB;CA6GnH"}
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,MAAM,EAAkB,MAAM,KAAK,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAuB,MAAM,eAAe,CAAA;AAMlE,eAAO,MAAM,YAAY;;;gCAAoD,CAAA;AAC7E,eAAO,MAAM,aAAa;;;gCAAoD,CAAA;AAE9E,MAAM,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAyCjC,qBAAa,SAAU,SAAQ,IAAI,CAAC,aAAa,CAAC;gBACpC,WAAW,EAAE,WAAW,EAAE,QAAQ,GAAE,QAAkC,EAAE,OAAO,GAAE,gBAAqB;CA4GnH"}
@@ -34,7 +34,6 @@ function resolveHeights(position, items, interpreter, reverse) {
34
34
  }
35
35
  export class TilesMesh extends Mesh {
36
36
  constructor(interpreter, material = new MeshBasicMaterial(), options = {}) {
37
- super();
38
37
  const rows = interpreter.getRows();
39
38
  const cols = interpreter.getCols();
40
39
  // Helper to manage texture indices on the fly
@@ -58,21 +57,21 @@ export class TilesMesh extends Mesh {
58
57
  left: [],
59
58
  right: [],
60
59
  })));
61
- for (let z = 0; z < rows; z++) {
62
- for (let x = 0; x < cols; x++) {
60
+ for (let row = 0; row < rows; row++) {
61
+ for (let col = 0; col < cols; col++) {
63
62
  // 1. Collect all entries for this cell
64
- const calls = Array.from(interpreter.getCalls([z, x], {
63
+ const calls = Array.from(interpreter.getCalls([row, col], {
65
64
  ground: groundSchema,
66
65
  ceiling: ceilingSchema,
67
66
  wall: wallSchema,
68
67
  }));
69
68
  // 2. Compute wall heights using the helper
70
- const bottomYs = resolveHeights([z, x], calls.map(([_1, parsed, _2, loc]) => ({
69
+ const bottomYs = resolveHeights([row, col], calls.map(([_1, parsed, _2, loc]) => ({
71
70
  loc,
72
71
  layerY: 'y' in parsed ? parsed.y : undefined,
73
72
  explicitWallY: 'bottomY' in parsed ? parsed.bottomY : undefined,
74
73
  })), interpreter, false);
75
- const topYs = resolveHeights([z, x], calls.map(([_1, parsed, _2, loc]) => ({
74
+ const topYs = resolveHeights([row, col], calls.map(([_1, parsed, _2, loc]) => ({
76
75
  loc,
77
76
  layerY: 'y' in parsed ? parsed.y : undefined,
78
77
  explicitWallY: 'topY' in parsed ? parsed.topY : undefined,
@@ -91,18 +90,18 @@ export class TilesMesh extends Mesh {
91
90
  [bottomY, topY] = [topY, bottomY];
92
91
  }
93
92
  const dir = parsed.dir;
94
- if (walls[z][x][dir]) {
95
- walls[z][x][dir].push({ bottomY, topY });
93
+ if (walls[row][col][dir]) {
94
+ walls[row][col][dir].push({ bottomY, topY });
96
95
  }
97
96
  }
98
97
  else {
99
98
  // Ground or Ceiling
100
- tiles[z][x].push({
99
+ tiles[row][col].push({
101
100
  type: name,
102
101
  y: parsed.y,
103
102
  textureId: getTextureIndex(parsed.texture, loc),
104
- cellIndexX: x,
105
- cellIndexZ: z,
103
+ row,
104
+ col,
106
105
  });
107
106
  }
108
107
  }
@@ -110,7 +109,7 @@ export class TilesMesh extends Mesh {
110
109
  }
111
110
  const cellSize = interpreter.getCellSize();
112
111
  const geometry = new TilesGeometry(tiles, walls, cols * cellSize, rows * cellSize);
113
- this.geometry = geometry;
112
+ super(geometry);
114
113
  interpreter.setAsset('tilesGeometry', geometry);
115
114
  // Build texture array from interpreter assets using encountered material names in insertion order
116
115
  const texturesInOrder = Array.from(textureIndex.keys()).sort((a, b) => textureIndex.get(a) - textureIndex.get(b));
@@ -129,7 +129,7 @@ export function computeWallVerticalBounds(interpreter, tilesGeometry, row, col,
129
129
  if (bottomLayer) {
130
130
  const offX = sX + (col - bottomLayer.col) * cellSize;
131
131
  const offZ = sZ + (row - bottomLayer.row) * cellSize;
132
- yStart[k] = tilesGeometry.getHeight(bottomLayer.col, bottomLayer.row, bottomLayer.layerIdx, offX, offZ);
132
+ yStart[k] = tilesGeometry.getHeight(bottomLayer.row, bottomLayer.col, bottomLayer.layerIdx, offX, offZ);
133
133
  }
134
134
  else {
135
135
  yStart[k] = parsed.bottomY;
@@ -138,7 +138,7 @@ export function computeWallVerticalBounds(interpreter, tilesGeometry, row, col,
138
138
  if (topLayer) {
139
139
  const offX = sX + (col - topLayer.col) * cellSize;
140
140
  const offZ = sZ + (row - topLayer.row) * cellSize;
141
- yEnd[k] = tilesGeometry.getHeight(topLayer.col, topLayer.row, topLayer.layerIdx, offX, offZ);
141
+ yEnd[k] = tilesGeometry.getHeight(topLayer.row, topLayer.col, topLayer.layerIdx, offX, offZ);
142
142
  }
143
143
  else {
144
144
  yEnd[k] = parsed.topY;
@@ -6,24 +6,24 @@ export class WaterMesh extends Mesh {
6
6
  constructor(interpreter, options = {}) {
7
7
  const rows = interpreter.getRows();
8
8
  const cols = interpreter.getCols();
9
- // Build tiles[z][x] => Array<Tile>, containing only water tiles
9
+ // Build tiles[row][col] => Array<Tile>, containing only water tiles
10
10
  const tiles = new Array(rows)
11
11
  .fill(undefined)
12
12
  .map(() => new Array(cols).fill(undefined).map(() => []));
13
- for (let z = 0; z < rows; z++) {
14
- for (let x = 0; x < cols; x++) {
15
- const entries = interpreter.getCalls([z, x], { water: waterSchema });
13
+ for (let row = 0; row < rows; row++) {
14
+ for (let col = 0; col < cols; col++) {
15
+ const entries = interpreter.getCalls([row, col], { water: waterSchema });
16
16
  const stack = [];
17
17
  for (const [, parsed] of entries) {
18
18
  stack.push({
19
19
  type: "water",
20
20
  y: parsed.y,
21
21
  textureId: 0,
22
- cellIndexX: x,
23
- cellIndexZ: z,
22
+ row,
23
+ col,
24
24
  });
25
25
  }
26
- tiles[z][x] = stack;
26
+ tiles[row][col] = stack;
27
27
  }
28
28
  }
29
29
  const cellSize = interpreter.getCellSize();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawcall/charta",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "author": "Bela Bohlender",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://drawcall.ai",