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
JSX
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);
}
};