Skip to content

Instantly share code, notes, and snippets.

@partybusiness
Last active December 11, 2024 02:42
Show Gist options
  • Save partybusiness/447a23ee188235b6a0a016293519ed04 to your computer and use it in GitHub Desktop.
Save partybusiness/447a23ee188235b6a0a016293519ed04 to your computer and use it in GitHub Desktop.
#Based on Procedural Toolkit by Syomus (https://github.com/Syomus/ProceduralToolkit)
@tool
extends PrimitiveMesh
class_name DiamondMesh
enum CutType {
Octahedral,
Table,
OldMine,
OldEuropean,
Brilliant
}
@export var cut:CutType = CutType.Table:
get:
return cut
set(p_value):
cut = p_value
request_update()
@export var radius : float = 1.0 :
get:
return radius
set(p_value):
radius = p_value
request_update()
# radius scaled down so the percentage math is quicker
var rad : float :
get:
return radius / 100.0
# size of parts of a diamond as percentage of radius
@export var table : float = 60.0 :
get:
return table
set(p_value):
table = p_value
request_update()
@export var crown : float = 32.0 :
get:
return crown
set(p_value):
crown = p_value
request_update()
@export var girdle : float = 2.0 :
get:
return girdle
set(p_value):
girdle = p_value
request_update()
@export var pavilion : float = 43.0 :
get:
return pavilion
set(p_value):
pavilion = p_value
request_update()
@export var culet : float = 2.0 :
get:
return culet
set(p_value):
culet = p_value
request_update()
func add_triangle_vertices(p_vert_array : PackedVector3Array, p_v0 : Vector3, p_v1 : Vector3, p_v2 : Vector3) -> void:
p_vert_array.push_back(p_v0)
p_vert_array.push_back(p_v1)
p_vert_array.push_back(p_v2)
func add_triangle_normals(p_normal_array : PackedVector3Array, p_v0 : Vector3, p_v1 : Vector3, p_v2 : Vector3) -> void:
var normal := (p_v2 - p_v0).cross(p_v1 - p_v0).normalized()
p_normal_array.push_back(normal)
p_normal_array.push_back(normal)
p_normal_array.push_back(normal)
func add_triangle_uv(p_vert_array : PackedVector2Array, p_uv0 : Vector2, p_uv1 : Vector2, p_uv2 : Vector2) -> void:
p_vert_array.push_back(p_uv0)
p_vert_array.push_back(p_uv1)
p_vert_array.push_back(p_uv2)
func add_triangle_vertices_plus_normals(p_vert_array : PackedVector3Array, p_normal_array : PackedVector3Array, p_v0 : Vector3, p_v1 : Vector3, p_v2 : Vector3) -> void:
add_triangle_vertices(p_vert_array, p_v0, p_v1, p_v2)
add_triangle_normals(p_normal_array, p_v0, p_v1, p_v2)
func add_table(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * PI * 2.0
var offset : float = 0.5 / 8.0 * PI * 2.0
var y:float = (crown + girdle) * 2.0
var centre:Vector3 = Vector3(0, y, 0) * rad
var clockwise:Vector3 = Vector3(cos(angle + offset) * table, y, sin(angle + offset) * table) * rad
var counter:Vector3 = Vector3(cos(angle - offset) * table, y, sin(angle - offset) * table) * rad
add_triangle_vertices(verts, centre, counter, clockwise)
normals.push_back(Vector3.UP)
normals.push_back(Vector3.UP)
normals.push_back(Vector3.UP)
var uv0 := Vector2(float(strip_index) / 16.0, 0.5 + girdle * 0.01)
var uv1 := Vector2(float(strip_index + 1) / 16.0, 0.5 + girdle * 0.01)
var uv2 := Vector2(float(strip_index) / 16.0, 0.5)
var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5)
add_triangle_uv(uvs, uv0, uv1, uv2)
func add_crown(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * PI * 2.0
var offset : float = 0.5 / 8.0 * PI * 2.0
var table_y : float = (crown + girdle) * 2.0
var ratio : float = 0.8 # TODO find right ratio for this
var table_clockwise:Vector3 = Vector3(cos(angle + offset) * table, table_y, sin(angle + offset) * table) * rad
var table_counter:Vector3 = Vector3(cos(angle - offset) * table, table_y, sin(angle - offset) * table) * rad
var outer_counter:Vector3 = Vector3(cos(angle) * 100.0, girdle, sin(angle) * 100.0) * rad
var outer_centre:Vector3 = Vector3(cos(angle + offset) * 100.0, girdle, sin(angle + offset) * 100.0) * rad
var outer_clockwise:Vector3 = Vector3(cos(angle + offset * 2.0) * 100.0, girdle, sin(angle + offset * 2.0) * 100.0) * rad
var midlevel:Vector3 = (outer_centre + table_clockwise) / 2.0
var mid_y:float = midlevel.y;
var mid_radius:float = Vector2(midlevel.x, midlevel.z).length();
var mid_r:float = mid_radius / cos(offset);
var mid_counter:Vector3 = Vector3(cos(angle) * mid_r, mid_y, sin(angle) * mid_r)
var mid_clockwise:Vector3 = Vector3(cos(angle + offset * 2.0) * mid_r, mid_y, sin(angle + offset * 2.0) * mid_r)
add_triangle_vertices_plus_normals(verts, normals, table_counter, mid_counter, table_clockwise)
add_triangle_vertices_plus_normals(verts, normals, mid_counter, outer_counter, outer_centre)
add_triangle_vertices_plus_normals(verts, normals, mid_clockwise, outer_centre, outer_clockwise)
add_triangle_vertices_plus_normals(verts, normals, table_clockwise, mid_counter, outer_centre)
add_triangle_vertices_plus_normals(verts, normals, mid_clockwise, table_clockwise, outer_centre)
var uv0 := Vector2(float(strip_index) / 16.0, 0.5 + girdle * 0.01)
var uv1 := Vector2(float(strip_index + 1) / 16.0, 0.5 + girdle * 0.01)
var uv2 := Vector2(float(strip_index) / 16.0, 0.5)
var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
func add_girdle(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array):
for strip_index in range(0, 16):
var angle : float = float(strip_index) / 16.0 * PI * 2.0
var angle_offset : float = float(strip_index + 1) / 16.0 * PI * 2.0
var vertex0:Vector3 = Vector3(cos(angle), girdle/50.0, sin(angle)) * radius
var vertex1:Vector3 = Vector3(cos(angle_offset), girdle/50.0, sin(angle_offset)) * radius
var vertex2:Vector3 = Vector3(cos(angle), 0, sin(angle)) * radius
var vertex3:Vector3 = Vector3(cos(angle_offset), 0, sin(angle_offset)) * radius
add_triangle_vertices(verts, vertex0, vertex2, vertex1)
add_triangle_vertices(verts, vertex2, vertex3, vertex1)
#var bottom_slope:Vector2 = Vector2(radius - culet * rad, pavilion * rad).normalized()
#var top_slope:Vector2 = Vector2(radius - table * rad, crown * rad).normalized()
var normal0:Vector3 = vertex2.normalized()
#normal0 = Vector3(normal0.x * top_slope.x, -top_slope.y, normal0.z * top_slope.x)
var normal1:Vector3 = vertex3.normalized()
#normal1 = Vector3(normal1.x * top_slope.x, -top_slope.y, normal1.z * top_slope.x)
var normal2:Vector3 = vertex2.normalized()
#normal2 = Vector3(normal2.x * bottom_slope.x, bottom_slope.y, normal2.z * bottom_slope.x)
var normal3:Vector3 = vertex3.normalized()
#normal3 = Vector3(normal3.x * bottom_slope.x, bottom_slope.y, normal3.z * bottom_slope.x)
# girdle is one area we want curved normals
normals.push_back(normal0)
normals.push_back(normal2)
normals.push_back(normal1)
normals.push_back(normal2)
normals.push_back(normal3)
normals.push_back(normal1)
var uv0 := Vector2(float(strip_index) / 16.0, 0.5 + girdle * 0.02)
var uv1 := Vector2(float(strip_index + 1) / 16.0, 0.5 + girdle * 0.02)
var uv2 := Vector2(float(strip_index) / 16.0, 0.5)
var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
func add_pavilion(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * PI * 2.0
var offset : float = 0.5 / 8.0 * PI * 2.0
var culet_y:float = -pavilion * 2.0
var ratio:float = 0.4 # TODO find actual desired ratio for this
var centre_top:Vector3 = Vector3(cos(angle) * 100.0, 0, sin(angle) * 100.0) * rad
var clockwise_top:Vector3 = Vector3(cos(angle + offset) * 100.0, 0, sin(angle + offset) * 100.0) * rad
var counter_top:Vector3 = Vector3(cos(angle - offset) * 100.0, 0, sin(angle - offset) * 100.0) * rad
var clockwise_culet:Vector3 = Vector3(cos(angle + offset) * culet, culet_y, sin(angle + offset) * culet) * rad
var counter_culet:Vector3 = Vector3(cos(angle - offset) * culet, culet_y, sin(angle - offset) * culet) * rad
var middle_culet:Vector3 = (clockwise_culet + counter_culet) / 2.0
var midlevel:Vector3 = lerp(centre_top, middle_culet, ratio)
var mid_direction:Vector3 = Vector3(sin(angle), 0, cos(angle));
var mid_radius:float = Vector2(midlevel.x, midlevel.z).length();
# calculate midlevel positions that are flat with midlevel plane
var mid_y:float = midlevel.y;
var mid_r:float = mid_radius / cos(offset);
var clockwise_midlevel:Vector3 = Vector3(cos(angle + offset) * mid_r, mid_y, sin(angle + offset) * mid_r)
var counter_midlevel:Vector3 = Vector3(cos(angle - offset) * mid_r, mid_y, sin(angle - offset) * mid_r)
add_triangle_vertices_plus_normals(verts, normals, centre_top, clockwise_midlevel, clockwise_top)
add_triangle_vertices_plus_normals(verts, normals, centre_top, counter_top, counter_midlevel)
add_triangle_vertices_plus_normals(verts, normals, centre_top, middle_culet, clockwise_midlevel)
add_triangle_vertices_plus_normals(verts, normals, centre_top, counter_midlevel, middle_culet)
add_triangle_vertices_plus_normals(verts, normals, clockwise_midlevel, middle_culet, clockwise_culet)
add_triangle_vertices_plus_normals(verts, normals, counter_midlevel, counter_culet, middle_culet)
var uv0 := Vector2(float(strip_index) / 16.0, 0.5 + girdle * 0.01)
var uv1 := Vector2(float(strip_index + 1) / 16.0, 0.5 + girdle * 0.01)
var uv2 := Vector2(float(strip_index) / 16.0, 0.5)
var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
add_triangle_uv(uvs, uv0, uv1, uv2)
func add_culet(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * PI * 2.0
var offset : float = 0.5 / 8.0 * PI * 2.0
var y:float = -pavilion*2.0
var centre:Vector3 = Vector3(0, y, 0) * rad
var clockwise:Vector3 = Vector3(cos(angle + offset) * culet, y, sin(angle + offset) * culet) * rad
var counter:Vector3 = Vector3(cos(angle - offset) * culet, y, sin(angle - offset) * culet) * rad
add_triangle_vertices(verts, centre, clockwise, counter)
normals.push_back(Vector3.DOWN)
normals.push_back(Vector3.DOWN)
normals.push_back(Vector3.DOWN)
var uv0 := Vector2(float(strip_index) / 16.0, 0.5 + girdle * 0.01)
var uv1 := Vector2(float(strip_index + 1) / 16.0, 0.5 + girdle * 0.01)
var uv2 := Vector2(float(strip_index) / 16.0, 0.5)
var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5)
add_triangle_uv(uvs, uv0, uv1, uv2)
func add_table_top(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array):
var y:float = (crown) * 2.0
# Table cut table
var v0:Vector3 = Vector3(-table, y, -table) * rad
var v1:Vector3 = Vector3(-table, y, table) * rad
var v2:Vector3 = Vector3(table, y, -table) * rad
var v3:Vector3 = Vector3(table, y, table) * rad
add_triangle_vertices(verts, v0, v2, v1)
add_triangle_vertices(verts, v2, v3, v1)
normals.push_back(Vector3.UP)
normals.push_back(Vector3.UP)
normals.push_back(Vector3.UP)
normals.push_back(Vector3.UP)
normals.push_back(Vector3.UP)
normals.push_back(Vector3.UP)
var ratio:float = table / 200.0
var uv0 := Vector2(0.5 - ratio, 0.5 - ratio)
var uv1 := Vector2(0.5 - ratio, 0.5 + ratio)
var uv2 := Vector2(0.5 + ratio, 0.5 - ratio)
var uv3 := Vector2(0.5 + ratio, 0.5 + ratio)
add_triangle_uv(uvs, uv0, uv2, uv1)
add_triangle_uv(uvs, uv2, uv3, uv1)
# Table cut crown
var v4:Vector3 = Vector3(-100, 0, -100) * rad
var v5:Vector3 = Vector3(-100, 0, 100) * rad
var v6:Vector3 = Vector3(100, 0, -100) * rad
var v7:Vector3 = Vector3(100, 0, 100) * rad
add_triangle_vertices_plus_normals(verts, normals, v0, v5, v4)
add_triangle_vertices_plus_normals(verts, normals, v0, v1, v5)
add_triangle_vertices_plus_normals(verts, normals, v1, v7, v5)
add_triangle_vertices_plus_normals(verts, normals, v1, v3, v7)
add_triangle_vertices_plus_normals(verts, normals, v3, v6, v7)
add_triangle_vertices_plus_normals(verts, normals, v3, v2, v6)
add_triangle_vertices_plus_normals(verts, normals, v2, v4, v6)
add_triangle_vertices_plus_normals(verts, normals, v2, v0, v4)
var uv4 := Vector2(0.0, 0.0)
var uv5 := Vector2(0.0, 1.0)
var uv6 := Vector2(1.0, 0.0)
var uv7 := Vector2(1.0, 1.0)
add_triangle_uv(uvs, uv0, uv5, uv4)
add_triangle_uv(uvs, uv0, uv1, uv5)
add_triangle_uv(uvs, uv1, uv7, uv5)
add_triangle_uv(uvs, uv1, uv3, uv7)
add_triangle_uv(uvs, uv3, uv6, uv7)
add_triangle_uv(uvs, uv3, uv2, uv6)
add_triangle_uv(uvs, uv2, uv4, uv6)
add_triangle_uv(uvs, uv2, uv0, uv4)
func add_table_pavilion(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array):
var v0:Vector3 = Vector3(-100, 0, -100) * rad
var v1:Vector3 = Vector3(-100, 0, 100) * rad
var v2:Vector3 = Vector3(100, 0, 100) * rad
var v3:Vector3 = Vector3(100, 0, -100) * rad
var tip:Vector3 = Vector3(0, -pavilion * 2.0, 0) * rad
add_triangle_vertices_plus_normals(verts, normals, tip, v0, v1)
add_triangle_vertices_plus_normals(verts, normals, tip, v1, v2)
add_triangle_vertices_plus_normals(verts, normals, tip, v2, v3)
add_triangle_vertices_plus_normals(verts, normals, tip, v3, v0)
var uv0 := Vector2(0.0, 0.0)
var uv1 := Vector2(0.0, 1.0)
var uv2 := Vector2(1.0, 1.0)
var uv3 := Vector2(1.0, 0.0)
var uvtip := Vector2(0.5, 0.5)
add_triangle_uv(uvs, uvtip, uv0, uv1)
add_triangle_uv(uvs, uvtip, uv1, uv2)
add_triangle_uv(uvs, uvtip, uv2, uv3)
add_triangle_uv(uvs, uvtip, uv3, uv0)
func _create_mesh_array() -> Array:
const tetra_angle : float = -19.471220333
var verts := PackedVector3Array()
var uvs := PackedVector2Array()
var normals := PackedVector3Array()
match cut:
CutType.Table:
add_table_top(verts, normals, uvs)
add_table_pavilion(verts, normals, uvs)
_: # default
add_table(verts, normals, uvs)
add_crown(verts, normals, uvs)
add_girdle(verts, normals, uvs)
add_pavilion(verts, normals, uvs)
add_culet(verts, normals, uvs)
var arrays = []
arrays.resize(Mesh.ARRAY_MAX)
arrays[Mesh.ARRAY_VERTEX] = verts
arrays[Mesh.ARRAY_TEX_UV] = uvs
arrays[Mesh.ARRAY_NORMAL] = normals
#arrays[Mesh.ARRAY_TEX_UV2] = uvs
return arrays
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment