Luccid-ai / react-planner

:pencil2: A React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.
https://cvdlab.github.io/react-planner
MIT License
15 stars 16 forks source link

Threejs Version Upgrade #31

Open khelaia opened 3 months ago

khelaia commented 3 months ago

are you planning threejs version update? also is it possible to import gltf bin+textures model import as item??

tboyer-idnum commented 2 months ago

hi @khelaia

I think this project is starting to no longer be maintained.... My team worked on gltf import, here an example :

import React from 'react';
import { ReactPlannerSharedStyle } from 'react-planner';
import * as Three from 'three';
import { GLTFLoader } from "three/addons";
import Translator from "../../../../../../src/translator/translator";
import model from './lamp-neon.glb';
import * as SharedStyle from "react-planner/styles/shared-style";

let translator = new Translator();

const WIDTH = 150;
const DEPTH = 30;
const HEIGHT = 50;
const ALTITUDE = 200;

export default {
  name: 'lamp-neon',
  elementType: 'lighting_fixtures',
  prototype: 'items',

  info: {
    title: 'lamp-neon',
    tag: ['lighting fixtures'],
    description: 'neon',
    image: require('./lamp-neon.png')
  },

  properties: {
    color: {
      label: translator.t('Color'),
      type: 'color',
      defaultValue: ReactPlannerSharedStyle.AREA_MESH_COLOR.unselected
    },
    width: {
      label: translator.t('Width'),
      type: 'length-measure',
      defaultValue: {
        length: WIDTH,
        unit: 'cm'
      }
    },
    height: {
      label: translator.t('Height'),
      type: 'length-measure',
      defaultValue: {
        length: HEIGHT,
        unit: 'cm'
      }
    },
    depth: {
      label: translator.t('Depth'),
      type: 'length-measure',
      defaultValue: {
        length: DEPTH,
        unit: 'cm'
      }
    },
    altitude: {
      label: translator.t("Altitude"),
      type: "length-measure",
      defaultValue: {
        length: ALTITUDE,
        unit: 'cm'
      }
    }
  },

  render2D: (element, layer, scene) => {
    let style = {
      stroke : element.selected ? SharedStyle.SECONDARY_COLOR.main : '#000',
      strokeWidth: "2px",
      fill: "#fff"
    };

    let w = element.properties.getIn(['width', 'length']);
    let d = element.properties.getIn(['depth', 'length']);
    let w2 = w / 2;
    let d2 = d / 2;

    let angle = element.rotation + 90;

    let textRotation = 0;
    if (Math.sin(angle * Math.PI / 180) < 0) {
      textRotation = 180;
    }

    return (
      <g transform={`translate(-${w2}, -${d2})`}>
        <rect key='1' x="0" y="0" width={w} height={d} style={style}/>
        {/*        <text key='2' x='0' y='0'
              transform={`translate(${w / 2}, ${d / 2}) scale(1,-1) rotate(${textRotation})`}
              style={{textAnchor: 'middle', fontSize: '11px'}}>
          {translator.t(element.type)}
        </text>*/}
        <text key='3' x='0' y='6'
              transform={`translate(${w / 2}, ${d / 2}) scale(1,-1) rotate(${textRotation})`}
              style={{textAnchor: 'middle', fontSize: '14px'}}>
          {element.name}
        </text>
      </g>
    );
  },

  render3D: (element, layer, scene) => {
    const loader = new GLTFLoader();
    const lod = new Three.LOD();

    loader.load(model, (gltf) => {
      lod.addLevel(gltf.scene, 200);

      let value = new Three.Box3().setFromObject(lod);
      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);

      lod.position.x+= -DEPTH/6;
      lod.position.y+= HEIGHT/2 + ALTITUDE;
      lod.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
    })

    return Promise.resolve(lod);
  }
};

image

you will need to use "three": "^0.161.0" and fix some imports & bugs in Luccid-ai/react-planner sources, like this :

image

faces are not available in this three version image

image

remove old packaged ThreeCSG file and use sources image

etc....

good luck