diff --git a/index.html b/index.html index c23c1ec0d6..a3354a9d17 100644 --- a/index.html +++ b/index.html @@ -1651,289 +1651,12 @@ })(); scene.add(gridMesh); */ -worker = (() => { - let cbs = []; - const worker = new Worker('mc-worker.js'); - worker.onmessage = e => { - const {data} = e; - const {error, result} = data; - cbs.shift()(error, result); - }; - worker.onerror = err => { - console.warn(err); - }; - worker.request = (req, transfers) => new Promise((accept, reject) => { - worker.postMessage(req, transfers); - - cbs.push((err, result) => { - if (!err) { - accept(result); - } else { - reject(err); - } - }); - }); - return worker; -})(); const _makeMiningPlaceholderMesh = (x, z, owner) => { - // console.log('make text mesh', token); - const mesh = _makeTextMesh('Parcel ' + x + ' : ' + z + ' owned by ' + owner, 30); - mesh.position.set(x * PARCEL_SIZE, 1, z * PARCEL_SIZE); - // mesh.token = token; - mesh.update = () => { - // XXX - }; - mesh.intersect = () => null; - mesh.destroy = () => { - // XXX - }; + const mesh = new THREE.Object3D(); return mesh; }; -const _makeMiningMesh = (x, z/*, token*/) => { - const terrainVsh = ` - varying vec3 vViewPosition; - void main() { - vec4 mvPosition = modelMatrix * vec4( position.xyz, 1.0 ); - gl_Position = projectionMatrix * modelViewMatrix * vec4( position.xyz, 1.0 ); - vViewPosition = mvPosition.xyz; - } - `; - const terrainFsh = ` - uniform vec3 uSelect; - varying vec3 vViewPosition; - vec4 color = vec4(${new THREE.Color(0x9ccc65).toArray().map(n => n.toFixed(8)).join(',')}, 1.0); - vec4 color2 = vec4(${new THREE.Color(0xec407a).toArray().map(n => n.toFixed(8)).join(',')}, 1.0); - bool inRange(vec3 pos, vec3 minPos, vec3 maxPos) { - return pos.x >= minPos.x && - pos.y >= minPos.y && - pos.z >= minPos.z && - pos.x <= maxPos.x && - pos.y <= maxPos.y && - pos.z <= maxPos.z; - } - void main() { - vec3 fdx = vec3( dFdx( -vViewPosition.x ), dFdx( -vViewPosition.y ), dFdx( -vViewPosition.z ) ); - vec3 fdy = vec3( dFdy( -vViewPosition.x ), dFdy( -vViewPosition.y ), dFdy( -vViewPosition.z ) ); - vec3 normal = normalize( cross( fdx, fdy ) ); - float dotNL = saturate( dot( normal, normalize(vec3(1.0, 1.0, 1.0))) ); - - float range = 1.01; - // float range = 2.01; - vec3 minPos = uSelect - range; - vec3 maxPos = minPos + (range*2.); - if (inRange(vViewPosition, minPos, maxPos)) { - gl_FragColor = color2; - } else { - gl_FragColor = color; - } - gl_FragColor.rgb += dotNL * 0.5; - } - `; - - const geometry = new THREE.BufferGeometry(); - const material = new THREE.ShaderMaterial({ - uniforms: { - uSelect: { - type: 'v3', - value: new THREE.Vector3(NaN, NaN, NaN), - }, - }, - vertexShader: terrainVsh, - fragmentShader: terrainFsh, - extensions: { - derivatives: true, - }, - }); - const mesh = new THREE.Mesh(geometry, material); - mesh.frustumCulled = false; - mesh.visible = false; - // mesh.token = token; - - const size = PARCEL_SIZE; - const dims = Float32Array.from([size, size, size]); - const potential = new Float32Array(size*size*size); - potential.fill(1); - for (let x = 0; x < size; x++) { - for (let y = 0; y < size; y++) { - for (let z = 0; z < size; z++) { - if ( - x === 0 || y === 0 || z === 0 || - x === (size-1) || y === (size-1) || z === (size-1) - ) { - potential[x + y*size + z*size*size] = 0; - } - } - } - } - const shift = Float32Array.from([(x-0.5)*size, 0, (z-0.5)*size]); - - mesh.x = x; - mesh.z = z; - mesh.potential = potential; - mesh.shift = shift; - mesh.contains = pos => - pos.x >= shift[0] && - pos.y >= shift[1] && - pos.z >= shift[2] && - pos.x < shift[0] + size && - pos.y < shift[1] + size && - pos.z < shift[2] + size; - mesh.getPotential = pos => { - const x = pos.x - shift[0]; - const y = pos.y - shift[1]; - const z = pos.z - shift[2]; - return potential[x + y*size*size + z*size]; - }; - mesh.mine = pos => { - const x = Math.floor(pos.x - shift[0]); - const y = Math.floor(pos.y - shift[1]); - const z = Math.floor(pos.z - shift[2]); - const factor = 2; - const max = Math.sqrt(factor*factor*3); - for (let dx = -factor; dx <= factor; dx++) { - for (let dz = -factor; dz <= factor; dz++) { - for (let dy = -factor; dy <= factor; dy++) { - const ax = x + dx; - const ay = y + dy; - const az = z + dz; - if ( - ax >= 0 && - ay >= 0 && - az >= 0 && - ax < size && - ay < size && - az < size - ) { - const index = ax + ay*size*size + az*size; - const d = (max - Math.sqrt(dx*dx + dy*dy + dz*dz)) / max * 2; - potential[index] = Math.max(potential[index] - d, 0); - } - } - } - } - worker.request({ - method: 'march', - dims, - potential, - shift, - }).then(res => { - geometry.addAttribute('position', new THREE.BufferAttribute(res.positions, 3)); - geometry.setIndex(new THREE.BufferAttribute(res.faces, 1)); - - if (potential.every(n => n <= 0)) { - const {x, z} = mesh; - fetch('https://djj7y2i5p8.execute-api.us-west-1.amazonaws.com/default/Webaverse', { - method: 'POST', - body: JSON.stringify({ - addr: window.web3.eth.defaultAccount, - x, - y: z, - }), - }) - .then(res => res.json()) - .then(o => { - const {v, r, s} = o; - const addr = window.web3.eth.defaultAccount; - console.log('mintTokenFromSignature', {addr, x, z, v, r, s}); - return user.execute({ - method: 'mintTokenFromSignature', - data: { - addr, - x, - y: z, - v, - r, - s, - }, - }); - }) - .then(() => { - console.log('mined', {x, z}); - - for (;;) { - const index = sceneMeshes.findIndex(sceneMesh => sceneMesh.token.coords.some(coord => coord[0] === x && coord[1] === z)); - if (index !== -1) { - const sceneMesh = sceneMeshes[index]; - sceneMesh.destroy(); - scene.remove(sceneMesh); - sceneMeshes.splice(index, 1); - } else { - break; - } - } - - const sceneMesh = _makeSceneObjectMesh(); - sceneMesh.token = { - id: 0, - coords: [[x, z]], - apps: [], - owner: _getUserAddress(), - }; - scene.add(sceneMesh); - sceneMeshes.push(sceneMesh); - - selectedSceneToken = null; - - lastSceneCoords[0] = NaN; - lastSceneCoords[1] = NaN; - }); - } - }); - }; - mesh.destroy = () => { - geometry.dispose(); - material.dispose(); - }; - let colliding = false; - mesh.update = () => { - if (!colliding && geometry.attributes.position) { - colliding = true; - - const controllerMesh = controllerMeshes[1]; // XXX make this work for all controllers - worker.request({ - method: 'collide', - positions: geometry.attributes.position.array, - indices: geometry.index.array, - origin: controllerMesh.ray.origin.toArray(new Float32Array(3)), - direction: controllerMesh.ray.direction.toArray(new Float32Array(3)), - }) - .then(collision => { - material.uniforms.uSelect.value.fromArray(collision); - }) - .catch(err => { - console.warn(err.stack); - }) - .finally(() => { - colliding = false; - }); - } - }; - mesh.intersect = ray => { - if (isFinite(material.uniforms.uSelect.value.x)) { - const intersectionPoint = material.uniforms.uSelect.value.clone(); - const distance = ray.origin.distanceTo(intersectionPoint); - return { - type: 'mine', - mesh, - intersectionPoint, - distance, - }; - } else { - return null; - } - }; - - worker.request({ - method: 'march', - dims, - potential, - shift, - }).then(res => { - geometry.addAttribute('position', new THREE.BufferAttribute(res.positions, 3)); - geometry.setIndex(new THREE.BufferAttribute(res.faces, 1)); - mesh.visible = true; - }); - +const _makeMiningMesh = (x, z) => { + const mesh = new THREE.Object3D(); return mesh; }; let data; diff --git a/mc-worker.js b/mc-worker.js deleted file mode 100644 index d408261cc1..0000000000 --- a/mc-worker.js +++ /dev/null @@ -1,157 +0,0 @@ -/* importScripts('/archae/plugins/_core_engines_resource/serve/three.js'); -const {exports: THREE} = self.module; -importScripts('/archae/assets/murmurhash.js'); -const {exports: murmur} = self.module; -importScripts('/archae/assets/autows.js'); -const {exports: Autows} = self.module; -importScripts('/archae/assets/alea.js'); -const {exports: alea} = self.module; -self.module = {}; */ - -// let Module = null; -// let slab = null; -self.wasmModule = (moduleName, moduleFn) => { - // console.log('wasm module', moduleName, moduleFn); - if (moduleName === 'mc') { - self.LocalModule = moduleFn({ - print(text) { console.log(text); }, - printErr(text) { console.warn(text); }, - locateFile(path, scriptDirectory) { - if (path === 'mc.wasm') { - return 'bin/' + path; - } else { - return path; - } - }, - onRuntimeInitialized: () => { - // Module = localModule; - - loaded = true; - _flushMessages(); - }, - }); - - // console.log('got module', Module); - } else { - console.warn('unknown wasm module', moduleName); - } -}; -importScripts('bin/mc.js'); - -class Allocator { - constructor() { - this.offsets = []; - } - alloc(constructor, size) { - const offset = self.LocalModule._doMalloc(size * constructor.BYTES_PER_ELEMENT); - const b = new constructor(self.LocalModule.HEAP8.buffer, self.LocalModule.HEAP8.byteOffset + offset, size); - b.offset = offset; - this.offsets.push(offset); - return b; - } - freeAll() { - for (let i = 0; i < this.offsets.length; i++) { - self.LocalModule._doFree(this.offsets[i]); - } - this.offsets.length = 0; - } -} - -const queue = []; -let loaded = false; -const _handleMessage = data => { - const {method} = data; - switch (method) { - case 'march': { - const allocator = new Allocator(); - - const {dims: dimsData, potential: potentialData, shift: shiftData} = data; - const dims = allocator.alloc(Int32Array, 3); - dims[0] = dimsData[0]; - dims[1] = dimsData[1]; - dims[2] = dimsData[2]; - const potential = allocator.alloc(Float32Array, potentialData.length); - potential.set(potentialData); - const shift = allocator.alloc(Float32Array, 3); - shift[0] = shiftData[0]; - shift[1] = shiftData[1]; - shift[2] = shiftData[2]; - const indexOffset = 0; - const positions = allocator.alloc(Float32Array, 1024*1024/Float32Array.BYTES_PER_ELEMENT); - const faces = allocator.alloc(Uint32Array, 1024*1024/Uint32Array.BYTES_PER_ELEMENT); - const positionIndex = allocator.alloc(Uint32Array, 1); - const faceIndex = allocator.alloc(Uint32Array, 1); - self.LocalModule._doMarchingCubes( - dims.offset, - potential.offset, - shift.offset, - indexOffset, - positions.offset, - faces.offset, - positionIndex.offset, - faceIndex.offset - ); - self.postMessage({ - result: { - positions: positions.slice(0, positionIndex[0]), - faces: faces.slice(0, faceIndex[0]), - }, - }); - allocator.freeAll(); - break; - } - case 'collide': { - const allocator = new Allocator(); - - const {positions: positionsData, indices: indicesData, origin: originData, direction: directionData} = data; - - const positions = allocator.alloc(Float32Array, positionsData.length); - positions.set(positionsData); - const indices = allocator.alloc(Uint32Array, indicesData.length); - indices.set(indicesData); - const origin = allocator.alloc(Float32Array, 3); - origin[0] = originData[0]; - origin[1] = originData[1]; - origin[2] = originData[2]; - const direction = allocator.alloc(Float32Array, 3); - direction[0] = directionData[0]; - direction[1] = directionData[1]; - direction[2] = directionData[2]; - const result = allocator.alloc(Float32Array, 3); - - self.LocalModule._doCollide( - positions.offset, - indices.offset, - positions.length, - indices.length, - origin.offset, - direction.offset, - result.offset - ); - - self.postMessage({ - result: Float32Array.from([result[0], result[1], result[2]]), - }); - - allocator.freeAll(); - break; - } - default: { - console.warn('unknown method', data.method); - break; - } - } -}; -const _flushMessages = () => { - for (let i = 0; i < queue.length; i++) { - _handleMessage(queue[i]); - } -}; -self.onmessage = e => { - const {data} = e; - if (!loaded) { - queue.push(data); - } else { - _handleMessage(data); - } -};