author Yannick Deubel (https://github.com/yandeu)
 *  copyright license https import { BufferGeometry , Color , DoubleSide , MeshPhongMaterial , MeshPhongMaterialParameters , PlaneBufferGeometry , Scene , Texture } from 'three' ; import { ExtendedMesh } from '@enable3d/common/dist/extendedMesh' ; import { HeightMapConfig } from '@enable3d/common/dist/types' ; import { Geometry } from 'three/examples/jsm/deprecated/Geometry' ; import { Face3 } from '@enable3d/three-wrapper/dist/deprecated/face3' ; import { fromGeometry } from '../csg/_fromGeometry' ; export default class HeightMap { constructor ( private scene ) { } public add ( texture , config = { } ) { const heightMap = this . make ( texture , config ) ; if ( heightMap ) this . scene . add ( heightMap ) ; else console . warn ( 'Could not make heightmap' ) ; return heightMap ; } public make ( texture , config = { } ) { const { image } = texture ; const { width , height } = image ; const { colorScale } = config ; const canvas = document . createElement ( 'canvas' ) ; canvas . width = width ; canvas . height = height ; const ctx = canvas . getContext ( '2d' ) ; if ( ! ctx ) return ; ctx . drawImage ( texture . image , 0 , 0 ) ; const pixel = ctx . getImageData ( 0 , 0 , width , height ) ; const plane = new Geometry ( ) . fromBufferGeometry ( new PlaneBufferGeometry ( 10 , 10 , width - 1 , height - 1 ) ) ; let materialConfig = { color : 0xcccccc , side : DoubleSide } ; if ( colorScale ) materialConfig = { ... materialConfig , vertexColors : true } ; const material = new MeshPhongMaterial ( materialConfig ) ; const mesh = new ExtendedMesh ( plane , material ) ; mesh . receiveShadow = mesh . castShadow = true ; mesh . shape = 'concave' ; const geo = mesh . geometry as Geometry ; for ( let i = 0 ; i < geo . vertices . length ; i ++ ) { geo . vertices [ i ] . z = pixel . data [ i * 4 ] / 120 ; } const getHighPoint = ( geometry , face ) => { var v1 = geometry . vertices [ face . a ] . z ; var v2 = geometry . vertices [ face . b ] . z ; var v3 = geometry . vertices [ face . c ] . z ; return Math . max ( v1 , v2 , v3 ) ; } ; if ( colorScale ) geo . faces . forEach ( face => ( face . color = new Color ( colorScale ( getHighPoint ( geo , face ) ) . hex ( ) ) ) ) ; mesh . rotateX ( - Math . PI / 2 ) ; mesh . updateMatrix ( ) ; plane . computeFaceNormals ( ) ; plane . computeVertexNormals ( ) ; mesh . name = 'heightmap' ; mesh . geometry = fromGeometry ( new BufferGeometry ( ) , mesh . geometry ) ; return mesh as ExtendedMesh ; } }