├── .gitignore ├── collaborators.md ├── package.json ├── readme.md └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /collaborators.md: -------------------------------------------------------------------------------- 1 | ## Collaborators 2 | 3 | voxel-mesh is only possible due to the excellent work of the following collaborators: 4 | 5 | 6 | 7 |
maxogdenGitHub/maxogden
deathcapGitHub/deathcap
8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "voxel-mesh", 3 | "description": "generate a three.js mesh from voxel data", 4 | "version": "0.3.0", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "http://github.com/maxogden/voxel-mesh.git" 9 | }, 10 | "author": { 11 | "name": "Max Ogden", 12 | "email": "max@maxogden.com" 13 | }, 14 | "license": "MIT", 15 | "peerDependencies": { 16 | "three": "*" 17 | }, 18 | "engine": { 19 | "node": ">=0.6.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # voxel-mesh 2 | 3 | generate a three.js mesh from voxel data. extracted from some code by @mikolalysenko 4 | 5 | - original repo: https://github.com/mikolalysenko/mikolalysenko.github.com/tree/master/MinecraftMeshes2 6 | - blog post: http://0fps.wordpress.com/2012/07/07/meshing-minecraft-part-2/ 7 | - webgl demo: http://mikolalysenko.github.com/MinecraftMeshes2/ 8 | 9 | # installation 10 | 11 | it is recommended that you use browserify to use this module 12 | 13 | ``` 14 | npm install voxel-mesh 15 | npm install browserify -g 16 | browserify -r voxel-mesh > voxel-mesh-browserified.js 17 | ``` 18 | 19 | # usage 20 | 21 | ```javascript 22 | var Mesh = require('voxel-mesh') 23 | var voxelData = require('voxel').generator['Hilly Terrain'] 24 | var mesh = new Mesh(voxelData) 25 | mesh.createSurfaceMesh() 26 | threeJSScene.add(mesh) 27 | ``` 28 | 29 | ## new Mesh(voxelData, meshingAlgorithm, scaleFactor) 30 | 31 | `voxelData` and `meshingAlgorithm` are required, `scaleFactor` defaults to `new Three.Vector3(10, 10, 10)`. 32 | 33 | ## Mesh.prototype.createSurfaceMesh(material) 34 | 35 | returns the generated surface mesh. `material` defaults to `new THREE.MeshNormalMaterial()`. after calling this method your mesh will also have `.surfaceMesh` populated with the new mesh 36 | 37 | ## Mesh.prototype.createWireMesh(hexColor) 38 | 39 | returns the generated wire mesh. `hexColor` defaults to `0xffffff`. after calling this method your mesh will also have `.wireMesh` populated with the new mesh 40 | 41 | ## Mesh.prototype.addToScene(scene) 42 | 43 | convenience method for adding the currently generated meshes (either `surfaceMesh` or `wireMesh`) to a `three.js` scene instance 44 | 45 | ## Mesh.prototype.setPosition(x, y, z) 46 | 47 | convenience method for setting the position of the currently generated meshes (either `surfaceMesh` or `wireMesh`) 48 | 49 | # license 50 | 51 | MIT -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three') 2 | 3 | module.exports = function(data, mesher, scaleFactor, three) { 4 | return new Mesh(data, mesher, scaleFactor, three) 5 | } 6 | 7 | module.exports.Mesh = Mesh 8 | 9 | function Mesh(data, mesher, scaleFactor, three) { 10 | this.THREE = three || THREE 11 | this.data = data 12 | var geometry = this.geometry = new this.THREE.Geometry() 13 | this.scale = scaleFactor || new this.THREE.Vector3(10, 10, 10) 14 | 15 | var result = mesher( data.voxels, data.dims ) 16 | this.meshed = result 17 | 18 | geometry.vertices.length = 0 19 | geometry.faces.length = 0 20 | 21 | for (var i = 0; i < result.vertices.length; ++i) { 22 | var q = result.vertices[i] 23 | geometry.vertices.push(new this.THREE.Vector3(q[0], q[1], q[2])) 24 | } 25 | 26 | for (var i = 0; i < result.faces.length; ++i) { 27 | geometry.faceVertexUvs[0].push(this.faceVertexUv(i)) 28 | 29 | var q = result.faces[i] 30 | if (q.length === 5) { 31 | var f = new this.THREE.Face4(q[0], q[1], q[2], q[3]) 32 | f.color = new this.THREE.Color(q[4]) 33 | geometry.faces.push(f) 34 | } else if (q.length == 4) { 35 | var f = new this.THREE.Face3(q[0], q[1], q[2]) 36 | f.color = new this.THREE.Color(q[3]) 37 | geometry.faces.push(f) 38 | } 39 | } 40 | 41 | geometry.computeFaceNormals() 42 | 43 | geometry.verticesNeedUpdate = true 44 | geometry.elementsNeedUpdate = true 45 | geometry.normalsNeedUpdate = true 46 | 47 | geometry.computeBoundingBox() 48 | geometry.computeBoundingSphere() 49 | 50 | } 51 | 52 | Mesh.prototype.createWireMesh = function(hexColor) { 53 | var wireMaterial = new this.THREE.MeshBasicMaterial({ 54 | color : hexColor || 0xffffff, 55 | wireframe : true 56 | }) 57 | wireMesh = new this.THREE.Mesh(this.geometry, wireMaterial) 58 | wireMesh.scale = this.scale 59 | wireMesh.doubleSided = true 60 | this.wireMesh = wireMesh 61 | return wireMesh 62 | } 63 | 64 | Mesh.prototype.createSurfaceMesh = function(material) { 65 | material = material || new this.THREE.MeshNormalMaterial() 66 | var surfaceMesh = new this.THREE.Mesh( this.geometry, material ) 67 | surfaceMesh.scale = this.scale 68 | surfaceMesh.doubleSided = false 69 | this.surfaceMesh = surfaceMesh 70 | return surfaceMesh 71 | } 72 | 73 | Mesh.prototype.addToScene = function(scene) { 74 | if (this.wireMesh) scene.add( this.wireMesh ) 75 | if (this.surfaceMesh) scene.add( this.surfaceMesh ) 76 | } 77 | 78 | Mesh.prototype.setPosition = function(x, y, z) { 79 | if (this.wireMesh) this.wireMesh.position = new this.THREE.Vector3(x, y, z) 80 | if (this.surfaceMesh) this.surfaceMesh.position = new this.THREE.Vector3(x, y, z) 81 | } 82 | 83 | Mesh.prototype.faceVertexUv = function(i) { 84 | var vs = [ 85 | this.meshed.vertices[i*4+0], 86 | this.meshed.vertices[i*4+1], 87 | this.meshed.vertices[i*4+2], 88 | this.meshed.vertices[i*4+3] 89 | ] 90 | var spans = { 91 | x0: vs[0][0] - vs[1][0], 92 | x1: vs[1][0] - vs[2][0], 93 | y0: vs[0][1] - vs[1][1], 94 | y1: vs[1][1] - vs[2][1], 95 | z0: vs[0][2] - vs[1][2], 96 | z1: vs[1][2] - vs[2][2] 97 | } 98 | var size = { 99 | x: Math.max(Math.abs(spans.x0), Math.abs(spans.x1)), 100 | y: Math.max(Math.abs(spans.y0), Math.abs(spans.y1)), 101 | z: Math.max(Math.abs(spans.z0), Math.abs(spans.z1)) 102 | } 103 | if (size.x === 0) { 104 | if (spans.y0 > spans.y1) { 105 | var width = size.y 106 | var height = size.z 107 | } 108 | else { 109 | var width = size.z 110 | var height = size.y 111 | } 112 | } 113 | if (size.y === 0) { 114 | if (spans.x0 > spans.x1) { 115 | var width = size.x 116 | var height = size.z 117 | } 118 | else { 119 | var width = size.z 120 | var height = size.x 121 | } 122 | } 123 | if (size.z === 0) { 124 | if (spans.x0 > spans.x1) { 125 | var width = size.x 126 | var height = size.y 127 | } 128 | else { 129 | var width = size.y 130 | var height = size.x 131 | } 132 | } 133 | if ((size.z === 0 && spans.x0 < spans.x1) || (size.x === 0 && spans.y0 > spans.y1)) { 134 | return [ 135 | new this.THREE.Vector2(height, 0), 136 | new this.THREE.Vector2(0, 0), 137 | new this.THREE.Vector2(0, width), 138 | new this.THREE.Vector2(height, width) 139 | ] 140 | } else { 141 | return [ 142 | new this.THREE.Vector2(0, 0), 143 | new this.THREE.Vector2(0, height), 144 | new this.THREE.Vector2(width, height), 145 | new this.THREE.Vector2(width, 0) 146 | ] 147 | } 148 | } 149 | ; 150 | --------------------------------------------------------------------------------