|  |  |  | const Faces = preload("./Faces.gd"); | 
					
						
							|  |  |  | const vox_to_godot = Basis(Vector3.RIGHT, Vector3.FORWARD, Vector3.UP); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func generate(vox, voxel_data, scale, snaptoground): | 
					
						
							|  |  |  |     var generator = VoxelMeshGenerator.new(vox, voxel_data, scale, snaptoground); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return generator.generate_mesh(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MeshGenerator: | 
					
						
							|  |  |  |     var surfaces = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     func ensure_surface_exists(surface_index: int, color: Color, material: Material): | 
					
						
							|  |  |  |         if (surfaces.has(surface_index)): return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var st = SurfaceTool.new(); | 
					
						
							|  |  |  |         st.begin(Mesh.PRIMITIVE_TRIANGLES); | 
					
						
							|  |  |  |         st.set_color(color); | 
					
						
							|  |  |  |         st.set_material(material); | 
					
						
							|  |  |  |         surfaces[surface_index] = st; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     func add_vertex(surface_index: int, vertex: Vector3): | 
					
						
							|  |  |  |         var st = surfaces[surface_index] as SurfaceTool; | 
					
						
							|  |  |  |         st.add_vertex(vertex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     func combine_surfaces(): | 
					
						
							|  |  |  |         var mesh = null; | 
					
						
							|  |  |  |         for surface_index in surfaces: | 
					
						
							|  |  |  |             var surface = surfaces[surface_index] as SurfaceTool; | 
					
						
							|  |  |  |             surface.index(); | 
					
						
							|  |  |  |             surface.generate_normals(); | 
					
						
							|  |  |  |             mesh = surface.commit(mesh); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var new_surface_index = mesh.get_surface_count() - 1; | 
					
						
							|  |  |  |             var name = str(surface_index); | 
					
						
							|  |  |  |             mesh.surface_set_name(new_surface_index, name); | 
					
						
							|  |  |  |         return mesh; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VoxelMeshGenerator: | 
					
						
							|  |  |  |     var vox; | 
					
						
							|  |  |  |     var voxel_data = {}; | 
					
						
							|  |  |  |     var scale:float; | 
					
						
							|  |  |  |     var snaptoground:bool; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     func _init(vox,voxel_data,scale,snaptoground): | 
					
						
							|  |  |  |         self.vox = vox; | 
					
						
							|  |  |  |         self.voxel_data = voxel_data; | 
					
						
							|  |  |  |         self.scale = scale; | 
					
						
							|  |  |  |         self.snaptoground = snaptoground; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     func get_material(voxel): | 
					
						
							|  |  |  |         var surface_index = voxel_data[voxel]; | 
					
						
							|  |  |  |         return vox.materials[surface_index] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     func face_is_visible(voxel, face): | 
					
						
							|  |  |  |         if (not voxel_data.has(voxel + face)): | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         var local_material = get_material(voxel); | 
					
						
							|  |  |  |         var adj_material = get_material(voxel + face); | 
					
						
							|  |  |  |         return adj_material.is_glass() && !local_material.is_glass(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     func generate_mesh(): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Minimum extends of the volume | 
					
						
							|  |  |  |         var mins :Vector3 = Vector3(1000000, 1000000, 1000000) | 
					
						
							|  |  |  |         # Maximum extends of the volume | 
					
						
							|  |  |  |         var maxs :Vector3 = Vector3(-1000000,-1000000,-1000000)     | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Find bounds | 
					
						
							|  |  |  |         for v in voxel_data: | 
					
						
							|  |  |  |             mins.x = min(mins.x, v.x) | 
					
						
							|  |  |  |             mins.y = min(mins.y, v.y) | 
					
						
							|  |  |  |             mins.z = min(mins.z, v.z) | 
					
						
							|  |  |  |             maxs.x = max(maxs.x, v.x) | 
					
						
							|  |  |  |             maxs.y = max(maxs.y, v.y) | 
					
						
							|  |  |  |             maxs.z = max(maxs.z, v.z)     | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var vox_to_godot = Basis(Vector3.RIGHT, Vector3.FORWARD, Vector3.UP); | 
					
						
							|  |  |  |         var yoffset = Vector3(0,0,0); | 
					
						
							|  |  |  |         if snaptoground : yoffset = Vector3(0, -mins.z * scale, 0); | 
					
						
							|  |  |  |         var gen = MeshGenerator.new(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for voxel in voxel_data: | 
					
						
							|  |  |  |             var voxelSides = [] | 
					
						
							|  |  |  |             if face_is_visible(voxel, Vector3.UP): voxelSides += Faces.Top | 
					
						
							|  |  |  |             if face_is_visible(voxel, Vector3.DOWN): voxelSides += Faces.Bottom | 
					
						
							|  |  |  |             if face_is_visible(voxel, Vector3.LEFT): voxelSides += Faces.Left | 
					
						
							|  |  |  |             if face_is_visible(voxel, Vector3.RIGHT): voxelSides += Faces.Right | 
					
						
							|  |  |  |             if face_is_visible(voxel, Vector3.BACK): voxelSides += Faces.Front | 
					
						
							|  |  |  |             if face_is_visible(voxel, Vector3.FORWARD): voxelSides += Faces.Back | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var surface_index = voxel_data[voxel]; | 
					
						
							|  |  |  |             var color = vox.colors[surface_index]; | 
					
						
							|  |  |  |             var material = vox.materials[surface_index].get_material(color); | 
					
						
							|  |  |  |             gen.ensure_surface_exists(surface_index, color, material); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for t in voxelSides: | 
					
						
							|  |  |  |                 gen.add_vertex(surface_index, yoffset + vox_to_godot * (t + voxel) * scale); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return gen.combine_surfaces(); |