UNPKG

crmod-api

Version:

A dynamic mod/asset generator for Cosmic Reach

428 lines (390 loc) 12.2 kB
import { Box3 } from "three"; import Material from "./material.js"; import { Direction } from "./directions.js"; import BlockModel from "./blockModel.js"; /** * @typedef ModelCuboidMaterials * @property {Material} west * @property {Material} east * @property {Material} down * @property {Material} up * @property {Material} north * @property {Material} south */ /** * @typedef ModelCuboidVisible * @property {boolean} west * @property {boolean} east * @property {boolean} down * @property {boolean} up * @property {boolean} north * @property {boolean} south */ /** * The default material for the faces of a cuboid. * * @package * @readonly * @type {Material} */ const DEFAULT_MATERIAL = new Material("debug.png"); /** * Defines a cuboid within a {@link BlockModel}. * * @class ModelCuboid */ class ModelCuboid { /** * The bounding box of the cuboid. * * @type {Box3} * @memberof ModelCuboid */ box; /** * Whether ambient occlusion is enabled for the cuboid. * * @type {boolean} * @memberof ModelCuboid */ ambientOcclusion; /** * The materials for each face of the cuboid. * * @type {ModelCuboidMaterials} * @memberof ModelCuboid */ materials; /** * The visibility of each face of the cuboid. * * @type {ModelCuboidVisible} * @memberof ModelCuboid */ visible; /** * Initializes a new ModelCuboid. * * @param {Box3} box The bounding box of the cuboid. * @memberof ModelCuboid */ constructor(box) { /** * @type {Box3} */ this.box = box; this.ambientOcclusion = false; this.materials = { west: DEFAULT_MATERIAL, east: DEFAULT_MATERIAL, down: DEFAULT_MATERIAL, up: DEFAULT_MATERIAL, north: DEFAULT_MATERIAL, south: DEFAULT_MATERIAL }; this.visible = { west: true, east: true, down: true, up: true, north: true, south: true } } /** * Sets the ambient occlusion for the cuboid. * * @param {boolean} ambientOcclusionEnabled Whether ambient occlusion is enabled. * @returns {this} */ setAmbientOcclusionEnabled(ambientOcclusionEnabled) { this.ambientOcclusion = ambientOcclusionEnabled; return this; } /** * Sets the material for all faces of the cuboid. * * @param {Material} material The material to set. * @returns {this} */ setAllMaterials(material) { this.materials.west = this.materials.east = this.materials.down = this.materials.up = this.materials.north = this.materials.south = material; return this; } /** * Sets the material for each face of the cuboid individually. * * @param {Material} west The material for the west face. * @param {Material} east The material for the east face. * @param {Material} down The material for the down face. * @param {Material} up The material for the up face. * @param {Material} north The material for the north face. * @param {Material} south The material for the south face. * @returns {this} */ setIndividualMaterials(west, east, down, up, north, south) { this.materials = { west, east, down, up, north, south }; return this; } /** * Sets the material for a specific face of the cuboid. * * @param {Direction} direction The direction of the face. * @param {Material} material The material for the face. * @returns {this} */ setFaceMaterial(direction, material) { this.materials[direction.name] = material; return this; } /** * Sets the material for the west face of the cuboid. * * @param {Material} material The material for the west face. * @returns {this} */ setWestMaterial(material) { this.materials.west = material; return this; } /** * Sets the material for the east face of the cuboid. * * @param {Material} material The material for the east face. * @returns {this} */ setEastMaterial(material) { this.materials.east = material; return this; } /** * Sets the material for the down face of the cuboid. * * @param {Material} material The material for the down face. * @returns {this} */ setDownMaterial(material) { this.materials.down = material; return this; } /** * Sets the material for the up face of the cuboid. * * @param {Material} material The material for the up face. * @returns {this} */ setUpMaterial(material) { this.materials.up = material; return this; } /** * Sets the material for the south face of the cuboid. * * @param {Material} material The material for the south face. * @returns {this} */ setSouthMaterial(material) { this.materials.south = material; return this; } /** * Sets the material for the north face of the cuboid. * * @param {Material} material The material for the north face. * @returns {this} */ setNorthMaterial(material) { this.materials.north = material; return this; } /** * Gets the materials for all faces of the cuboid. * * @return {Array<Material>} * @memberof ModelCuboid */ getMaterials() { return Object.values(this.materials); } /** * Sets the visibility for all faces of the cuboid. * * @param {boolean} visible Whether the faces are visible. * @returns {this} */ setAllVisible(visible) { this.visible.west = this.visible.east = this.visible.down = this.visible.up = this.visible.north = this.visible.south = visible; return this; } /** * Sets the visibility for each face of the cuboid individually. * * @param {boolean} west Whether the west face is visible. * @param {boolean} east Whether the east face is visible. * @param {boolean} down Whether the down face is visible. * @param {boolean} up Whether the up face is visible. * @param {boolean} north Whether the north face is visible. * @param {boolean} south Whether the south face is visible. * @returns {this} */ setIndividualVisible(west, east, down, up, north, south) { this.visible = { west, east, down, up, north, south }; return this; } /** * Sets the visibility for a specific face of the cuboid. * * @param {Direction} face The direction of the face. * @param {boolean} visible Whether the face is visible. * @returns {this} */ setFaceVisible(face, visible) { this.visible[face] = visible; return this; } /** * Sets the visibility for the west face of the cuboid. * * @param {boolean} visible Whether the west face is visible. * @returns {this} */ setWestVisible(visible) { this.visible.west = visible; return this; } /** * Sets the visibility for the west face of the cuboid. * * @param {boolean} visible Whether the west face is visible. * @returns {this} */ setEastVisible(visible) { this.visible.east = visible; return this; } /** * Sets the visibility for the down face of the cuboid. * * @param {boolean} visible Whether the down face is visible. * @returns {this} */ setDownVisible(visible) { this.visible.down = visible; return this; } /** * Sets the visibility for the up face of the cuboid. * * @param {boolean} visible Whether the up face is visible. * @returns {this} */ setUpVisible(visible) { this.visible.up = visible; return this; } /** * Sets the visibility for the south face of the cuboid. * * @param {boolean} visible Whether the south face is visible. * @returns {this} */ setSouthVisible(visible) { this.visible.south = visible; return this; } /** * Sets the visibility for the north face of the cuboid. * * @param {boolean} visible Whether the north face is visible. * @returns {this} */ setNorthVisible(visible) { this.visible.north = visible; return this; } /** * Gets number of visible faces. * * @readonly * @memberof ModelCuboid */ get visibleFaces() { return Object.keys(this.visible).reduce((p, c) => p + this.visible[c], 0) } /** * Applies a matrix transformation to the cuboid. * * @param {Matrix4} matrix The matrix to apply. * @returns {this} */ applyMatrixTransform(matrix) { this.box.applyMatrix4(matrix); return this; } /** * Clones the cuboid into a new instance. * * @return {ModelCuboid} A new instance of the current cuboid. * @memberof ModelCuboid */ clone() { const cuboid = new ModelCuboid(this.box.clone()); cuboid.setAmbientOcclusionEnabled(this.ambientOcclusion); Object.assign(cuboid.materials, this.materials); return cuboid; } /** * Serializes the cuboid into a JSON object. * * @override * @return {Object} The serialized cuboid as a JSON object. * @memberof ModelCuboid */ serialize() { return { localBounds: [ this.box.min.x, this.box.min.y, this.box.min.z, this.box.max.x, this.box.max.y, this.box.max.z, ], faces: { localNegX: this.visible.west ? { uv: [ this.box.min.z, 16 - this.box.max.y, this.box.max.z, 16 - this.box.min.y ], ambientocclusion: this.ambientOcclusion, cullFace: this.box.min.x == 0, texture: this.materials.west.id } : undefined, localNegY: this.visible.down ? { uv: [ 16 - this.box.min.x, this.box.max.z, 16 - this.box.max.x, this.box.min.z ], ambientocclusion: this.ambientOcclusion, cullFace: this.box.min.y == 0, texture: this.materials.down.id } : undefined, localNegZ: this.visible.south ? { uv: [ 16 - this.box.min.x, 16 - this.box.max.y, 16 - this.box.max.x, 16 - this.box.min.y ], ambientocclusion: this.ambientOcclusion, cullFace: this.box.min.z == 0, texture: this.materials.south.id } : undefined, localPosX: this.visible.east ? { uv: [ 16 - this.box.max.z, 16 - this.box.max.y, 16 - this.box.min.z, 16 - this.box.min.y ], ambientocclusion: this.ambientOcclusion, cullFace: this.box.max.x == 16, texture: this.materials.east.id } : undefined, localPosY: this.visible.up ? { uv: [ 16 - this.box.min.x, 16 - this.box.min.z, 16 - this.box.max.x, 16 - this.box.max.z ], ambientocclusion: this.ambientOcclusion, cullFace: this.box.max.y == 16, texture: this.materials.up.id } : undefined, localPosZ: this.visible.north ? { uv: [ this.box.min.x, 16 - this.box.max.y, this.box.max.x, 16 - this.box.min.y ], ambientocclusion: this.ambientOcclusion, cullFace: this.box.max.z == 16, texture: this.materials.north.id } : undefined } } } } export default ModelCuboid;