UNPKG

useloadpcd

Version:

A .pcd file loader for React with React hooks and Three.js.

129 lines (104 loc) 4.24 kB
import { useEffect, useRef, useState } from 'react'; import * as THREE from 'three'; import { IConfig, IFeedback } from './@types/types'; import loadConfig from './config/loadConfig'; import setupCamera from './config/setupCamera'; import setupControls from './config/setupControls'; import PCDLoader from './three/PCDLoader'; const load = ( path: string, configuration: IConfig ): [React.RefObject<HTMLDivElement>, IFeedback] => { const canvas = useRef<HTMLDivElement>(null); const [loading, setLoading] = useState<number>(0); const [err, setErr] = useState<ErrorEvent | null>(null); const [frameId, setFrameId] = useState<number | undefined>(undefined); const config = loadConfig(configuration); const getFile = async () => { const scene = new THREE.Scene(); scene.background = new THREE.Color(config.backgroundColor); const loader = new PCDLoader(); const camera = setupCamera(config.camera); scene.add(camera); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(config.windowSize.width, config.windowSize.height); if (canvas.current !== null) { const controls = setupControls( camera, canvas.current, config.controls ); await loader.load( path, mesh => { scene.add(mesh); const center = mesh.geometry.boundingSphere.center; controls.target.set(center.x, center.y, center.z); controls.update(); const sceneStyle = scene.getObjectByName( path.substring(path.lastIndexOf('/') + 1) ); if (config.particalColor !== undefined) { (sceneStyle as any).material.color = new THREE.Color( config.particalColor ); } (sceneStyle as any).material.size = 0.1; if (canvas.current !== null) { canvas.current.appendChild(renderer.domElement); } const renderScene = () => { renderer.render(scene, camera); }; const animate = () => { controls.update(); requestAnimationFrame(animate); renderScene(); }; const start = () => { if (!frameId) { setFrameId(requestAnimationFrame(animate)); } }; start(); const onWindowResize = () => { camera.aspect = config.windowSize.width / config.windowSize.height; camera.updateProjectionMatrix(); renderer.setSize( config.windowSize.width, config.windowSize.height ); controls.handleResize(); }; window.addEventListener('resize', onWindowResize, false); }, xhr => { const completed = (xhr.loaded / xhr.total) * 100; // console.log(completed + '% loaded'); setLoading(completed); }, error => { setErr(error); } ); } }; useEffect(() => { if (canvas.current !== null) { if (canvas.current.children.length === 0) { getFile(); } } }, []); return [ canvas, { error: err, loading: loading < 100, percentage: loading } ]; }; export default load;