Last active
June 17, 2024 15:07
-
-
Save partybusiness/f624749bebdcf9892367afbf9e0a60c0 to your computer and use it in GitHub Desktop.
generates a mesh in a figure-eight shape and saves it as a resource
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
shader_type spatial; | |
render_mode cull_disabled, unshaded, depth_draw_opaque; | |
//just something I used to diaply the figure eight | |
uniform sampler2D tex:source_color; | |
uniform float spin_speed = 1.0; | |
void vertex() { | |
UV.y = UV.y + TIME * spin_speed; | |
} | |
void fragment() { | |
vec4 col = texture(tex,UV); | |
float modof = 0.0; | |
if (FRONT_FACING){ | |
ALBEDO = col.rgb*col.a; | |
modof = 1.0; | |
} else | |
ALBEDO = col.brg*col.a; | |
ALPHA = col.a * floor(mod (floor(SCREEN_UV.x*VIEWPORT_SIZE.x)+floor(SCREEN_UV.y*VIEWPORT_SIZE.y) + modof, 2.0)); | |
ALPHA_SCISSOR_THRESHOLD = 0.5; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@tool | |
extends EditorScript | |
#Godot editorscript that generates a mesh and saves it to a resource file | |
# this one is a figure eight but the same idea could be used for other shapes. | |
#name of MeshInstance3D in current scene that will display generated mesh | |
var display_mesh_name:String = "meshDisplay" | |
#file path of mesh resource you want to save | |
var file_path:String = "res://figure_eight.res" | |
func _run(): | |
var surface = SurfaceTool.new() | |
surface.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP) | |
#generate figure eight | |
for i in range(0,32+1): | |
var rad = i/16.0 * PI * 2.0 | |
var spacing = 1.0 | |
var circle1 = Vector2(cos(rad) + spacing,sin(rad)) | |
var circle2 = Vector2(cos(-rad-PI) - spacing,sin(-rad-PI)) | |
var circle = circle1; | |
if (rad>PI && rad<PI*3.0): | |
circle = circle2; | |
var height = sin(rad/2.0 + PI)*0.5 | |
surface.set_uv(Vector2(0,i*0.25)) | |
surface.add_vertex(Vector3(circle.x,-0.5+height,circle.y)) | |
surface.set_uv(Vector2(1,i*0.25)) | |
surface.add_vertex(Vector3(circle.x,0.5+height,circle.y)) | |
var mesh = surface.commit() #generate the mesh | |
var currentScene = get_scene() | |
var mesh_instance:MeshInstance3D = currentScene.find_child(display_mesh_name, true) | |
mesh_instance.mesh = mesh #assign to MeshInstance3D in scene | |
ResourceSaver.save( mesh, file_path ) #save it to a file |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@tool | |
extends EditorScript | |
#generates series of meshes and assigns them to a MeshLibrary for use in a GridMap | |
#at the moment this makes ground planes with each corner at one of two heights | |
#name of MeshInstance3D in current scene that will display generated mesh | |
var display_mesh_name:String = "meshDisplay" | |
var grid_name:String = "GridMap" | |
var xx = 32 #number of vertices in each direction | |
var yy = 32 # | |
var width:float = 1.0 #metres in each direction | |
var depth:float = 1.0 | |
var height:float = 0.5 | |
var grid_material:Material | |
#file path of mesh resource you want to save | |
var file_path:String = "res://waves/wave_%d_%d_%d_%d.res" | |
var material_name:String = "res://waves/wave_material.res" | |
func get_h(u:float,v:float, c00:int, c01:int, c10:int, c11:int)-> float: | |
var sv = sin(v*PI - PI/2.0)*0.5+0.5 | |
var su = sin(u*PI - PI/2.0)*0.5+0.5 | |
var xh0 = lerp(c00,c01,sv) | |
var xh1 = lerp(c10,c11,sv) | |
var yh0 = lerp(c00,c10,su) | |
var yh1 = lerp(c01,c11,su) | |
var h = lerp(xh0,xh1, su) * height | |
return h | |
func generate_wave(c00:int, c01:int, c10:int, c11:int) -> Mesh: | |
var arr = [] | |
arr.resize(Mesh.ARRAY_MAX) | |
var verts:PackedVector3Array | |
var uvs:PackedVector2Array | |
var normals:PackedVector3Array | |
var indices:PackedInt32Array | |
var radius = 2.0 | |
#make vertices | |
for x in range(0, xx+1): #one extra so UVs wrap seamlessly | |
for y in range (0, yy+1): | |
var u = x/float(xx) | |
var v = y/float(yy) | |
var h = get_h(u,v,c00,c01,c10,c11) | |
#calculates u delta height and v delta height and creates tangents from those | |
var udh = get_h(u+0.1/float(xx),v,c00,c01,c10,c11) - get_h(u-0.1/float(xx),v,c00,c01,c10,c11) | |
var vdh = get_h(u,v+0.1/float(yy),c00,c01,c10,c11) - get_h(u,v-0.1/float(yy),c00,c01,c10,c11) | |
var udvec = Vector3(0.1/float(xx),udh,0).normalized() | |
var vdvec = Vector3(0,vdh,0.1/float(yy)).normalized() | |
uvs.append(Vector2(u,v)) | |
verts.append(Vector3(lerp(-width,width, u),h,lerp(-depth,depth, v))) | |
#uses cross-product of two tangents to set normal | |
normals.append(-(udvec.cross(vdvec)).normalized()) | |
#assign indices | |
for x in range(0, xx): | |
for y in range (0, yy): | |
var i = x * (yy+1) + y | |
var n = (i + yy + 1) | |
indices.append_array([n,i+1,i]) | |
indices.append_array([n+1,i+1,n]) | |
arr[Mesh.ARRAY_VERTEX] = verts | |
arr[Mesh.ARRAY_TEX_UV] = uvs | |
arr[Mesh.ARRAY_NORMAL] = normals | |
arr[Mesh.ARRAY_INDEX] = indices | |
var mesh:ArrayMesh = ArrayMesh.new() | |
# Create mesh surface from mesh array. | |
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) | |
mesh.regen_normal_maps() #if you don't want to customize normals this is eaasiest | |
var currentScene = get_scene() | |
var mesh_instance:MeshInstance3D = currentScene.find_child(display_mesh_name, true) | |
mesh_instance.mesh = mesh | |
mesh.surface_set_material(0, grid_material) | |
ResourceSaver.save( mesh, file_path%[c00,c01,c10,c11] ) | |
return mesh | |
func _run(): | |
var currentScene = get_scene() | |
var grid_map:GridMap = currentScene.find_child(grid_name, true) | |
grid_map.visible = false #prevents errors from trying to render | |
grid_map.mesh_library = MeshLibrary.new() | |
var lib:MeshLibrary = grid_map.mesh_library | |
grid_material = ShaderMaterial.new() | |
ResourceSaver.save (grid_material, material_name) | |
var meshes:Array[Mesh] | |
for a in range(0,2): | |
for b in range(0,2): | |
for c in range(0,2): | |
for d in range(0,2): | |
var new_mesh = generate_wave(a,b,c,d) | |
meshes.append(new_mesh) | |
var id = lib.get_last_unused_item_id() | |
lib.create_item(id) | |
lib.set_item_mesh(id, new_mesh) | |
#These are for adding colliders | |
lib.set_item_shapes(id,[new_mesh.create_trimesh_shape()]) | |
lib.set_item_mesh_transform(id, Transform3D.IDENTITY) | |
lib.set_item_name(id, "wave_%d_%d_%d_%d.res"%[a,b,c,d]) | |
grid_map.visible = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@tool | |
extends EditorScript | |
#alternate version of generating a mesh that assigns values to arrays rather than call the SurfaceTool functions | |
#name of MeshInstance3D in current scene that will display generated mesh | |
var display_mesh_name:String = "meshDisplay" | |
#file path of mesh resource you want to save | |
var file_path:String = "res://loop.res" | |
func _run(): | |
var arr = [] | |
arr.resize(Mesh.ARRAY_MAX) | |
var verts:PackedVector3Array | |
var uvs:PackedVector2Array | |
var normals:PackedVector3Array | |
var indices:PackedInt32Array | |
var h = 16 #height of loop in number of vertices | |
var w = 32 #segments of loop as number of vertices | |
var radius = 2.0 | |
#make vertices | |
for x in range(0, w+1): #one extra so UVs wrap seamlessly | |
for y in range (0, h): | |
var u = y/float(h) | |
var v = x/float(w) * 5.0 | |
var rad = x/float(w) * 2.0 * PI | |
var radius_ult = lerp(radius + sin(u*PI), radius, u) | |
uvs.append(Vector2(u,v)) | |
verts.append(Vector3(sin(rad)*radius_ult,u,cos(rad)*radius_ult)) | |
normals.append(Vector3(sin(rad),u-0.5,cos(rad)).normalized()) | |
#assign indices | |
for x in range(0, w): | |
for y in range (0, h-1): | |
var i = x * h + y | |
var n = (i + h) | |
indices.append_array([i,i+1,n]) | |
indices.append_array([i+1,n+1,n]) | |
arr[Mesh.ARRAY_VERTEX] = verts | |
arr[Mesh.ARRAY_TEX_UV] = uvs | |
arr[Mesh.ARRAY_NORMAL] = normals | |
arr[Mesh.ARRAY_INDEX] = indices | |
var mesh:ArrayMesh = ArrayMesh.new() | |
# Create mesh surface from mesh array. | |
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) | |
var currentScene = get_scene() | |
var mesh_instance:MeshInstance3D = currentScene.find_child(display_mesh_name, true) | |
mesh_instance.mesh = mesh #this works fine | |
ResourceSaver.save( mesh, file_path ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment