UNPKG

react-planner-electron

Version:

react-planner-electron is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.

147 lines (116 loc) 4.87 kB
import { Shape, MeshPhongMaterial, ShapeGeometry, Box3, TextureLoader, BackSide, FrontSide, Object3D, Mesh, MeshBasicMaterial, RepeatWrapping, Vector2, DoubleSide } from 'three'; import * as SharedStyle from '../../shared-style'; /** * 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.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); geometry.faceVertexUvs[0] = geometry.faces.map(function (face) { var v1 = geometry.vertices[face.a]; var v2 = geometry.vertices[face.b]; var v3 = geometry.vertices[face.c]; return [new Vector2((v1.x + offset.x) / range.x, (v1.y + offset.y) / range.y), new Vector2((v2.x + offset.x) / range.x, (v2.y + offset.y) / range.y), new Vector2((v3.x + offset.x) / range.x, (v3.y + offset.y) / range.y)]; }); geometry.uvsNeedUpdate = true; }; export function createArea(element, layer, scene, textures) { var vertices = []; element.vertices.forEach(function (vertexID) { vertices.push(layer.vertices.get(vertexID)); }); var textureName = element.properties.get('texture'); var color = element.properties.get('patternColor'); if (element.selected) { color = SharedStyle.AREA_MESH_COLOR.selected; } else if (textureName && textureName !== 'none') { color = SharedStyle.AREA_MESH_COLOR.unselected; } 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); } var areaMaterial = new MeshPhongMaterial({ side: DoubleSide, color: color }); /* 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); }); var shapeGeometry = new ShapeGeometry(shape); 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 = textures[textureName]; applyTexture(areaMaterial, texture, width, height); var area = new Mesh(shapeGeometry, areaMaterial); area.rotation.x -= Math.PI / 2; area.name = 'floor'; 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'); if (differences[0] == 'selected') { var color = element.selected ? SharedStyle.AREA_MESH_COLOR.selected : element.properties.get('patternColor') || 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; };