diff --git a/examples/jsm/loaders/VOXLoader.js b/examples/jsm/loaders/VOXLoader.js index 7a03de6718517..fac5eb56df81b 100644 --- a/examples/jsm/loaders/VOXLoader.js +++ b/examples/jsm/loaders/VOXLoader.js @@ -1,15 +1,19 @@ import { + BufferGeometry, FileLoader, - Loader + Float32BufferAttribute, + Loader, + Mesh, + MeshStandardMaterial } from '../../../build/three.module.js'; class VOXLoader extends Loader { load( url, onLoad, onProgress, onError ) { - var scope = this; + const scope = this; - var loader = new FileLoader( scope.manager ); + const loader = new FileLoader( scope.manager ); loader.setPath( scope.path ); loader.setResponseType( 'arraybuffer' ); loader.setRequestHeader( scope.requestHeader ); @@ -156,4 +160,101 @@ class VOXLoader extends Loader { } -export { VOXLoader }; +class VOXMesh extends Mesh { + + constructor( chunk ) { + + const data = chunk.data; + const size = chunk.size; + const palette = chunk.palette; + + // + + const vertices = []; + const colors = []; + + const nx = [ 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 ]; + const px = [ 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0 ]; + const py = [ 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 ]; + const ny = [ 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0 ]; + const nz = [ 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0 ]; + const pz = [ 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1 ]; + + function add( tile, x, y, z, r, g, b ) { + + x -= size.x / 2; + y -= size.z / 2; + z += size.y / 2; + + for ( let i = 0; i < 18; i += 3 ) { + + vertices.push( tile[ i + 0 ] + x, tile[ i + 1 ] + y, tile[ i + 2 ] + z ); + colors.push( r, g, b ); + + } + + } + + // Store data in a volume for sampling + + const offsety = size.x; + const offsetz = size.x * size.y; + + const array = new Uint8Array( size.x * size.y * size.z ); + + for ( let j = 0; j < data.length; j += 4 ) { + + const x = data[ j + 0 ]; + const y = data[ j + 1 ]; + const z = data[ j + 2 ]; + + const index = x + ( y * offsety ) + ( z * offsetz ); + + array[ index ] = 255; + + } + + // Construct geometry + + let hasColors = false; + + for ( let j = 0; j < data.length; j += 4 ) { + + const x = data[ j + 0 ]; + const y = data[ j + 1 ]; + const z = data[ j + 2 ]; + const c = data[ j + 3 ]; + + const hex = palette[ c ]; + const r = ( hex >> 0 & 0xff ) / 0xff; + const g = ( hex >> 8 & 0xff ) / 0xff; + const b = ( hex >> 16 & 0xff ) / 0xff; + + if ( r > 0 || g > 0 || b > 0 ) hasColors = true; + + const index = x + ( y * offsety ) + ( z * offsetz ); + + if ( array[ index + 1 ] === 0 || x === size.x - 1 ) add( px, x, z, - y, r, g, b ); + if ( array[ index - 1 ] === 0 || x === 0 ) add( nx, x, z, - y, r, g, b ); + if ( array[ index + offsety ] === 0 || y === size.y - 1 ) add( ny, x, z, - y, r, g, b ); + if ( array[ index - offsety ] === 0 || y === 0 ) add( py, x, z, - y, r, g, b ); + if ( array[ index + offsetz ] === 0 || z === size.z - 1 ) add( pz, x, z, - y, r, g, b ); + if ( array[ index - offsetz ] === 0 || z === 0 ) add( nz, x, z, - y, r, g, b ); + + } + + const geometry = new BufferGeometry(); + geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + geometry.computeVertexNormals(); + + if ( hasColors ) geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) ); + + const material = new MeshStandardMaterial( { vertexColors: hasColors } ); + + super( geometry, material ); + + } + +} + +export { VOXLoader, VOXMesh }; diff --git a/examples/webgl_loader_vox.html b/examples/webgl_loader_vox.html index 9788c796c2557..1f7b0d99042e5 100644 --- a/examples/webgl_loader_vox.html +++ b/examples/webgl_loader_vox.html @@ -17,7 +17,7 @@ import * as THREE from '../build/three.module.js'; import { OrbitControls } from './jsm/controls/OrbitControls.js'; - import { VOXLoader } from './jsm/loaders/VOXLoader.js'; + import { VOXLoader, VOXMesh } from './jsm/loaders/VOXLoader.js'; let camera, controls, scene, renderer; @@ -52,12 +52,9 @@ const chunk = chunks[ i ]; - const geometry = buildGeometry( chunk ); - const material = new THREE.MeshStandardMaterial( { - vertexColors: geometry.hasAttribute( 'color' ) - } ); + // displayPalette( chunk.palette ); - const mesh = new THREE.Mesh( geometry, material ); + const mesh = new VOXMesh( chunk ); mesh.scale.setScalar( 0.0015 ); scene.add( mesh ); @@ -84,97 +81,6 @@ } - function buildGeometry( chunk ) { - - const data = chunk.data; - const size = chunk.size; - const palette = chunk.palette; - - // displayPalette( palette ); - - const vertices = []; - const colors = []; - - const nx = [ 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1 ]; - const px = [ 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0 ]; - const py = [ 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 ]; - const ny = [ 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0 ]; - const nz = [ 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0 ]; - const pz = [ 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1 ]; - - function add( tile, x, y, z, r, g, b ) { - - x -= size.x / 2; - y -= size.z / 2; - z += size.y / 2; - - for ( let i = 0; i < 18; i += 3 ) { - - vertices.push( tile[ i + 0 ] + x, tile[ i + 1 ] + y, tile[ i + 2 ] + z ); - colors.push( r, g, b ); - - } - - } - - // Store data in a volume for sampling - - const offsety = size.x; - const offsetz = size.x * size.y; - - const array = new Uint8Array( size.x * size.y * size.z ); - - for ( let j = 0; j < data.length; j += 4 ) { - - const x = data[ j + 0 ]; - const y = data[ j + 1 ]; - const z = data[ j + 2 ]; - - const index = x + ( y * offsety ) + ( z * offsetz ); - - array[ index ] = 255; - - } - - // Construct geometry - - let hasColors = false; - - for ( let j = 0; j < data.length; j += 4 ) { - - const x = data[ j + 0 ]; - const y = data[ j + 1 ]; - const z = data[ j + 2 ]; - const c = data[ j + 3 ]; - - const hex = palette[ c ]; - const r = ( hex >> 0 & 0xff ) / 0xff; - const g = ( hex >> 8 & 0xff ) / 0xff; - const b = ( hex >> 16 & 0xff ) / 0xff; - - if ( r > 0 || g > 0 || b > 0 ) hasColors = true; - - const index = x + ( y * offsety ) + ( z * offsetz ); - - if ( array[ index + 1 ] === 0 || x === size.x - 1 ) add( px, x, z, - y, r, g, b ); - if ( array[ index - 1 ] === 0 || x === 0 ) add( nx, x, z, - y, r, g, b ); - if ( array[ index + offsety ] === 0 || y === size.y - 1 ) add( ny, x, z, - y, r, g, b ); - if ( array[ index - offsety ] === 0 || y === 0 ) add( py, x, z, - y, r, g, b ); - if ( array[ index + offsetz ] === 0 || z === size.z - 1 ) add( pz, x, z, - y, r, g, b ); - if ( array[ index - offsetz ] === 0 || z === 0 ) add( nz, x, z, - y, r, g, b ); - - } - - const geometry = new THREE.BufferGeometry(); - geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) ); - geometry.computeVertexNormals(); - - if ( hasColors ) geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) ); - - return geometry; - - } - /* function displayPalette( palette ) {