Last active
December 11, 2024 02:42
-
-
Save partybusiness/447a23ee188235b6a0a016293519ed04 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#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