UNPKG

kitchen-simulator

Version:

It is a kitchen simulator (self-contained micro-frontend).

181 lines (173 loc) 6.38 kB
import * as Three from 'three'; import { Box3, Mesh, MeshBasicMaterial, MeshPhysicalMaterial, RepeatWrapping, Shape, TextureLoader, Vector2 } from 'three'; import * as SharedStyle from "../../shared-style"; import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'; var params = { envMap: 'HDR', roughness: 0.9, metalness: 0.8, exposure: 1.0 // debug: false }; /** * Apply a texture to a wall face * @param material: The material of the face * @param texture: The texture to load * @param length: The lenght of the face * @param height: The height of the face */ var applyTexture = function applyTexture(material, texture, length, height) { var loader = new TextureLoader(); if (texture) { material.map = loader.load(texture.uri); material.map.colorSpace = Three.SRGBColorSpace; material.needsUpdate = true; material.map.wrapS = RepeatWrapping; material.map.wrapT = RepeatWrapping; material.map.repeat.set(length * texture.lengthRepeatScale, height * texture.heightRepeatScale); if (texture.normal) { material.normalMap = loader.load(texture.normal.uri); material.normalScale = new Vector2(texture.normal.normalScaleX, texture.normal.normalScaleY); material.normalMap.wrapS = RepeatWrapping; material.normalMap.wrapT = RepeatWrapping; material.normalMap.repeat.set(length * texture.normal.lengthRepeatScale, height * texture.normal.heightRepeatScale); } } }; /** * Function that assign UV coordinates to a geometry * @param geometry */ var assignUVs = function assignUVs(geometry) { geometry.computeBoundingBox(); var _geometry$boundingBox = geometry.boundingBox, min = _geometry$boundingBox.min, max = _geometry$boundingBox.max; var offset = new Vector2(0 - min.x, 0 - min.y); var range = new Vector2(max.x - min.x, max.y - min.y); var uvArray = []; var position = geometry.attributes.position; for (var i = 0; i < position.count; i += 3) { var x1 = position.getX(i); var y1 = position.getY(i); var x2 = position.getX(i + 1); var y2 = position.getY(i + 1); var x3 = position.getX(i + 2); var y3 = position.getY(i + 2); uvArray.push((x1 + offset.x) / range.x, (y1 + offset.y) / range.y, (x2 + offset.x) / range.x, (y2 + offset.y) / range.y, (x3 + offset.x) / range.x, (y3 + offset.y) / range.y); } geometry.setAttribute('uv', new Three.BufferAttribute(new Float32Array(uvArray), 2)); geometry.needsUpdate = true; }; export function createArea(element, layer, scene, textures) { var vertices = []; element.vertices.forEach(function (vertexID) { vertices.push(layer.vertices.get(vertexID)); }); var texture = element.texture; texture.lengthRepeatScale = 0.01; texture.heightRepeatScale = 0.01; var color = element.properties.get('patternColor'); if (element.selected) { color = SharedStyle.AREA_MESH_COLOR.selected; } else { color = SharedStyle.AREA_MESH_COLOR.unselected; } if (texture.uri === undefined || texture.uri == '') { texture.uri = layer.floorStyle.uri; } var shape = new Shape(); shape.moveTo(vertices[0].x, vertices[0].y); for (var i = 1; i < vertices.length; i++) { shape.lineTo(vertices[i].x, vertices[i].y); } function loadFloorENV() { return new RGBELoader().load('/assets/Window.hdr', function (texture) { texture.mapping = Three.EquirectangularReflectionMapping; return texture; }); } var floorENV = loadFloorENV(); var loader = new TextureLoader(); var areaMaterial = new MeshPhysicalMaterial({ side: Three.DoubleSide, metalness: texture.metalness, roughness: 0.3, envMap: floorENV, envMapIntensity: 1.8, specularIntensity: 0.4, map: loader.load(texture.uri) }); /* Create holes for the area */ element.holes.forEach(function (holeID) { var holeCoords = []; layer.getIn(['areas', holeID, 'vertices']).forEach(function (vertexID) { var _layer$getIn = layer.getIn(['vertices', vertexID]), x = _layer$getIn.x, y = _layer$getIn.y; holeCoords.push([x, y]); }); holeCoords = holeCoords.reverse(); var holeShape = createShape(holeCoords); shape.holes.push(holeShape); }); // This is extrude floor mesh var extrudeSettings = { depth: -3, bevelEnabled: false }; var shapeGeometry = new Three.ExtrudeGeometry(shape, extrudeSettings); assignUVs(shapeGeometry); var boundingBox = new Box3().setFromObject(new Mesh(shapeGeometry, new MeshBasicMaterial())); var width = boundingBox.max.x - boundingBox.min.x; var height = boundingBox.max.y - boundingBox.min.y; var texture_unit = 70 * 2.54; // 70 inch applyTexture(areaMaterial, texture, width / texture_unit * 100, height / texture_unit * 100); var area = new Mesh(shapeGeometry, areaMaterial); area.rotation.x -= Math.PI / 2; area.receiveShadow = true; area.name = 'floor'; // This mesh is use for creating ceiling mesh var shapeGeometry2 = new Three.ShapeGeometry(shape); var area2 = new Mesh(shapeGeometry2, new MeshBasicMaterial({ transparent: true, opacity: 0.0 })); area2.castShadow = true; area2.rotation.x -= Math.PI / 2; area2.receiveShadow = true; area2.name = 'floorSupport'; var floorSupport = area2.clone(); area.userData.floorSupport = floorSupport; return Promise.resolve(area); } export function updatedArea(element, layer, scene, textures, mesh, oldElement, differences, selfDestroy, selfBuild) { var noPerf = function noPerf() { selfDestroy(); return selfBuild(); }; var floor = mesh.getObjectByName('floor'); floor.receiveShadow = true; if (differences[0] == 'selected') { var color = element.selected ? SharedStyle.AREA_MESH_COLOR.selected : SharedStyle.AREA_MESH_COLOR.unselected; floor.material.color.set(color); } else if (differences[0] == 'properties') { if (differences[1] === 'texture') { return noPerf(); } } else return noPerf(); return Promise.resolve(mesh); } /** * This function will create a shape given a list of coordinates * @param shapeCoords * @returns {Shape} */ var createShape = function createShape(shapeCoords) { var shape = new Shape(); shape.moveTo(shapeCoords[0][0], shapeCoords[0][1]); for (var i = 1; i < shapeCoords.length; i++) { shape.lineTo(shapeCoords[i][0], shapeCoords[i][1]); } return shape; };