Amp-Thread-ID: https://ampcode.com/threads/T-01a02485-5574-707c-bff4-5668d83bee8a Co-authored-by: Heaust Azure <heaust.azure@gmail.com>
58 lines
1.8 KiB
TypeScript
58 lines
1.8 KiB
TypeScript
import { Mesh, type MeshOptions } from "../Mesh";
|
|
import type { Scene } from "../Scene";
|
|
|
|
export type CubeOptions = Omit<MeshOptions, "geometryId" | "vertexData"> & {
|
|
size?: number;
|
|
width?: number;
|
|
height?: number;
|
|
depth?: number;
|
|
};
|
|
|
|
function dimension(value: number, name: string) {
|
|
if (!Number.isFinite(value) || value <= 0) throw new RangeError(name);
|
|
return value / 2;
|
|
}
|
|
|
|
/** A six-sided mesh with independent vertices and normals for every face. */
|
|
export class Cube extends Mesh {
|
|
constructor(scene: Scene, options: CubeOptions = {}) {
|
|
const {
|
|
size = 1,
|
|
width = size,
|
|
height = size,
|
|
depth = size,
|
|
...meshOptions
|
|
} = options;
|
|
const x = dimension(width, "width");
|
|
const y = dimension(height, "height");
|
|
const z = dimension(depth, "depth");
|
|
const positions = [
|
|
[-x, -y, z, x, -y, z, x, y, z, -x, y, z],
|
|
[x, -y, -z, -x, -y, -z, -x, y, -z, x, y, -z],
|
|
[x, -y, z, x, -y, -z, x, y, -z, x, y, z],
|
|
[-x, -y, -z, -x, -y, z, -x, y, z, -x, y, -z],
|
|
[-x, y, z, x, y, z, x, y, -z, -x, y, -z],
|
|
[-x, -y, -z, x, -y, -z, x, -y, z, -x, -y, z],
|
|
].flat();
|
|
const normals = [
|
|
[0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],
|
|
[0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1],
|
|
[1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0],
|
|
[-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0],
|
|
[0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0],
|
|
[0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0],
|
|
].flat();
|
|
const uvs = Array.from({ length: 6 }, () => [
|
|
0, 0, 1, 0, 1, 1, 0, 1,
|
|
]).flat();
|
|
const indices = Array.from({ length: 6 }, (_, face) => {
|
|
const vertex = face * 4;
|
|
return [vertex, vertex + 1, vertex + 2, vertex, vertex + 2, vertex + 3];
|
|
}).flat();
|
|
super(scene, {
|
|
...meshOptions,
|
|
vertexData: { positions, normals, uvs, indices },
|
|
});
|
|
}
|
|
}
|