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.

415 lines (317 loc) 11.6 kB
import * as Three from 'three'; import React from 'react'; const WIDTH = 60; const DEPTH = 60; const HEIGHT = 100; let greyMaterial = new Three.MeshLambertMaterial({color: 0xC0C0C0}); greyMaterial.side = Three.DoubleSide; let greenMaterial = new Three.MeshLambertMaterial({color: 0x008250}); function makeArmchairMaxLOD() { let armchair = new Three.Object3D(); let foot = new Three.Mesh(); //armchair base let g_base_foot = new Three.BoxGeometry(0.3, 0.05, 0.4); let m_base_foot1 = new Three.Mesh(g_base_foot, greyMaterial); m_base_foot1.position.set(0, 0.1, 0.1); foot.add(m_base_foot1); let g_base_foot2 = new Three.CylinderGeometry(0.055, 0.055, 0.35, 20); let m_base_foot2 = new Three.Mesh(g_base_foot2, greyMaterial); m_base_foot2.position.set(0, 0.25, 0.15); foot.add(m_base_foot2); armchair.add(foot); //seat let seat = new Three.Mesh(); let extrusionSettings = { depth: 0.65, bevelEnabled: false, bevelSegments: 2, steps: 10, bevelSize: 1, bevelThickness: 1 }; let shape_sed = new Three.Shape(); shape_sed.moveTo(0, 0); shape_sed.lineTo(0, 0.05); shape_sed.quadraticCurveTo(0, 0.1, -0.02, 0.1); shape_sed.lineTo(-0.6, 0.1); shape_sed.quadraticCurveTo(-0.6, 0.1, -0.6, 0.07); shape_sed.lineTo(-0.6, 0); let g_sitting = new Three.ExtrudeGeometry(shape_sed, extrusionSettings); let sitting = new Three.Mesh(g_sitting, greenMaterial); sitting.rotation.y = Math.PI / 2; sitting.rotation.z = Math.PI / 3.5; sitting.position.set(-0.325, .905, -0.3); seat.add(sitting); //back armchair let shape_sc = new Three.Shape(); shape_sc.moveTo(0, 0); shape_sc.lineTo(0, 0.1); shape_sc.quadraticCurveTo(-0.5, 0.07, -0.97, 0.1); shape_sc.quadraticCurveTo(-1, 0.1, -1, 0.07); shape_sc.lineTo(-1, 0); shape_sc.quadraticCurveTo(-0.5, -0.03, 0, 0); let g_back = new Three.ExtrudeGeometry(shape_sc, extrusionSettings); let back = new Three.Mesh(g_back, greenMaterial); back.rotation.z = -105 * Math.PI / 180; back.rotation.y = -Math.PI / 2; back.position.set(0.325, 0.52, 0.125); seat.add(back); let g_asse_rotaz2 = new Three.CylinderGeometry(0.06, 0.06, 0.8, 32, 32, true); let asse_rotaz2 = new Three.Mesh(g_asse_rotaz2, greyMaterial); asse_rotaz2.rotation.z = -Math.PI / 2; asse_rotaz2.position.set(0, 0.45, 0.15); seat.add(asse_rotaz2); let roundedRectShape = new Three.Shape(); let x = 0; let y = 0; let width = .7; let height = .75; let radius = 0.25; roundedRectShape.moveTo(x, y + radius); roundedRectShape.lineTo(x, y + height - radius); roundedRectShape.quadraticCurveTo(x, y + height, x + radius, y + height); roundedRectShape.lineTo(x + width - radius, y + height); roundedRectShape.lineTo(x + width, y + radius); roundedRectShape.quadraticCurveTo(x + width, y, x + width - radius, y); roundedRectShape.lineTo(x + radius, y); roundedRectShape.quadraticCurveTo(x, y, x, y + radius); let extrudeSettings = { steps: 2, depth: .07, bevelEnabled: false, bevelThickness: 1, bevelSize: 1, bevelSegments: 1 }; let geometry2 = new Three.ExtrudeGeometry(roundedRectShape, extrudeSettings); let armrest_1 = new Three.Mesh(geometry2, greyMaterial); armrest_1.rotation.y = Math.PI / 2; armrest_1.rotation.z = .9 * Math.PI; armrest_1.position.set(-0.4, 1, -0.4); seat.add(armrest_1); let armrest_2 = armrest_1.clone(); armrest_2.position.x += .73; seat.add(armrest_2); armchair.add(seat); return armchair } function makeArmchairMinLOD() { let armchair = new Three.Object3D(); let foot = new Three.Mesh(); //armchair base let g_base_foot = new Three.BoxGeometry(0.3, 0.05, 0.4); let base_foot1 = new Three.Mesh(g_base_foot, greyMaterial); base_foot1.position.set(0, 0.1, 0.1); foot.add(base_foot1); let g_base_foot2 = new Three.CylinderGeometry(0.055, 0.055, 0.35, 8, 8); let base_foot2 = new Three.Mesh(g_base_foot2, greyMaterial); base_foot2.position.set(0, 0.25, 0.15); foot.add(base_foot2); armchair.add(foot); //seat let seat = new Three.Mesh(); let extrusionSettings = { depth: 0.65, bevelEnabled: false, bevelSegments: 2, steps: 10, bevelSize: 1, bevelThickness: 1 }; let shape_sed = new Three.Shape(); shape_sed.moveTo(0, 0); shape_sed.lineTo(0, 0.05); shape_sed.quadraticCurveTo(0, 0.1, -0.02, 0.1); shape_sed.lineTo(-0.6, 0.1); shape_sed.quadraticCurveTo(-0.6, 0.1, -0.6, 0.07); shape_sed.lineTo(-0.6, 0); let g_sitting = new Three.ExtrudeGeometry(shape_sed, extrusionSettings); let sitting = new Three.Mesh(g_sitting, greenMaterial); sitting.rotation.y = Math.PI / 2; sitting.rotation.z = Math.PI / 3.5; sitting.position.set(-0.325, .905, -0.3); seat.add(sitting); //back armchair let shape_sc = new Three.Shape(); shape_sc.moveTo(0, 0); shape_sc.lineTo(0, 0.1); shape_sc.quadraticCurveTo(-0.5, 0.07, -0.97, 0.1); shape_sc.quadraticCurveTo(-1, 0.1, -1, 0.07); shape_sc.lineTo(-1, 0); shape_sc.quadraticCurveTo(-0.5, -0.03, 0, 0); let g_back = new Three.ExtrudeGeometry(shape_sc, extrusionSettings); let back = new Three.Mesh(g_back, greenMaterial); back.rotation.z = -105 * Math.PI / 180; back.rotation.y = -Math.PI / 2; back.position.set(0.325, 0.52, 0.125); seat.add(back); let g_asse_rotaz2 = new Three.CylinderGeometry(0.06, 0.06, 0.8, 8, 8, true); let asse_rotaz2 = new Three.Mesh(g_asse_rotaz2, greyMaterial); asse_rotaz2.rotation.z = -Math.PI / 2; asse_rotaz2.position.set(0, 0.45, 0.15); seat.add(asse_rotaz2); let roundedRectShape = new Three.Shape(); let x = 0; let y = 0; let width = .7; let height = .75; let radius = 0.25; roundedRectShape.moveTo(x, y + radius); roundedRectShape.lineTo(x, y + height - radius); roundedRectShape.quadraticCurveTo(x, y + height, x + radius, y + height); roundedRectShape.lineTo(x + width - radius, y + height); roundedRectShape.lineTo(x + width, y + radius); roundedRectShape.quadraticCurveTo(x + width, y, x + width - radius, y); roundedRectShape.lineTo(x + radius, y); roundedRectShape.quadraticCurveTo(x, y, x, y + radius); let extrudeSettings = { steps: 2, depth: .07, bevelEnabled: false, bevelThickness: 1, bevelSize: 1, bevelSegments: 1 }; let geometry2 = new Three.ExtrudeGeometry(roundedRectShape, extrudeSettings); let armrest_1 = new Three.Mesh(geometry2, greyMaterial); armrest_1.rotation.y = Math.PI / 2; armrest_1.rotation.z = .9 * Math.PI; armrest_1.position.set(-0.4, 1, -0.4); seat.add(armrest_1); let armrest_2 = armrest_1.clone(); armrest_2.position.x += .73; seat.add(armrest_2); armchair.add(seat); return armchair } export default { name: 'armchairs', prototype: 'items', info: { tag: ['furnishings', 'wood'], title: 'armchairs', description: 'armchairs', image: require('./armchairs.png') }, properties: { altitude: { label: 'altitude', type: 'length-measure', defaultValue: { length: 0, unit: 'cm' } }, seat: { label: 'seats', type: 'number', defaultValue: 1 }, flip: { label: 'flip', type: 'checkbox', defaultValue: false, values: { 'none': false, 'yes': true } } }, render2D: function (element, layer, scene) { let rect_style ={stroke: element.selected ? '#0096fd' : '#000', strokeWidth: '2px', fill: '#84e1ce'}; let text_style ={textAnchor: 'middle', fontSize: '11px', fill: '#FF0000'}; let angle = element.rotation + 90; let textRotation = 0; if (Math.sin(angle * Math.PI / 180) < 0) { textRotation = 180; } let seats = element.properties.get('seat'); let flip = element.properties.get('flip'); let seatsArray = new Array(seats); let eps = -1.7; for (let ind = 0; ind < seats; ind++) seatsArray[ind]=<rect key={ind} x={WIDTH * ind} y={eps * ind } width={WIDTH} height={DEPTH} style={rect_style}/> return ( <g transform={`translate(${(flip?-1:1) * WIDTH * seats/2},${-DEPTH / 2}) scale(${flip?1:-1},1)`}> {seatsArray} <text x='0' y='0' transform={`translate(${WIDTH * seats/2}, ${DEPTH / 2 + eps * seats/2}) scale(${flip?1:-1},-1) rotate(${textRotation})`} style={text_style}> {element.type} </text> </g> ); }, render3D: function (element, layer, scene) { let newAltitude = element.properties.get('altitude').get('length'); let seats = element.properties.get('seat'); let flip = element.properties.get('flip'); let newWidth = WIDTH; let newDepth = DEPTH; let armchairsMaxLOD = new Three.Object3D(); let seatArray = new Array(seats); function setArmchairsPos(listObject,seats) { newWidth = WIDTH * seats; newDepth = DEPTH + (DEPTH / 8 * seats / 2); seatArray = listObject; for (let ind = 0; ind < seats; ind++) { seatArray[ind].position.x = (ind - Math.floor(seats / 2)) * -.8; if(flip) seatArray[ind].position.z = (ind - Math.floor(seats / 2)) * -.085; else seatArray[ind].position.z = (ind - Math.floor(seats / 2)) * +.085; } } function makeSeriesArmchair2(seats) { let chair = makeArmchairMaxLOD().clone(); for (let ind = 0; ind < seats; ind++) seatArray[ind] = chair.clone(); return seatArray } let armchairsObject2 = makeSeriesArmchair2(seats); setArmchairsPos(armchairsObject2,seats); for(let i=0; i<armchairsObject2.length; i++) armchairsMaxLOD.add(armchairsObject2[i]); let valueObject = new Three.Box3().setFromObject(armchairsMaxLOD); let deltaX = Math.abs(valueObject.max.x - valueObject.min.x); let deltaY = Math.abs(valueObject.max.y - valueObject.min.y); let deltaZ = Math.abs(valueObject.max.z - valueObject.min.z); armchairsMaxLOD.position.y+= -HEIGHT/20 + newAltitude; seats%2 ? armchairsMaxLOD.position.x+= newWidth/seats - WIDTH : armchairsMaxLOD.position.x+= newWidth/seats - 1.5*WIDTH ; armchairsMaxLOD.position.z-= DEPTH/8; armchairsMaxLOD.scale.set(newWidth / deltaX, HEIGHT / deltaY, newDepth / deltaZ); /********************** lod min ************************************/ let armchairsMinLOD = new Three.Object3D(); function makeSeriesArmchair1(seats) { let chair = makeArmchairMinLOD().clone(); for (let ind = 0; ind < seats; ind++) seatArray[ind] = chair.clone(); return seatArray } let armchairsObject1 = makeSeriesArmchair1(seats); setArmchairsPos(armchairsObject1,seats); for(let j=0; j<armchairsObject1.length; j++) armchairsMinLOD.add(armchairsObject1[j]); armchairsMinLOD.position.y+= -HEIGHT/20 + newAltitude; seats%2 ? armchairsMinLOD.position.x+= newWidth/seats - WIDTH : armchairsMinLOD.position.x+= (newWidth)/seats - 1.5*WIDTH ; armchairsMinLOD.position.z-= DEPTH/8; armchairsMinLOD.scale.set(newWidth / deltaX, HEIGHT / deltaY, newDepth / deltaZ); /********* all level of detail ************/ let lod = new Three.LOD(); lod.addLevel(armchairsMaxLOD, 200); lod.addLevel(armchairsMinLOD, 700); lod.updateMatrix(); lod.matrixAutoUpdate = false; if (element.selected) { let bbox = new Three.BoxHelper(lod, 0x99c3fb); bbox.material.linewidth = 5; bbox.renderOrder = 1000; bbox.material.depthTest = false; lod.add(bbox); } return Promise.resolve(lod); } };