react-planner
Version:
react-planner is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.
237 lines (174 loc) • 6.62 kB
JSX
import * as Three from 'three';
import React from 'react';
const WIDTH = 80;
const DEPTH = 80;
const HEIGHT = 200;
const textureLoader = new Three.TextureLoader();
const woodMaterial=textureLoader.load(require('./wood.jpg'));
const bookTexture1=textureLoader.load(require('./bookTexture1.jpg' ));
const bookTexture2=textureLoader.load(require('./bookTexture2.jpg' ));
const bookTexture3=textureLoader.load(require('./bookTexture3.jpg' ));
const objectMaxLOD = makeObjectMaxLOD();
const objectMinLOD = makeObjectMinLOD();
function makeObjectMaxLOD() {
let bookcase = new Three.Mesh();
//Bookcase
let backGeometry = new Three.BoxGeometry(0.03,2,0.8);
let wood = new Three.MeshPhongMaterial({map:woodMaterial});
let backside = new Three.Mesh(backGeometry,wood);
backside.position.set(0,1,0);
bookcase.add(backside);
let sideGeometry = new Three.BoxGeometry(0.3,2,0.03);
let side1 = new Three.Mesh(sideGeometry,wood);
side1.position.set(0.15,1,0.4);
bookcase.add(side1);
let side2 = new Three.Mesh(sideGeometry,wood);
side2.position.set(0.15,1,-0.4);
bookcase.add(side2);
let bottomGeometry = new Three.BoxGeometry(0.3,0.03,0.8);
let bottomPanel = new Three.Mesh(bottomGeometry,wood);
bottomPanel.position.set(0.15,2,0);
bookcase.add(bottomPanel);
let topGeometry = new Three.BoxGeometry(0.3,0.03,0.8);
let topPanel = new Three.Mesh(topGeometry,wood);
topPanel.position.set(0.15,0.015,0);
bookcase.add(topPanel);
//shelves
for(let i=1;i<5;i++){
let shelveGeometry = new Three.BoxGeometry(0.3,0.03,0.8);
let shelve = new Three.Mesh(shelveGeometry,wood);
shelve.position.set(0.15,0.015+i*0.4,0);
bookcase.add(shelve);
}
function choiceTexture() {
return (Math.floor(Math.random() * 3))
}
//book
let bookGeometry = new Three.BoxGeometry(0.24,0.32,0.76);
let bookMaterial =
[ new Three.MeshLambertMaterial({map:bookTexture1}),
new Three.MeshLambertMaterial({map:bookTexture2}),
new Three.MeshLambertMaterial({map:bookTexture3})];
let book1 = new Three.Mesh(bookGeometry,bookMaterial[choiceTexture()]);
book1.position.set(0.15,0.59,0);
bookcase.add(book1);
let book2 = new Three.Mesh(bookGeometry,bookMaterial[choiceTexture()]);
book2.position.set(0.15,0.99,0);
bookcase.add(book2);
let book3 = new Three.Mesh(bookGeometry,bookMaterial[choiceTexture()]);
book3.position.set(0.15,0.19,0);
bookcase.add(book3);
let book4 = new Three.Mesh(bookGeometry,bookMaterial[choiceTexture()]);
book4.position.set(0.15,1.39,0);
bookcase.add(book4);
let book5 = new Three.Mesh(bookGeometry,bookMaterial[choiceTexture()]);
book5.position.set(0.15,1.79,0);
bookcase.add(book5);
return bookcase
}
function makeObjectMinLOD() {
let bookcase = new Three.Mesh();
let textureLoader = new Three.TextureLoader();
let woodMaterial=textureLoader.load(require('./wood.jpg'));
//Bookcase
let backGeometry = new Three.BoxGeometry(0.03,2,0.8);
let wood = new Three.MeshPhongMaterial({map:woodMaterial});
let backside = new Three.Mesh(backGeometry,wood);
backside.position.set(0,1,0);
bookcase.add(backside);
let sideGeometry = new Three.BoxGeometry(0.3,2,0.03);
let side1 = new Three.Mesh(sideGeometry,wood);
side1.position.set(0.15,1,0.4);
bookcase.add(side1);
let side2 = new Three.Mesh(sideGeometry,wood);
side2.position.set(0.15,1,-0.4);
bookcase.add(side2);
let bottomGeometry = new Three.BoxGeometry(0.3,0.03,0.8);
let bottomPanel = new Three.Mesh(bottomGeometry,wood);
bottomPanel.position.set(0.15,2,0);
bookcase.add(bottomPanel);
let topGeometry = new Three.BoxGeometry(0.3,0.03,0.8);
let topPanel = new Three.Mesh(topGeometry,wood);
topPanel.position.set(0.15,0.015,0);
bookcase.add(topPanel);
//shelves
for(let i=1;i<5;i++){
let shelveGeometry = new Three.BoxGeometry(0.3,0.03,0.8);
let shelve = new Three.Mesh(shelveGeometry,wood);
shelve.position.set(0.15,0.015+i*0.4,0);
bookcase.add(shelve);
}
return bookcase
}
export default {
name: 'bookcase',
prototype: 'items',
info: {
tag: ['furnishings', 'wood'],
title: 'bookcase',
description: 'bookcase',
image: require('./bookcase.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;
}
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.get('altitude').get('length');
/**************** lod max ******************/
let bookcaseMaxLOD=new Three.Object3D();
bookcaseMaxLOD.add(objectMaxLOD.clone());
let value = new Three.Box3().setFromObject(bookcaseMaxLOD);
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);
bookcaseMaxLOD.rotation.y+=Math.PI/2;
bookcaseMaxLOD.position.y+= newAltitude;
bookcaseMaxLOD.position.z+= WIDTH/2;
bookcaseMaxLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
/**************** lod min ******************/
let bookcaseMinLOD=new Three.Object3D();
bookcaseMinLOD.add(objectMinLOD.clone());
bookcaseMinLOD.rotation.y+=Math.PI/2;
bookcaseMinLOD.position.y+= newAltitude;
bookcaseMinLOD.position.z+= WIDTH/2;
bookcaseMinLOD.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
/**** all level of detail ***/
let lod = new Three.LOD();
lod.addLevel(bookcaseMaxLOD, 200);
lod.addLevel(bookcaseMinLOD, 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);
}
};