diff options
Diffstat (limited to 'client/splash/face/mesh.js')
| -rw-r--r-- | client/splash/face/mesh.js | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/client/splash/face/mesh.js b/client/splash/face/mesh.js index 82e7fa6a..de8cd28c 100644 --- a/client/splash/face/mesh.js +++ b/client/splash/face/mesh.js @@ -1,6 +1,128 @@ +import { Mesh, MeshBasicMaterial, VertexColors, TrianglesDrawMode } from 'three' + +import { scene } from '../renderer' + import DRACOLoader from '../../util/vendor/DRACOLoader' import GeometryHelper from '../../util/vendor/geometryHelper' DRACOLoader.setDecoderPath('/assets/js/vendor/draco/') const dracoLoader = new DRACOLoader() DRACOLoader.getDecoderModule() + +export function load(name) { + dracoLoader.load('/assets/data/faces/' + name + '.drc', (geometry) => { + geometry.computeVertexNormals() + + const material = new MeshBasicMaterial({ vertexColors: VertexColors }) + const mesh = new Mesh(geometry, material) + scene.add(mesh) + console.log(name) + + // Release the cached decoder module. + DRACOLoader.releaseDecoderModule() + }) +} + +export function update(name) { + load(name) +} + +function setDequantizationForMaterial(material, bufferGeometry) { + material.onBeforeCompile = function(shader) { + // Add uniform variables needed for dequantization. + var posAttribute = bufferGeometry.attributes['position']; + shader.uniforms.normConstant = + { value: posAttribute.maxRange / (1 << posAttribute.numQuantizationBits) }; + shader.uniforms.minPos = { value: posAttribute.minValues }; + + shader.vertexShader = 'uniform float maxRange;\n' + + 'uniform float normConstant;\n' + + 'uniform vec3 minPos;\n' + + shader.vertexShader; + shader.vertexShader = shader.vertexShader.replace( + '#include <begin_vertex>', + 'vec3 transformed = minPos + position * normConstant;' + ); + } +} + +export function loadFromPath() { + // Enable logging to console output. + dracoLoader.setVerbosity(1) + + // To use triangle strips use: + // dracoLoader.setDrawMode(THREE.TriangleStripDrawMode) + dracoLoader.setDrawMode(THREE.TrianglesDrawMode) + + // Skip dequantization of the position attribute. It will be done on the GPU. + dracoLoader.setSkipDequantization('position', true) + dracoLoader.decodeDracoFile(reader.result, function(bufferGeometry) { + // if (dracoLoader.decode_time !== undefined) { + // fileDisplayArea.innerText = 'Decode time = ' + dracoLoader.decode_time + '\n' + + // 'Import time = ' + dracoLoader.import_time + // } + var material = new THREE.MeshBasicMaterial({ vertexColors: VertexColors }) + material.wireframe = true + // If the position attribute is quantized, modify the material to perform + // dequantization on the GPU. + if (bufferGeometry.attributes['position'].isQuantized) { + setDequantizationForMaterial(material, bufferGeometry) + } + + var geometry; + // Point cloud does not have face indices. + if (bufferGeometry.index == null) { + geometry = new THREE.Points(bufferGeometry, material); + } else { + if (bufferGeometry.attributes.normal === undefined) { + var geometryHelper = new GeometryHelper(); + geometryHelper.computeVertexNormals(bufferGeometry); + } + geometry = new THREE.Mesh(bufferGeometry, material); + geometry.drawMode = dracoLoader.drawMode; + } + + // Compute range of the geometry coordinates for proper rendering. + bufferGeometry.computeBoundingBox(); + if (bufferGeometry.attributes['position'].isQuantized) { + // If the geometry is quantized, transform the bounding box to the dequantized + // coordinates. + var posAttribute = bufferGeometry.attributes['position']; + var normConstant = + posAttribute.maxRange / (1 << posAttribute.numQuantizationBits); + var minPos = posAttribute.minValues; + bufferGeometry.boundingBox.max.x = + minPos[0] + bufferGeometry.boundingBox.max.x * normConstant; + bufferGeometry.boundingBox.max.y = + minPos[1] + bufferGeometry.boundingBox.max.y * normConstant; + bufferGeometry.boundingBox.max.z = + minPos[2] + bufferGeometry.boundingBox.max.z * normConstant; + bufferGeometry.boundingBox.min.x = + minPos[0] + bufferGeometry.boundingBox.min.x * normConstant; + bufferGeometry.boundingBox.min.y = + minPos[1] + bufferGeometry.boundingBox.min.y * normConstant; + bufferGeometry.boundingBox.min.z = + minPos[2] + bufferGeometry.boundingBox.min.z * normConstant; + } + var sizeX = bufferGeometry.boundingBox.max.x - bufferGeometry.boundingBox.min.x; + var sizeY = bufferGeometry.boundingBox.max.y - bufferGeometry.boundingBox.min.y; + var sizeZ = bufferGeometry.boundingBox.max.z - bufferGeometry.boundingBox.min.z; + var diagonalSize = Math.sqrt(sizeX * sizeX + sizeY * sizeY + sizeZ * sizeZ); + var scale = 1.0 / diagonalSize; + var midX = (bufferGeometry.boundingBox.min.x + bufferGeometry.boundingBox.max.x) / 2; + var midY = (bufferGeometry.boundingBox.min.y + bufferGeometry.boundingBox.max.y) / 2; + var midZ = (bufferGeometry.boundingBox.min.z + bufferGeometry.boundingBox.max.z) / 2; + + geometry.scale.multiplyScalar(scale); + geometry.position.x = -midX * scale; + geometry.position.y = -midY * scale; + geometry.position.z = -midZ * scale; + // geometry.castShadow = true; + // geometry.receiveShadow = true; + + var selectedObject = scene.getObjectByName("my_mesh"); + scene.remove(selectedObject); + geometry.name = "my_mesh"; + scene.add(geometry); + }); +} |
