Sin Descripción

thrixl.html 4.6KB

    <!doctype html> <html> <head> <title>.thrixl</title> <meta charset="utf-8" /> <style> canvas { position: absolute; top: 0; left: 0; } </style> </head> <body> <script src="three.js"></script> <script src="three.flycontrols.js"></script> <script src="geometry.js"></script> <script> window.trixl = {}; trixl.chunks = {}; trixl.chunkSize = 32; trixl.bits = 5; trixl.toChunk = function(pos) { var b = trixl.bits; return [pos[1] >> b, pos[2] >> b, pos[3] >> b]; } trixl.toIndex = function(pos) { var b = trixl.bits; var mask = (1 << b) - 1; return (pos[0] & mask) + ((pos[1] & mask) << b) + ((pos[2] & mask) << b * 2); } trixl.set = function(pos, data) { var chunkIndex = trixl.toChunk(pos).join(','); var chunk = trixl.chunks[chunkIndex]; if (!chunk) { chunk = trixl.chunks[chunkIndex] = { voxels: [] }; } data.pos = pos; chunk.voxels[trixl.toIndex(pos)] = data; chunk.dirty = true; } trixl.get = function(pos) { var chunk = trixl.chunks[trixl.toChunk(pos).join(',')]; return chunk ? (chunk.voxels[trixl.toIndex(pos)] || null) : null; } var cube = new THREE.CubeGeometry(1, 1, 1); trixl.toGeometry = function(chunk) { var chunkGeometry = new THREE.Object3D(); for (var i = 0; i < chunk.voxels.length; i++) { var voxel = chunk.voxels[i]; if (!voxel) { continue; } var mesh = new THREE.Mesh(cube, new THREE.MeshBasicMaterial({color: voxel.color})); mesh.position.x = voxel.pos[0]; mesh.position.y = voxel.pos[1]; mesh.position.z = voxel.pos[2]; mesh.frustumCulled = false; mesh.matrixAutoUpdate = false; mesh.updateMatrix(); chunkGeometry.add(mesh); } return chunkGeometry; } trixl.toBufferGeometry = function(chunk) { var n = 0; for (var i = 0; i < chunk.voxels.length; i++) { n += chunk.voxels[i] ? 1 : 0; } var chunkGeometry = new THREE.BufferGeometry(); // 6 sides * 2 triangles var m = 6 * 2; var vs = n * m * 3 * 3; chunkGeometry.addAttribute('position', Float32Array, vs, 3); chunkGeometry.addAttribute('normal', Float32Array, vs, 3); chunkGeometry.addAttribute('color', Float32Array, vs, 3); var positions = chunkGeometry.attributes.position.array; var normals = chunkGeometry.attributes.normal.array; var colors = chunkGeometry.attributes.color.array; var cube = geometry.cube(); cube.normals = geometry.cube.normals(); var c = -1; for (var i = 0; i < chunk.voxels.length; i++) { var voxel = chunk.voxels[i]; if (!voxel) continue; c += 1; var x = voxel.pos[0], y = voxel.pos[1], z = voxel.pos[2]; for (var j = 0; j < cube.length; j += 3) { positions[c * m * 9 + j + 0] = x + cube[j + 0] positions[c * m * 9 + j + 1] = y + cube[j + 1] positions[c * m * 9 + j + 2] = z + cube[j + 2] normals[c * m * 9 + j + 0] = cube.normals[j + 0]; normals[c * m * 9 + j + 1] = cube.normals[j + 1]; normals[c * m * 9 + j + 2] = cube.normals[j + 2]; colors[c * m * 9 + j + 0] = voxel.color[0]; colors[c * m * 9 + j + 1] = voxel.color[1]; colors[c * m * 9 + j + 2] = voxel.color[2]; } } chunkGeometry.computeBoundingSphere(); var material = new THREE.MeshBasicMaterial({color: 0x00ff00}); return new THREE.Mesh(chunkGeometry, material); } trixl.generate = {} trixl.generate.many = function(n, lo, hi) { for (var i = 0; i < n; i++) { var pos = [ lo + Math.random() * (hi - lo), lo + Math.random() * (hi - lo), lo + Math.random() * (hi - lo) ]; var color = [Math.random(), Math.random(), Math.random()]; trixl.set(pos, {color: color}); } } var scene = new THREE.Scene(); var aspect = window.innerWidth / window.innerHeight; var camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000); camera.position.z = 10; var controls = new THREE.FlyControls(camera); controls.movementSpeed = 5.0; controls.rollSpeed = 0.75; var renderer = new THREE.WebGLRenderer(); renderer.sortObjects = false; renderer.setClearColor(0xffffff); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); var group = new THREE.Object3D(); group.frustumCulled = false; scene.add(group); var clock = new THREE.Clock(); var render = function() { requestAnimationFrame(render); for (var key in trixl.chunks) { var chunk = trixl.chunks[key]; if (chunk.dirty) { group.remove(chunk.geometry); chunk.geometry = trixl.toGeometry(chunk); chunk.dirty = false; group.add(chunk.geometry); } } controls.update(clock.getDelta()); renderer.render(scene, camera); } render(); </script> </body> </html>