react-planner
Version:
react-planner is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.
198 lines (154 loc) • 5.35 kB
JSX
import * as Three from 'three';
import React from 'react';
const WIDTH = 150;
const DEPTH = 50;
const HEIGHT = 50;
const RADIUS = 10;
const grey = new Three.MeshLambertMaterial({ color: 0xC0C0C0 });
const black = new Three.MeshLambertMaterial({ color: 0x00000 });
const textureLoader = new Three.TextureLoader();
const woodTexture = textureLoader.load(require('./wood.jpg'));
const objectMaxLOD = makeObjectMaxLOD();
const objectMinLOD = makeObjectMinLOD();
function makeObjectMaxLOD() {
let bench = new Three.Mesh();
// axis
let axis1 = new Three.Mesh(new Three.BoxGeometry(10, 0.5, 0.5), grey);
axis1.position.set(0, 0, 0);
bench.add(axis1);
let axi2 = new Three.Mesh(new Three.BoxGeometry(10, 0.5, 0.5), grey);
axi2.position.set(0, 0, 3);
bench.add(axi2);
//beams
for (let lx = -5; lx <= 5; lx += 5) {
let beam = new Three.Mesh(new Three.BoxGeometry(0.5, 0.5, 3.5), grey);
beam.position.set(lx, 0, 1.5);
bench.add(beam);
}
//legs
for (let gx = -5; gx <= 5; gx += 5) {
for (let gz = 0; gz <= 3; gz += 3) {
let leg = new Three.Mesh(new Three.BoxGeometry(3, 0.5, 0.5), grey);
leg.rotation.z = 0.5 * Math.PI;
leg.position.set(gx, -1.5, gz);
bench.add(leg);
// foot
let foot = new Three.Mesh(new Three.BoxGeometry(0.5, 0.25, 0.5), black);
foot.rotation.z = 0.5 * Math.PI;
foot.position.x = -1.625;
leg.add(foot);
}
}
// wood axis
for (let z = 0; z <= 3; z += 0.75) {
let woodAxis = new Three.Mesh(new Three.BoxGeometry(12, 0.25, 0.5), new Three.MeshPhongMaterial({ map: woodTexture }));
woodAxis.position.set(0, 0.5, z);
bench.add(woodAxis);
}
//nuts
for (let z = 0; z <= 3; z += 0.75) {
for (let dy = -5; dy <= 5; dy += 5) {
let nut = new Three.Mesh(new Three.CylinderGeometry(0.1, 0.1, 0.8, 6), black);
nut.position.set(dy, 0.3, z);
bench.add(nut);
}
}
return bench;
}
function makeObjectMinLOD() {
let bench = new Three.Mesh();
// axis
let axis1 = new Three.Mesh(new Three.BoxGeometry(10, 0.5, 0.5), grey);
axis1.position.set(0, 0, 0);
bench.add(axis1);
let axi2 = new Three.Mesh(new Three.BoxGeometry(10, 0.5, 0.5), grey);
axi2.position.set(0, 0, 3);
bench.add(axi2);
//beams
for (let lx = -5; lx <= 5; lx += 5) {
let beam = new Three.Mesh(new Three.BoxGeometry(0.5, 0.5, 3.5), grey);
beam.position.set(lx, 0, 1.5);
bench.add(beam);
}
//legs
for (let gx = -5; gx <= 5; gx += 5) {
for (let gz = 0; gz <= 3; gz += 3) {
let leg = new Three.Mesh(new Three.BoxGeometry(3, 0.5, 0.5), grey);
leg.rotation.z = 0.5 * Math.PI;
leg.position.set(gx, -1.5, gz);
bench.add(leg);
}
}
// wood axis
for (let z = 0; z <= 3; z += 0.75) {
let woodAxis = new Three.Mesh(new Three.BoxGeometry(12, 0.25, 0.5), new Three.MeshPhongMaterial({ map: woodTexture }));
woodAxis.position.set(0, 0.5, z);
bench.add(woodAxis);
}
return bench;
}
export default {
name: 'bench',
prototype: 'items',
info: {
tag: ['furnishings', 'wood', 'metal'],
title: 'bench',
description: 'bench',
image: require('./bench.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 = Math.sin(angle * Math.PI / 180) < 0 ? 180 : 0;
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 newAltitude = element.properties.getIn(['altitude', 'length']);
/************ lod max *****************/
let benchMaxLOD = new Three.Object3D();
benchMaxLOD.add(objectMaxLOD.clone());
let value = new Three.Box3().setFromObject(benchMaxLOD);
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);
benchMaxLOD.position.y += HEIGHT + newAltitude;
benchMaxLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
/************ lod min *****************/
let benchMinLOD = new Three.Object3D();
benchMinLOD.add(objectMinLOD.clone());
benchMinLOD.position.y += HEIGHT + newAltitude;
benchMinLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
/**** all level of detail ***/
let lod = new Three.LOD();
lod.addLevel(benchMaxLOD, 200);
lod.addLevel(benchMinLOD, 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);
}
};