feat(tile): render tiles with the mesh generator
Replace the per-shape tile geometries with @tts/mesh extrusion, honoring the tile type and stretch aspect ratio. Add extrudeShapeParts so the caps carry the texture while the walls are solid white, matching TTS tinting. Fix bottom-face UVs to mirror horizontally and make wall UVs inherit the front mapping independent of z.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { extrudeShape, mergeFaces } from './extrude.js';
|
||||
import { rectShape, hexShape, circleShape, roundedRectShape } from './shapes.js';
|
||||
import { extrudeShape, extrudeShapeParts, mergeFaces } from './extrude.js';
|
||||
import { rectShape, hexShape, circleShape, roundedRectShape, scaleShape } from './shapes.js';
|
||||
import { capFaces } from './tessellate.js';
|
||||
import { wallFaces } from './walls.js';
|
||||
import type { FaceGeometry } from './types.js';
|
||||
@@ -44,6 +44,36 @@ describe('extrudeShape', () => {
|
||||
expect(geo.uvs[1]).toBeCloseTo(0, 5);
|
||||
expect(geo.uvs[4]).toBeCloseTo(2, 5);
|
||||
});
|
||||
|
||||
it('produces non-square geometry when scaled by an aspect ratio', () => {
|
||||
const geo = extrudeShape(scaleShape(rectShape(2, 2), 2, 1), { height: 0.5 });
|
||||
let minX = Infinity;
|
||||
let maxX = -Infinity;
|
||||
let minY = Infinity;
|
||||
let maxY = -Infinity;
|
||||
for (let i = 0; i < geo.positions.length; i += 3) {
|
||||
minX = Math.min(minX, geo.positions[i]!);
|
||||
maxX = Math.max(maxX, geo.positions[i]!);
|
||||
minY = Math.min(minY, geo.positions[i + 1]!);
|
||||
maxY = Math.max(maxY, geo.positions[i + 1]!);
|
||||
}
|
||||
expect(maxX - minX).toBeCloseTo(4, 5); // 2 * aspect 2
|
||||
expect(maxY - minY).toBeCloseTo(2, 5);
|
||||
});
|
||||
});
|
||||
|
||||
describe('extrudeShapeParts', () => {
|
||||
it('returns caps and walls as separate geometries', () => {
|
||||
const { caps, walls } = extrudeShapeParts(rectShape(2, 2), { height: 1 });
|
||||
// Caps: 2 faces * 4 outline points = 8 vertices.
|
||||
expect(caps.positions.length / 3).toBe(8);
|
||||
// Walls: 4 outline points * 2 vertices = 8 vertices.
|
||||
expect(walls.positions.length / 3).toBe(8);
|
||||
// Combined, they match `extrudeShape`.
|
||||
const combined = extrudeShape(rectShape(2, 2), { height: 1 });
|
||||
expect(caps.positions.length + walls.positions.length).toBe(combined.positions.length);
|
||||
expect(caps.indices.length + walls.indices.length).toBe(combined.indices.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mergeFaces', () => {
|
||||
|
||||
Reference in New Issue
Block a user