import { Geometry } from 'three/examples/jsm/deprecated/Geometry' ; import { BufferGeometry , Mesh , MeshBasicMaterial , OrthographicCamera , PerspectiveCamera , PlaneBufferGeometry , Raycaster , Shape , Vector2 , Vector3 , WebGLRenderer } from 'three' ; import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader' ; import { fromGeometry } from '../csg/_fromGeometry' ; author Yannick Deubel (https://github.com/yandeu)
 *  copyright license https export default class Transform { tmpPlane ! : Mesh ; tmpRaycaster ! : Raycaster ; tmpVector3 ! : Vector3 ; constructor ( private camera , private renderer ) { } static geometryToBufferGeometry ( geometry ) { if ( geometry . isGeometry ) return fromGeometry ( new BufferGeometry ( ) , geometry ) ; else return geometry as any ; } static bufferGeometryToGeometry ( bufferGeometry ) { if ( bufferGeometry . isBufferGeometry ) return new Geometry ( ) . fromBufferGeometry ( bufferGeometry ) ; else return bufferGeometry as any ; } /**
     * Transforms your svg files to paths.
     */ public fromSVGtoShape ( svg , isCCW = false , noHoles ? ) { if ( svg ) { const svgLoader = new SVGLoader ( ) ; const shapes = [ ] ; svgLoader . parse ( svg ) . paths . forEach ( path => { path . toShapes ( isCCW , noHoles ) . forEach ( shape => { shapes . push ( shape ) ; } ) ; } ) ; return shapes ; } return [ ] ; } public from3dto2d ( position ) { const vector3 = new Vector3 ( position . x , position . y , position . z ) ; const canvas = this . renderer . domElement ; this . camera . updateMatrixWorld ( ) ; vector3 . project ( this . camera ) ; const x = Math . round ( ( vector3 . x + 1 ) * ( canvas . width / 2 ) ) ; const y = Math . round ( ( - vector3 . y + 1 ) * ( canvas . height / 2 ) ) ; return new Vector2 ( x , y ) ; } param x param y param distanceFromCamera public from2dto3d ( x , y , distanceFromCamera ) { if ( ! this . tmpPlane ) { const geo = new PlaneBufferGeometry ( 10000 , 10000 ) ; const mat = new MeshBasicMaterial ( { transparent : true , opacity : 0.25 } ) ; this . tmpPlane = new Mesh ( geo , mat ) ; this . tmpPlane . name = '_tmp_raycast_plane' ; } if ( ! this . tmpRaycaster ) this . tmpRaycaster = new Raycaster ( ) ; if ( ! this . tmpVector3 ) this . tmpVector3 = new Vector3 ( ) ; let position ; this . tmpPlane . setRotationFromEuler ( this . camera . rotation ) ; const p = this . camera . position ; this . tmpPlane . position . set ( p . x , p . y , p . z ) ; this . camera . getWorldDirection ( this . tmpVector3 ) ; this . tmpPlane . position . add ( this . tmpVector3 . clone ( ) . multiplyScalar ( distanceFromCamera ) ) ; this . tmpPlane . updateMatrix ( ) ; this . tmpPlane . updateMatrixWorld ( true ) ; this . tmpRaycaster . setFromCamera ( { x , y } , this . camera ) ; const intersects = this . tmpRaycaster . intersectObjects ( [ this . tmpPlane ] ) ; if ( intersects [ 0 ] ?. object . name === '_tmp_raycast_plane' ) position = intersects [ 0 ] . point ; return position ; } }