├── .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 |
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 |
--------------------------------------------------------------------------------