UNPKG

react-planner

Version:

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

470 lines (387 loc) 13.5 kB
import * as Three from 'three'; import React from 'react'; const WIDTH = 80; const DEPTH = 100; const HEIGHT = 80; let textureLoader = new Three.TextureLoader(); let steel = textureLoader.load(require('./steel.jpg')); let darkSteel = textureLoader.load(require('./darksteel.jpg')); let logo = textureLoader.load(require('./logo.jpg')); let steelTexture = new Three.MeshLambertMaterial({map:steel}); let darkSteelTexture = new Three.MeshLambertMaterial({map:darkSteel}); let logoTexture = new Three.MeshLambertMaterial({map:logo}); const objectMaxLOD = makeObjectMaxLOD(); const objectMinLOD = makeObjectMinLOD(); function makeObjectMaxLOD() { let kitchen = new Three.Mesh(); //base let body = new Three.Mesh(new Three.BoxGeometry(1,0.05,1.5), steelTexture); body.position.set(0,0.15,0); kitchen.add(body); //foot for(let gx=-0.45;gx<=0.45;gx+=0.9){ for(let gz=-0.7125;gz<=0.7125;gz+=1.425){ let foot = new Three.Mesh(new Three.CylinderGeometry(0.05, 0.05, 0.05, 4), steelTexture) foot.position.set(gx,-0.05,gz); foot.rotation.y=0.25*Math.PI; body.add(foot) } } //back let back = new Three.Mesh(new Three.BoxGeometry(0.05,1,1.5), steelTexture); back.position.set(0.475,0.525,0); body.add(back); //side let side1 = new Three.Mesh(new Three.BoxGeometry(1,1,0.05), steelTexture); side1.position.set(0,0.525,0.725); body.add(side1); let side2 = new Three.Mesh(new Three.BoxGeometry(1,1,0.05), steelTexture); side2.position.set(0,0.525,-0.725); body.add(side2); //top let top = new Three.Mesh(new Three.BoxGeometry(1,0.20,1.5), steelTexture); top.position.set(0,1.1,0); body.add(top); //logo let logo = new Three.Mesh(new Three.PlaneGeometry(0.1,0.05),logoTexture); logo.position.set(-0.51,1.13,0); logo.rotation.y=-0.5*Math.PI; body.add(logo); //front let front = new Three.Mesh(new Three.BoxGeometry(0.05,0.99,1.4), steelTexture); front.position.set(-0.47,0.525,0); body.add(front); //oven let oven = new Three.Mesh(new Three.BoxGeometry(0.05,0.9,1.3), steelTexture); oven.position.set(-0.53,0.525,0); body.add(oven); //handle let handle1 = new Three.Mesh(new Three.CylinderGeometry(0.02,0.02,1),darkSteelTexture); handle1.position.set(-0.6,0.85,0); handle1.rotation.x=0.5*Math.PI; body.add(handle1); let handle2 = new Three.Mesh(new Three.CylinderGeometry(0.02,0.02,0.06),darkSteelTexture); handle2.position.set(-0.56,0.85,-0.4); handle2.rotation.z=0.5*Math.PI; body.add(handle2); let handle3 = new Three.Mesh(new Three.CylinderGeometry(0.02,0.02,0.06),darkSteelTexture); handle3.position.set(-0.56,0.85,0.4); handle3.rotation.z=0.5*Math.PI; body.add(handle3); //knob for(let gz=-0.6;gz<=0.65;gz+=0.3){ let knob = new Three.Mesh(new Three.CylinderGeometry(0.03, 0.03, 0.02, 32), darkSteelTexture); knob.position.set(-0.51,1.05,gz); knob.rotation.z=0.5*Math.PI; body.add(knob); let knob_p2 = new Three.Mesh(new Three.BoxGeometry(0.05, 0.03, 0.01), darkSteelTexture); knob_p2.position.set(0,0.02,0); knob.add(knob_p2) } //fire for(let gx=-0.22;gx<=0.22;gx+=0.44){ for(let gz=-0.45;gz<=0.45;gz+=0.9){ let fire = new Three.Mesh(new Three.CylinderGeometry(0.08, 0.1, 0.02, 32), darkSteelTexture) fire.position.set(gx,1.21,gz); body.add(fire) } } //central fire let centralFire = new Three.Mesh(new Three.CylinderGeometry(0.1, 0.12, 0.02, 32), darkSteelTexture); centralFire.position.set(0,1.21,0); body.add(centralFire); //long side grid for(let gx=-0.45;gx<=0.45;gx+=0.45){ if(gx!==0) { let longSideGrid = new Three.Mesh(new Three.BoxGeometry(0.03, 0.05, 1.38), darkSteelTexture); longSideGrid.position.set(gx,1.21,0); body.add(longSideGrid) } else { for(let gz=-0.46;gz<=0.68;gz+=0.90){ let longSideGrid2 = new Three.Mesh(new Three.BoxGeometry(0.03, 0.05, 0.46), darkSteelTexture); longSideGrid2.position.set(gx,1.21,gz); body.add(longSideGrid2) } } } //short side grid for(let gz=-0.675;gz<=0.675;gz+=0.45){ let shortSideGrid = new Three.Mesh(new Three.BoxGeometry(0.9, 0.05, 0.03), darkSteelTexture); shortSideGrid.position.set(0,1.21,gz); body.add(shortSideGrid) } //long side grid central for(let gx=-0.22;gx<=0.22;gx+=0.44){ for(let gz=-0.59;gz<=0.68;gz+=0.90){ let lsgc1 = new Three.Mesh(new Three.BoxGeometry(0.03, 0.01, 0.2), darkSteelTexture); lsgc1.position.set(gx,1.24,gz); body.add(lsgc1) } for(let gz=0.59;gz>=-0.68;gz-=0.90){ let lsgc2 = new Three.Mesh(new Three.BoxGeometry(0.03, 0.01, 0.2), darkSteelTexture); lsgc2.position.set(gx,1.24,gz); body.add(lsgc2) } } //short side grid central for(let gx=-0.365;gx<=0.345;gx+=0.7){ for(let gz=-0.45;gz<=0.45;gz+=0.45){ if(gz!==0) { let ssgc1 = new Three.Mesh(new Three.BoxGeometry(0.2, 0.02, 0.03),darkSteelTexture); if(gx<0) ssgc1.position.set(gx,1.24,gz); else ssgc1.position.set(gx+0.03,1.24,gz); body.add(ssgc1) } else { let ssgc2 = new Three.Mesh(new Three.BoxGeometry(0.4, 0.02, 0.03),darkSteelTexture); if(gx<0) ssgc2.position.set(gx+0.1,1.24,gz); else ssgc2.position.set(gx-0.07,1.24,gz); body.add(ssgc2) } } } //long side grid inside for(let gz=-0.45;gz<=0.45;gz+=0.9){ let lsgi = new Three.Mesh(new Three.BoxGeometry(0.35, 0.02, 0.03),darkSteelTexture); lsgi.position.set(0,1.24,gz); body.add(lsgi) } //central peace for(let gz=-0.14;gz<=0.14;gz+=0.28) { let cp = new Three.Mesh(new Three.BoxGeometry(0.03, 0.02, 0.2),darkSteelTexture); cp.position.set(0,1.25,gz); body.add(cp) } return kitchen } function makeObjectMinLOD() { let kitchen = new Three.Mesh(); //base let body = new Three.Mesh(new Three.BoxGeometry(1,0.05,1.5), steelTexture); body.position.set(0,0.15,0); kitchen.add(body); //foot for(let gx=-0.45;gx<=0.45;gx+=0.9){ for(let gz=-0.7125;gz<=0.7125;gz+=1.425){ let foot = new Three.Mesh(new Three.CylinderGeometry(0.05, 0.05, 0.05, 4), steelTexture) foot.position.set(gx,-0.05,gz); foot.rotation.y=0.25*Math.PI; body.add(foot) } } //back let back = new Three.Mesh(new Three.BoxGeometry(0.05,1,1.5), steelTexture); back.position.set(0.475,0.525,0); body.add(back); //side let side1 = new Three.Mesh(new Three.BoxGeometry(1,1,0.05), steelTexture); side1.position.set(0,0.525,0.725); body.add(side1); let side2 = new Three.Mesh(new Three.BoxGeometry(1,1,0.05), steelTexture); side2.position.set(0,0.525,-0.725); body.add(side2); //top let top = new Three.Mesh(new Three.BoxGeometry(1,0.20,1.5), steelTexture); top.position.set(0,1.1,0); body.add(top); //logo let logo = new Three.Mesh(new Three.PlaneGeometry(0.1,0.05),logoTexture); logo.position.set(-0.51,1.13,0); logo.rotation.y=-0.5*Math.PI; body.add(logo); //front let front = new Three.Mesh(new Three.BoxGeometry(0.05,0.99,1.4), steelTexture); front.position.set(-0.47,0.525,0); body.add(front); //oven let oven = new Three.Mesh(new Three.BoxGeometry(0.05,0.9,1.3), steelTexture); oven.position.set(-0.53,0.525,0); body.add(oven); //handle let handle1 = new Three.Mesh(new Three.CylinderGeometry(0.02,0.02,1),darkSteelTexture); handle1.position.set(-0.6,0.85,0); handle1.rotation.x=0.5*Math.PI; body.add(handle1); let handle2 = new Three.Mesh(new Three.CylinderGeometry(0.02,0.02,0.06),darkSteelTexture); handle2.position.set(-0.56,0.85,-0.4); handle2.rotation.z=0.5*Math.PI; body.add(handle2); let handle3 = new Three.Mesh(new Three.CylinderGeometry(0.02,0.02,0.06),darkSteelTexture); handle3.position.set(-0.56,0.85,0.4); handle3.rotation.z=0.5*Math.PI; body.add(handle3); //knob for(let gz=-0.6;gz<=0.65;gz+=0.3){ let knob = new Three.Mesh(new Three.CylinderGeometry(0.03, 0.03, 0.02, 32), darkSteelTexture); knob.position.set(-0.51,1.05,gz); knob.rotation.z=0.5*Math.PI; body.add(knob); let knob_p2 = new Three.Mesh(new Three.BoxGeometry(0.05, 0.03, 0.01), darkSteelTexture); knob_p2.position.set(0,0.02,0); knob.add(knob_p2) } //fire for(let gx=-0.22;gx<=0.22;gx+=0.44){ for(let gz=-0.45;gz<=0.45;gz+=0.9){ let fire = new Three.Mesh(new Three.CylinderGeometry(0.08, 0.1, 0.02, 32), darkSteelTexture) fire.position.set(gx,1.21,gz); body.add(fire) } } //central fire let centralFire = new Three.Mesh(new Three.CylinderGeometry(0.1, 0.12, 0.02, 32), darkSteelTexture); centralFire.position.set(0,1.21,0); body.add(centralFire); //long side grid for(let gx=-0.45;gx<=0.45;gx+=0.45){ if(gx!==0) { let longSideGrid = new Three.Mesh(new Three.BoxGeometry(0.03, 0.05, 1.38), darkSteelTexture); longSideGrid.position.set(gx,1.21,0); body.add(longSideGrid) } else { for(let gz=-0.46;gz<=0.68;gz+=0.90){ let longSideGrid2 = new Three.Mesh(new Three.BoxGeometry(0.03, 0.05, 0.46), darkSteelTexture); longSideGrid2.position.set(gx,1.21,gz); body.add(longSideGrid2) } } } //short side grid for(let gz=-0.675;gz<=0.675;gz+=0.45){ let shortSideGrid = new Three.Mesh(new Three.BoxGeometry(0.9, 0.05, 0.03), darkSteelTexture); shortSideGrid.position.set(0,1.21,gz); body.add(shortSideGrid) } //long side grid central for(let gx=-0.22;gx<=0.22;gx+=0.44){ for(let gz=-0.59;gz<=0.68;gz+=0.90){ let lsgc1 = new Three.Mesh(new Three.BoxGeometry(0.03, 0.01, 0.2), darkSteelTexture); lsgc1.position.set(gx,1.24,gz); body.add(lsgc1) } for(let gz=0.59;gz>=-0.68;gz-=0.90){ let lsgc2 = new Three.Mesh(new Three.BoxGeometry(0.03, 0.01, 0.2), darkSteelTexture); lsgc2.position.set(gx,1.24,gz); body.add(lsgc2) } } //short side grid central for(let gx=-0.365;gx<=0.345;gx+=0.7){ for(let gz=-0.45;gz<=0.45;gz+=0.45){ if(gz!==0) { let ssgc1 = new Three.Mesh(new Three.BoxGeometry(0.2, 0.02, 0.03),darkSteelTexture); if(gx<0) ssgc1.position.set(gx,1.24,gz); else ssgc1.position.set(gx+0.03,1.24,gz); body.add(ssgc1) } else { let ssgc2 = new Three.Mesh(new Three.BoxGeometry(0.4, 0.02, 0.03),darkSteelTexture); if(gx<0) ssgc2.position.set(gx+0.1,1.24,gz); else ssgc2.position.set(gx-0.07,1.24,gz); body.add(ssgc2) } } } //long side grid inside for(let gz=-0.45;gz<=0.45;gz+=0.9){ let lsgi = new Three.Mesh(new Three.BoxGeometry(0.35, 0.02, 0.03),darkSteelTexture); lsgi.position.set(0,1.24,gz); body.add(lsgi) } //central peace for(let gz=-0.14;gz<=0.14;gz+=0.28) { let cp = new Three.Mesh(new Three.BoxGeometry(0.03, 0.02, 0.2),darkSteelTexture); cp.position.set(0,1.25,gz); body.add(cp) } return kitchen } export default { name: "kitchen", prototype: "items", info: { tag: ['furnishings', 'metal'], title: "kitchen", description: "kitchen", image: require('./kitchen.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 kitchenMaxLOD=new Three.Object3D(); kitchenMaxLOD.add(objectMaxLOD.clone()); let valuePosition = new Three.Box3().setFromObject(kitchenMaxLOD); let deltaX = Math.abs(valuePosition.max.x - valuePosition.min.x); let deltaY = Math.abs(valuePosition.max.y - valuePosition.min.y); let deltaZ = Math.abs(valuePosition.max.z - valuePosition.min.z); kitchenMaxLOD.position.y+=newAltitude; kitchenMaxLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ); /************ lod min ****************/ let kitchenMinLOD=new Three.Object3D(); kitchenMinLOD.add(objectMinLOD.clone()); kitchenMinLOD.position.y+=newAltitude; kitchenMinLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ); /**** all level of detail ***/ let lod = new Three.LOD(); lod.addLevel(kitchenMaxLOD, 200); lod.addLevel(kitchenMinLOD, 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); } };