house/src/interiors.ts

101 lines
3.2 KiB
TypeScript

import {
Mesh,
Nullable,
Scene,
StandardMaterial,
Texture,
} from '@babylonjs/core/Legacy/legacy';
import { adjust, box, subtractMany } from './shapes.js';
export interface SurfaceOptions {
height?: number,
thickness?: number,
texturePath?: string,
};
export function attachTexture(b: Mesh, scene: Scene, texturePath: string | undefined): Mesh {
if (texturePath !== void 0) {
const mat = new StandardMaterial(b.name + "_mat", scene);
mat.diffuseTexture = new Texture(texturePath, scene);
b.material = mat;
}
return b;
}
export const DEFAULT_THICKNESS = 0.125;
export async function wall(name: string, length: number, scene: Scene, options: SurfaceOptions = {}): Promise<Mesh> {
return attachTexture(box(name, length, options.height ?? 2.90, options.thickness ?? DEFAULT_THICKNESS),
scene,
options.texturePath);
}
export async function floor(name: string, width: number, depth: number, scene: Scene, options: SurfaceOptions = {}): Promise<Mesh> {
return attachTexture(box(name, width, options.thickness ?? DEFAULT_THICKNESS, depth),
scene,
options.texturePath);
}
export type Wall = {
texture: string,
thickness?: number,
holes: Array<Mesh>,
};
export async function room(name: string, width: number, depth: number, scene: Scene,
floorTexture: string,
ceilingTexture: string,
wall0: Nullable<Wall>,
wall1: Nullable<Wall>,
wall2: Nullable<Wall>,
wall3: Nullable<Wall>): Promise<Mesh> {
const th = (wallDetails: Wall): number => wallDetails.thickness ?? DEFAULT_THICKNESS;
const mkw = async (n: number, width: number, wallDetails: Wall): Promise<Mesh> => {
return adjust(subtractMany,
await wall(`${name}_${n}`, width, scene, {
texturePath: wallDetails.texture,
thickness: wallDetails.thickness,
}),
... wallDetails.holes);
};
const f = await floor(name +"_f", width, depth, scene, { texturePath: floorTexture });
f.position.y = -DEFAULT_THICKNESS / 2;
const c = await floor(name + "_c", width, depth, scene, { texturePath: ceilingTexture });
c.position.y = 2.90 + DEFAULT_THICKNESS / 2;
c.setParent(f);
if (wall0 !== null) {
const w0 = await mkw(0, width, wall0);
w0.position.z = f.scaling.z / 2 + th(wall0) / 2;
w0.setParent(f);
}
if (wall1 !== null) {
const w1 = await mkw(1, depth, wall1);
w1.position.x = f.scaling.x / 2 + th(wall1) / 2;
w1.rotation.y = Math.PI / 2;
w1.setParent(f);
}
if (wall2 !== null) {
const w2 = await mkw(2, width, wall2);
w2.position.z = -(f.scaling.z / 2 + th(wall2) / 2);
w2.rotation.y = Math.PI;
w2.setParent(f);
}
if (wall3 !== null) {
const w3 = await mkw(3, depth, wall3);
w3.position.x = -(f.scaling.x / 2 + th(wall3) / 2);
w3.rotation.y = -Math.PI / 2;
w3.setParent(f);
}
f.position.y = DEFAULT_THICKNESS / 2;
return f;
}