You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			100 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			GDScript
		
	
			
		
		
	
	
			100 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			GDScript
		
	
| 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();
 |