react-planner-electron
Version:
react-planner-electron is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.
317 lines (251 loc) • 9.98 kB
JSX
import * as Three from 'three';
import React from 'react';
const DEPTH = 20;
//colors
const grey = new Three.MeshLambertMaterial( {color: 0xeae6ca} );
function makeObjectMaxLOD(WIDTH,HEIGHT) {
let OldStyleRadiator = new Three.Mesh();
let roundedRectShape = new Three.Shape();
let x=0;
let y=0;
let width=DEPTH;
let height=HEIGHT;
let radius=2.5;
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.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
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 holePath1 = new Three.Path();
holePath1.moveTo( DEPTH/6, HEIGHT*.16 );
holePath1.arc(0, HEIGHT*.07, DEPTH/8 ,0, Math.PI,false);
holePath1.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath1 );
let holePath4 = new Three.Path();
holePath4.moveTo( DEPTH/6, HEIGHT*.16);
holePath4.arc(0, HEIGHT*0.725, DEPTH/8 ,0, Math.PI,false);
holePath4.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath4 );
let holePath7 = new Three.Path();
holePath7.moveTo( DEPTH/6, HEIGHT*.16 );
holePath7.arc(0, HEIGHT*.4, DEPTH/8 ,0, Math.PI,false);
holePath7.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath7 );
////////////////////////////////////////////////
let holePath2 = new Three.Path();
holePath2.moveTo( DEPTH/2, HEIGHT*.2 );
holePath2.arc(0, HEIGHT*.07, DEPTH/8 ,0, Math.PI,false);
holePath2.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath2 );
let holePath5 = new Three.Path();
holePath5.moveTo( DEPTH/2, HEIGHT*.5 );
holePath5.arc(0, HEIGHT*.0725, DEPTH/8 ,0, Math.PI,false);
holePath5.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath5 );
let holePath8 = new Three.Path();
holePath8.moveTo( DEPTH/2, HEIGHT*1.25);
holePath8.arc(0, -HEIGHT*.4, DEPTH/8 ,0, Math.PI,false);
holePath8.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath8 );
////////////////////////////////////////////
let holePath3 = new Three.Path();
holePath3.moveTo( 0.85*DEPTH, HEIGHT*.16 );
holePath3.arc(0, HEIGHT*.07, DEPTH/8 ,0, Math.PI,false);
holePath3.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath3 );
let holePath6 = new Three.Path();
holePath6.moveTo( 0.85*DEPTH, HEIGHT*.16 );
holePath6.arc(0, HEIGHT*.4, DEPTH/8 ,0, Math.PI,false);
holePath6.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath6 );
let holePath9 = new Three.Path();
holePath9.moveTo( 0.85*DEPTH, HEIGHT*.16 );
holePath9.arc(0, HEIGHT*.725,DEPTH/8 ,0, Math.PI,false);
holePath9.arc(DEPTH/8, -HEIGHT*.15, DEPTH/8 ,Math.PI,0,false);
roundedRectShape.holes.push( holePath9 );
let extrudeSettings = {
steps: 1,
depth: 4.5,
bevelEnabled: false,
bevelThickness: .4,
bevelSize: .4,
bevelSegments: 1
};
for(let i = 2.5; i<=WIDTH-5; i+=5){
let geometry = new Three.ExtrudeGeometry( roundedRectShape, extrudeSettings );
let mesh = new Three.Mesh( geometry, grey ) ;
mesh.position.set(i,height/20,DEPTH);
mesh.rotation.y += Math.PI/2;
OldStyleRadiator.add(mesh);
}
for (let i = 10; i <= HEIGHT; i+=HEIGHT - 10) {
let geometry1 = new Three.CylinderGeometry( DEPTH/12,DEPTH/12, WIDTH, 32 );
let tube = new Three.Mesh(geometry1,grey);
tube.rotation.x+=Math.PI/2;
tube.rotation.z+=Math.PI/2;
tube.position.set(WIDTH/2,i,DEPTH/2);
OldStyleRadiator.add(tube);
let geometry2 = new Three.CylinderGeometry( DEPTH/8, DEPTH/8, WIDTH-2.5, 6 );
let tube2 = new Three.Mesh(geometry2,grey);
tube2.rotation.x+=Math.PI/2;
tube2.rotation.z+=Math.PI/2;
tube2.position.set(WIDTH/2,i,DEPTH/2);
OldStyleRadiator.add(tube2);
let geometry3 = new Three.CylinderGeometry( DEPTH/7, DEPTH/7, WIDTH-5, 32 );
let tube3 = new Three.Mesh(geometry3,grey);
tube3.rotation.x+=Math.PI/2;
tube3.rotation.z+=Math.PI/2;
tube3.position.set(WIDTH/2,i,DEPTH/2);
OldStyleRadiator.add(tube3);
}
return OldStyleRadiator
}
function makeObjectMinLOD(WIDTH,HEIGHT) {
let OldStyleRadiator = new Three.Mesh();
let roundedRectShape = new Three.Shape();
let x=0;
let y=0;
let width=DEPTH;
let height=HEIGHT;
let radius=2.5;
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.quadraticCurveTo( x + width, y + height, x + width, y + height - radius );
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: 1,
depth: 4.5,
bevelEnabled: false,
bevelThickness: .4,
bevelSize: .4,
bevelSegments: 1
};
for(let i = 2.5; i<=WIDTH-5; i+=5){
let geometry = new Three.ExtrudeGeometry( roundedRectShape, extrudeSettings );
let mesh = new Three.Mesh( geometry, grey ) ;
mesh.position.set(i,height/20,DEPTH);
mesh.rotation.y += Math.PI/2;
OldStyleRadiator.add(mesh);
}
for (let i = HEIGHT/10; i <= HEIGHT; i+=HEIGHT - 10) {
let geometry1 = new Three.CylinderGeometry( DEPTH/12,DEPTH/12, WIDTH, 32 );
let tube = new Three.Mesh(geometry1,grey);
tube.rotation.x+=Math.PI/2;
tube.rotation.z+=Math.PI/2;
tube.position.set(WIDTH/2,i,DEPTH/2);
OldStyleRadiator.add(tube);
let geometry2 = new Three.CylinderGeometry( DEPTH/8, DEPTH/8, WIDTH-2.5, 6 );
let tube2 = new Three.Mesh(geometry2,grey);
tube2.rotation.x+=Math.PI/2;
tube2.rotation.z+=Math.PI/2;
tube2.position.set(WIDTH/2,i,DEPTH/2);
OldStyleRadiator.add(tube2);
let geometry3 = new Three.CylinderGeometry( DEPTH/7, DEPTH/7, WIDTH-5, 32 );
let tube3 = new Three.Mesh(geometry3,grey);
tube3.rotation.x+=Math.PI/2;
tube3.rotation.z+=Math.PI/2;
tube3.position.set(WIDTH/2,i,DEPTH/2);
OldStyleRadiator.add(tube3);
}
return OldStyleRadiator
}
export default {
name: "radiator-old-style",
prototype: "items",
info: {
tag: ['furnishings', 'cast iron'],
title: "cast iron radiator",
description: "cast iron radiator",
image: require('./OldStyleRadiator.png')
},
properties: {
width: {
label: "width",
type: "length-measure",
defaultValue: {
length: 100,
unit: 'cm'
}
},
height: {
label: "height",
type: "length-measure",
defaultValue: {
length: 100,
unit: 'cm'
}
},
altitude: {
label: "altitude",
type: "length-measure",
defaultValue: {
length: 20,
unit: 'cm'
}
}
},
render2D: function (element, layer, scene) {
let WIDTH = element.properties.get('width').get('length');
let angle = element.rotation + 90;
let textRotation = 0;
if (Math.sin(angle * Math.PI / 180) < 0) {
textRotation = 180;
}
let rect_style = {stroke : element.selected ? '#0096fd' : '#000', strokeWidth: "2px", fill: "#84e1ce"};
return (
<g transform={`translate(${-WIDTH / 2},${-DEPTH / 2})`}>
<rect key="1" x="0" y="0" width={WIDTH} height={DEPTH} style={rect_style}/>
<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 WIDTH = element.properties.get('width').get('length');
let HEIGHT = element.properties.get('height').get('length');
let newAltitude = element.properties.get('altitude').get('length');
/********* lod max *************/
let OldStyleRadiatorMaxLOD = new Three.Object3D();
OldStyleRadiatorMaxLOD.add(makeObjectMaxLOD(WIDTH,HEIGHT).clone());
let value = new Three.Box3().setFromObject(OldStyleRadiatorMaxLOD);
let deltaX = Math.abs(value.max.x - value.min.x);
let deltaY = Math.abs(value.max.y - value.min.y);
let deltaZ = Math.abs(value.max.z - value.min.z);
OldStyleRadiatorMaxLOD.position.z-= DEPTH/2;
OldStyleRadiatorMaxLOD.position.x-= WIDTH/2;
OldStyleRadiatorMaxLOD.position.y+= -HEIGHT/20+newAltitude;
OldStyleRadiatorMaxLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
/********* lod min *************/
let OldStyleRadiatorMinLOD = new Three.Object3D();
OldStyleRadiatorMinLOD.add(makeObjectMinLOD(WIDTH,HEIGHT).clone());
OldStyleRadiatorMinLOD.position.z-= DEPTH/2;
OldStyleRadiatorMinLOD.position.x-= WIDTH/2;
OldStyleRadiatorMinLOD.position.y+= -HEIGHT/20+newAltitude;
OldStyleRadiatorMinLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
/**** all level of detail ***/
let lod = new Three.LOD();
lod.addLevel(OldStyleRadiatorMaxLOD, 400);
lod.addLevel(OldStyleRadiatorMinLOD, 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);
}
};