UNPKG

react-planner

Version:

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

223 lines (167 loc) 6.19 kB
import * as Three from 'three'; import React from 'react'; const WIDTH = 70; const DEPTH = 50; const HEIGHT = 90; const brown = new Three.MeshLambertMaterial( {color: 0x9b8c75} ); const grey = new Three.MeshLambertMaterial( {color: 0xd9d7d7} ); const green = new Three.MeshBasicMaterial({color:0x669966}); const objectMaxLOD = makeObjectMaxLOD(); const objectMinLOD = makeObjectMinLOD(); function makeObjectMaxLOD() { let desk = new Three.Mesh(); let newDepth = .5; let newWidth = .9; let newHeight = 1; let radius = .03; let geometry = new Three.BoxGeometry( newWidth+newWidth/6, newHeight/20, newDepth+newDepth/4 ); let boxMaterials = [ brown, brown, green, brown, brown, brown]; let plane = new Three.Mesh( geometry, boxMaterials); plane.position.y = newHeight; desk.add(plane); let geometry_legs = new Three.CylinderGeometry( radius, radius, newHeight, 32, 32 ); let geometry2 = new Three.BoxGeometry( newWidth, newHeight/20, newDepth ); let plane2 = new Three.Mesh( geometry2, brown ); plane2.position.y = newHeight/2+newHeight/4; desk.add(plane2); let geometry3 = new Three.BoxGeometry( newWidth, newHeight/10, newDepth/20 ); let plane3 = new Three.Mesh( geometry3, brown ); plane3.position.y = newHeight/2+newHeight/4+newHeight/16; plane3.position.z = newDepth/3+newDepth/5; desk.add(plane3); let leg1 = new Three.Mesh( geometry_legs, grey ); leg1.position.x = newWidth/2; leg1.position.z = newDepth/2; leg1.position.y = newHeight/2; desk.add(leg1); let leg2 = new Three.Mesh( geometry_legs, grey ); leg2.position.x = newWidth/2; leg2.position.z = -newDepth/2; leg2.position.y = newHeight/2; desk.add(leg2); let leg3 = new Three.Mesh( geometry_legs, grey ); leg3.position.x = -newWidth/2; leg3.position.z = newDepth/2; leg3.position.y = newHeight/2; desk.add(leg3); let leg4 = new Three.Mesh( geometry_legs, grey ); leg4.position.x = -newWidth/2; leg4.position.z = -newDepth/2; leg4.position.y = newHeight/2; desk.add(leg4); return desk } function makeObjectMinLOD() { let desk = new Three.Mesh(); let newDepth = .5; let newWidth = .9; let newHeight = 1; let radius = .03; let geometry = new Three.BoxGeometry( newWidth+newWidth/6, newHeight/20, newDepth+newDepth/4 ); let boxMaterials = [ brown, brown, green, brown, brown, brown]; let plane = new Three.Mesh( geometry, boxMaterials); plane.position.y = newHeight; desk.add(plane); let geometry_legs = new Three.CylinderGeometry( radius, radius, newHeight, 32, 32 ); let geometry2 = new Three.BoxGeometry( newWidth, newHeight/20, newDepth ); let plane2 = new Three.Mesh( geometry2, brown ); plane2.position.y = newHeight/2+newHeight/4; desk.add(plane2); let geometry3 = new Three.BoxGeometry( newWidth, newHeight/10, newDepth/20 ); let plane3 = new Three.Mesh( geometry3, brown ); plane3.position.y = newHeight/2+newHeight/4+newHeight/16; plane3.position.z = newDepth/3+newDepth/5; desk.add(plane3); let leg1 = new Three.Mesh( geometry_legs, grey ); leg1.position.x = newWidth/2; leg1.position.z = newDepth/2; leg1.position.y = newHeight/2; desk.add(leg1); let leg2 = new Three.Mesh( geometry_legs, grey ); leg2.position.x = newWidth/2; leg2.position.z = -newDepth/2; leg2.position.y = newHeight/2; desk.add(leg2); let leg3 = new Three.Mesh( geometry_legs, grey ); leg3.position.x = -newWidth/2; leg3.position.z = newDepth/2; leg3.position.y = newHeight/2; desk.add(leg3); let leg4 = new Three.Mesh( geometry_legs, grey ); leg4.position.x = -newWidth/2; leg4.position.z = -newDepth/2; leg4.position.y = newHeight/2; desk.add(leg4); return desk } export default { name: 'school desk', prototype: 'items', info: { tag: ['furnishings', 'wood'], title: 'school desk', description: 'school desk', image: require('./desk.png') }, properties: { altitude: { label: 'altitude', type: 'length-measure', defaultValue: { length: 0, unit: 'cm' } } }, render2D: function (element, layer, scene) { let angle = element.rotation + 90; let textRotation = 0; if (Math.sin(angle * Math.PI / 180) < 0) { textRotation = 180; } return ( <g transform={`translate(${-WIDTH / 2},${-DEPTH / 2})`}> <rect key='1' x='0' y='0' width={WIDTH} height={DEPTH} style={{stroke: element.selected ? '#0096fd' : '#000', strokeWidth: '2px', fill: '#84e1ce'}}/> <text key='2' x='0' y='0' transform={`translate(${WIDTH / 2}, ${DEPTH / 2}) scale(1,-1) rotate(${textRotation})`} style={{textAnchor: 'middle', fontSize: '11px'}}> {element.type} </text> </g> ) }, render3D: function (element, layer, scene) { let newAltitude = element.properties.get('altitude').get('length'); /************* lod max ******************/ let deskMaxLOD = new Three.Object3D(); deskMaxLOD.add(objectMaxLOD.clone()); let valueObject = new Three.Box3().setFromObject(deskMaxLOD); 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); deskMaxLOD.rotation.y+=Math.PI; deskMaxLOD.position.y+= newAltitude; deskMaxLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ ); /************* lod min ******************/ let deskMinLOD = new Three.Object3D(); deskMinLOD.add(objectMinLOD.clone()); deskMinLOD.rotation.y+=Math.PI; deskMinLOD.position.y+= newAltitude; deskMinLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ ); /**** all level of detail ***/ let lod = new Three.LOD(); lod.addLevel(deskMaxLOD, 200); lod.addLevel(deskMinLOD, 900); 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); } };