Skip to content

Instantly share code, notes, and snippets.

@partybusiness
Last active October 19, 2025 20:40
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 {
Point,
Table,
OldMine,
OldEuropean,
Brilliant,
Victorian,
Carre,
French,
Rose,
}
@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()
@export var adjuster : float = 0.0 :
get:
return adjuster
set(p_value):
adjuster = 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 calc_plane(p_v0 : Vector3, p_v1 : Vector3, p_v2 : Vector3) -> Plane:
return Plane(calc_normal(p_v0, p_v1, p_v2), p_v0)
func calc_normal(p_v0 : Vector3, p_v1 : Vector3, p_v2 : Vector3) -> Vector3:
var normal := (p_v2 - p_v0).cross(p_v1 - p_v0).normalized()
return normal
func add_triangle_normals(p_normal_array : PackedVector3Array, p_v0 : Vector3, p_v1 : Vector3, p_v2 : Vector3) -> void:
var normal := calc_normal(p_v0, p_v1, p_v2)
p_normal_array.push_back(normal)
p_normal_array.push_back(normal)
p_normal_array.push_back(normal)
func add_triangle_uv(p_uv_array : PackedVector2Array, p_uv0 : Vector2, p_uv1 : Vector2, p_uv2 : Vector2) -> void:
p_uv_array.push_back(p_uv0)
p_uv_array.push_back(p_uv1)
p_uv_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 calculate_triangle_tangents_counter(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array, count:int) -> void:
for index in count:
var offset := count * 3 - index * 3
calculate_triangle_tangents(verts, normals, uvs, tangents, offset)
func calculate_triangle_tangents(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array, offset:int = 3) -> void:
var indices: Array[int] = [0, 0, 0]
indices[0] = verts.size() - offset
indices[1] = verts.size() - offset + 1
indices[2] = verts.size() - offset + 2
var average_tangent:Vector4 = Vector4.ZERO
var count:int = 0
for i in 3:
var index = indices[i]
var j = indices[(i + 1) % 3]
var k = indices[(i + 2) % 3]
#print(index)
var n:Vector3 = normals[index]
# get differences between points
var v1:Vector3 = verts[j] - verts[index]
var v2:Vector3 = verts[k] - verts[index]
var t1:Vector2 = uvs[j] - uvs[index]
var t2:Vector2 = uvs[k] - uvs[index]
# Is the texture flipped?
var uv2xArea:float = t1.x * t2.y - t1.y * t2.x;
if (abs(uv2xArea) < 0.00001):
continue; # too small, skip it
var flip:float = 1.0
if uv2xArea > 0.0:
flip = 1.0
else:
flip = -1.0
# flatten along plane defined by normal
v1 -= n * v1.dot(n)
v2 -= n * v2.dot(n)
# get direction of movement
var s:Vector3 = (t2.y * v1 - t1.y * v2).normalized() * flip;
# Use angle between two vectors as weight
var angle:float = acos(v1.dot(v2) / (v1.length() * v2.length()));
var new_tangent:Vector3 = s * angle
count += 1
average_tangent += Vector4(new_tangent.x, new_tangent.y, new_tangent.z, flip)
var norm_tangent := Vector3(new_tangent.x, new_tangent.y, new_tangent.z).normalized()
tangents.push_back(new_tangent.x)
tangents.push_back(new_tangent.y)
tangents.push_back(new_tangent.z)
tangents.push_back(flip) # TODO decide if binormal needs to be flipped
average_tangent /= float(count)
var norm_tangent := Vector3(average_tangent.x, average_tangent.y, average_tangent.z).normalized()
for i in 3:
continue
tangents.push_back(norm_tangent.x)
tangents.push_back(norm_tangent.y)
tangents.push_back(norm_tangent.z)
tangents.push_back(average_tangent.w)
#################### OLD EUROPEAN ######################################
func add_table(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * TAU
var offset : float = 0.5 / 8.0 * TAU
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, 5.5)
var uv0 := Vector2(0.5, 0.5)
var uv1 := Vector2(cos(angle + offset) * 0.5 + 0.5, sin(angle + offset) * 0.5 + 0.5)
var uv2 := Vector2(cos(angle - offset) * 0.5 + 0.5, sin(angle - offset) * 0.5 + 0.5)
#var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5)
add_triangle_uv(uvs, uv0, uv2, uv1)
calculate_triangle_tangents(verts, normals, uvs, tangents)
func add_crown(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * TAU
var offset : float = 0.5 / 8.0 * TAU
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
# connects table, mid to outer
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)
#
var uv_theight:float = 1.0 / 16.0 * (outer_centre - mid_counter).length() / (mid_counter - mid_clockwise).length()
var scale_mult:float = 8.0
var tcount_uv := Vector2(float(strip_index + 0.5) / 16.0, 0.5) * scale_mult
var tclock_uv := Vector2(float(strip_index - 0.5) / 16.0, 0.5) * scale_mult
var mcount_uv := Vector2(float(strip_index) / 16.0, 0.5 + uv_theight) * scale_mult
var mclock_uv := Vector2(float(strip_index - 1.0) / 16.0, 0.5 + uv_theight) * scale_mult
var ocount_uv := Vector2(float(strip_index + 0.5) / 16.0, 0.5 + uv_theight * 2.0) * scale_mult
var ocent_uv := Vector2(float(strip_index) / 16.0, 0.5 + uv_theight * 2.0) * scale_mult
var oclock_uv := Vector2(float(strip_index - 0.5) / 16.0, 0.5 + uv_theight * 2.0) * scale_mult
add_triangle_uv(uvs, tcount_uv, mcount_uv, tclock_uv) #(table_counter, mid_counter, table_clockwise)
add_triangle_uv(uvs, mcount_uv, ocount_uv, ocent_uv) #(mid_counter, outer_counter, outer_centre)
add_triangle_uv(uvs, mclock_uv, ocent_uv, oclock_uv) #(mid_clockwise, outer_centre, outer_clockwise)
add_triangle_uv(uvs, tclock_uv, mcount_uv, ocent_uv) #(table_clockwise, mid_counter, outer_centre)
add_triangle_uv(uvs, mclock_uv, tclock_uv, ocent_uv) #(mid_clockwise, table_clockwise, outer_centre)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 5)
func add_girdle(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 16):
var angle : float = float(strip_index) / 16.0 * TAU
var angle_offset : float = float(strip_index + 1) / 16.0 * TAU
var vertex0:Vector3 = Vector3(cos(angle), girdle * 0.01, sin(angle)) * radius
var vertex1:Vector3 = Vector3(cos(angle_offset), girdle * 0.01, 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 uv_theight:float = 1.0 / 16.0 * (vertex0 - vertex2).length() / (vertex0 - vertex1).length()
var scale_mult:float = 8.0
var uv0 := Vector2(float(strip_index) / 16.0, 0.5 + uv_theight) * scale_mult
var uv1 := Vector2(float(strip_index + 1) / 16.0, 0.5 + uv_theight) * scale_mult
var uv2 := Vector2(float(strip_index) / 16.0, 0.5) * scale_mult
var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5) * scale_mult
add_triangle_uv(uvs, uv0, uv2, uv1)
add_triangle_uv(uvs, uv2, uv3, uv1)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 2)
func add_pavilion(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * TAU
var offset : float = 0.5 / 8.0 * TAU
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 top_height = 0.3
var culet_height = 0.5
var mid_offset := 0.5
var culet_offset := 0.1
var clocktop_uv := Vector2(float(strip_index - 1) / 8.0, 0.5 - top_height)
var centop_uv := Vector2(float(strip_index) / 8.0, 0.5 - top_height)
var counttop_uv := Vector2(float(strip_index + 1) / 8.0, 0.5 - top_height)
var clockmid_uv := Vector2(float(strip_index - mid_offset) / 8.0, 0.5)
var countmid_uv := Vector2(float(strip_index + mid_offset) / 8.0, 0.5)
var clockculet_uv := Vector2(float(strip_index - culet_offset) / 8.0, 0.5 + culet_height)
var cenculet_uv := Vector2(float(strip_index) / 8.0, 0.5 + culet_height)
var countculet_uv := Vector2(float(strip_index + culet_offset) / 8.0, 0.5 + culet_height)
add_triangle_uv(uvs, centop_uv, clockmid_uv, clocktop_uv) # centre_top, clockwise_midlevel, clockwise_top)
add_triangle_uv(uvs, centop_uv, counttop_uv, countmid_uv) # centre_top, counter_top, counter_midlevel)
add_triangle_uv(uvs, centop_uv, cenculet_uv, clockmid_uv) # centre_top, middle_culet, clockwise_midlevel)
add_triangle_uv(uvs, centop_uv, countmid_uv, cenculet_uv) # centre_top, counter_midlevel, middle_culet)
add_triangle_uv(uvs, clockmid_uv, cenculet_uv, clockculet_uv) # clockwise_midlevel, middle_culet, clockwise_culet)
add_triangle_uv(uvs, countmid_uv, countculet_uv, cenculet_uv) # counter_midlevel, counter_culet, middle_culet)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 6)
func add_culet(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * TAU
var offset : float = 0.5 / 8.0 * TAU
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 uv_scale:float = 1.0
var c_uv := Vector2(0.5, 0.5)
var clock_uv := Vector2(0.5 + clockwise.x * uv_scale, 0.5 + clockwise.z * uv_scale)
var count_uv := Vector2(0.5 + counter.x * uv_scale, 0.5 + counter.z * uv_scale)
add_triangle_uv(uvs, c_uv, clock_uv, count_uv)
calculate_triangle_tangents(verts, normals, uvs, tangents)
#################### OLD MINE ######################################
func add_mine_table(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * TAU
var offset : float = 0.5 / 8.0 * TAU
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, 5.5)
var uv0 := Vector2(0.5, 0.5)
var uv1 := Vector2(cos(angle + offset) * 0.5 + 0.5, sin(angle + offset) * 0.5 + 0.5)
var uv2 := Vector2(cos(angle - offset) * 0.5 + 0.5, sin(angle - offset) * 0.5 + 0.5)
#var uv3 := Vector2(float(strip_index + 1) / 16.0, 0.5)
add_triangle_uv(uvs, uv0, uv2, uv1)
calculate_triangle_tangents(verts, normals, uvs, tangents)
func add_mine_crown(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 8):
var angle : float = float(strip_index) / 8.0 * TAU
var offset : float = 0.5 / 8.0 * TAU
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
# connects table, mid to outer
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)
#
var uv_theight:float = 1.0 / 16.0 * (outer_centre - mid_counter).length() / (mid_counter - mid_clockwise).length()
var scale_mult:float = 8.0
var tcount_uv := Vector2(float(strip_index + 0.5) / 16.0, 0.5) * scale_mult
var tclock_uv := Vector2(float(strip_index - 0.5) / 16.0, 0.5) * scale_mult
var mcount_uv := Vector2(float(strip_index) / 16.0, 0.5 + uv_theight) * scale_mult
var mclock_uv := Vector2(float(strip_index - 1.0) / 16.0, 0.5 + uv_theight) * scale_mult
var ocount_uv := Vector2(float(strip_index + 0.5) / 16.0, 0.5 + uv_theight * 2.0) * scale_mult
var ocent_uv := Vector2(float(strip_index) / 16.0, 0.5 + uv_theight * 2.0) * scale_mult
var oclock_uv := Vector2(float(strip_index - 0.5) / 16.0, 0.5 + uv_theight * 2.0) * scale_mult
add_triangle_uv(uvs, tcount_uv, mcount_uv, tclock_uv) #(table_counter, mid_counter, table_clockwise)
add_triangle_uv(uvs, mcount_uv, ocount_uv, ocent_uv) #(mid_counter, outer_counter, outer_centre)
add_triangle_uv(uvs, mclock_uv, ocent_uv, oclock_uv) #(mid_clockwise, outer_centre, outer_clockwise)
add_triangle_uv(uvs, tclock_uv, mcount_uv, ocent_uv) #(table_clockwise, mid_counter, outer_centre)
add_triangle_uv(uvs, mclock_uv, tclock_uv, ocent_uv) #(mid_clockwise, table_clockwise, outer_centre)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 5)
func add_mine_girdle(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 4):
var angle : float = float(strip_index) / 4.0 * TAU
var yy:float = girdle
var offset:float = 39.0 / 360.0 * TAU
var b_offset:float = 22.0 / 360 * TAU
var a_top:Vector3 = Vector3(cos(angle) * 100.0, 0, sin(angle) * 100.0) * rad
var b_top:Vector3 = Vector3(cos(angle + b_offset) * 105.0, 0, sin(angle + b_offset) * 105.0) * rad
var c_top:Vector3 = Vector3(cos(angle + TAU / 8.0) * 119.0, 0, sin(angle + TAU / 8.0) * 119.0) * rad
var b_top2:Vector3 = Vector3(cos(angle - b_offset) * 105.0, 0, sin(angle - b_offset) * 105.0) * rad
var c_top2:Vector3 = Vector3(cos(angle - TAU / 8.0) * 119.0, 0, sin(angle - TAU / 8.0) * 119.0) * rad
var a_top_up:Vector3 = Vector3(cos(angle) * 100.0, yy, sin(angle) * 100.0) * rad
var b_top_up:Vector3 = Vector3(cos(angle + b_offset) * 105.0, yy, sin(angle + b_offset) * 105.0) * rad
var c_top_up:Vector3 = Vector3(cos(angle + TAU / 8.0) * 119.0, yy, sin(angle + TAU / 8.0) * 119.0) * rad
var b_top2_up:Vector3 = Vector3(cos(angle - b_offset) * 105.0, yy, sin(angle - b_offset) * 105.0) * rad
var c_top2_up:Vector3 = Vector3(cos(angle - TAU / 8.0) * 119.0, yy, sin(angle - TAU / 8.0) * 119.0) * rad
add_triangle_vertices_plus_normals(verts, normals, a_top, b_top, b_top_up)
add_triangle_vertices_plus_normals(verts, normals, a_top, b_top_up, a_top_up)
add_triangle_vertices_plus_normals(verts, normals, b_top, c_top, c_top_up)
add_triangle_vertices_plus_normals(verts, normals, b_top, c_top_up, b_top_up)
add_triangle_vertices_plus_normals(verts, normals, a_top, b_top2_up, b_top2)
add_triangle_vertices_plus_normals(verts, normals, a_top, a_top_up, b_top2_up)
add_triangle_vertices_plus_normals(verts, normals, b_top2, c_top2_up, c_top2)
add_triangle_vertices_plus_normals(verts, normals, b_top2, b_top2_up, c_top2_up)
var target_angle = atan2(a_top.x, a_top.z)
var a_top_uv:Vector2 = radial_uv(a_top, target_angle)
var b_top_uv:Vector2 = radial_uv(b_top, target_angle)
var c_top_uv:Vector2 = radial_uv(c_top, target_angle)
var b_top2_uv:Vector2 = radial_uv(b_top2, target_angle)
var c_top2_uv:Vector2 = radial_uv(c_top2, target_angle)
var a_top_up_uv:Vector2 = radial_uv(a_top_up, target_angle)
var b_top_up_uv:Vector2 = radial_uv(b_top_up, target_angle)
var c_top_up_uv:Vector2 = radial_uv(c_top_up, target_angle)
var b_top2_up_uv:Vector2 = radial_uv(b_top2_up, target_angle)
var c_top2_up_uv:Vector2 = radial_uv(c_top2_up, target_angle)
add_triangle_uv(uvs, a_top_uv, b_top_uv, b_top_up_uv)
add_triangle_uv(uvs, a_top_uv, b_top_up_uv, a_top_up_uv)
add_triangle_uv(uvs, b_top_uv, c_top_uv, c_top_up_uv)
add_triangle_uv(uvs, b_top_uv, c_top_up_uv, b_top_up_uv)
add_triangle_uv(uvs, a_top_uv, b_top2_up_uv, b_top2_uv)
add_triangle_uv(uvs, a_top_uv, a_top_up_uv, b_top2_up_uv)
add_triangle_uv(uvs, b_top2_uv, c_top2_up_uv, c_top2_uv)
add_triangle_uv(uvs, b_top2_uv, b_top2_up_uv, c_top2_up_uv)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 8)
func add_mine_pavilion(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 4):
var angle:float = float(strip_index) / 4.0 * TAU
var offset:float = 39.0 / 360.0 * TAU
var culet_y:float = -pavilion * 2.0
var ratio:float = 0.535 # ratio of D / C
var b_offset:float = 22.0 / 360 * TAU
var a_top:Vector3 = Vector3(cos(angle) * 100.0, 0, sin(angle) * 100.0) * rad
var b_top:Vector3 = Vector3(cos(angle + b_offset) * 105.0, 0, sin(angle + b_offset) * 105.0) * rad
var c_top:Vector3 = Vector3(cos(angle + TAU / 8.0) * 119.0, 0, sin(angle + TAU / 8.0) * 119.0) * rad
var b_top2:Vector3 = Vector3(cos(angle - b_offset) * 105.0, 0, sin(angle - b_offset) * 105.0) * rad
var c_top2:Vector3 = Vector3(cos(angle - TAU / 8.0) * 119.0, 0, sin(angle - TAU / 8.0) * 119.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 + PI / 2.0) * culet, culet_y, sin(angle - offset + PI / 2.0) * culet) * rad
var next_culet:Vector3 = counter_culet.rotated(Vector3.UP, PI / 2.0)
# mid point used to calculate positions of D and E but not used directly
# but calculating this way ensure this face is flat as possible
var mid_point:Vector3 = lerp((clockwise_culet + counter_culet) / 2.0, c_top, ratio)
# side direction vector for adjacent points
var mid_side_vector := (mid_point.cross(Vector3(mid_point.x, 0.0, mid_point.z))).normalized()
# get intersection of the mid_side line and plane defined by A and culet
# so that both faces will be flat
var mid_mult:float = radius * 0.1
var plane := calc_plane(a_top, next_culet, clockwise_culet)
var intersection = plane.intersects_ray(mid_point, -mid_side_vector)
if intersection != null:
mid_mult = (intersection as Vector3 - mid_point).length()
var d_mid:Vector3 = mid_point - mid_side_vector * mid_mult
var e_mid:Vector3 = mid_point + mid_side_vector * mid_mult
var d_mid2:Vector3 = e_mid.rotated(Vector3.UP, PI / 2.0)
add_triangle_vertices_plus_normals(verts, normals, a_top, d_mid, b_top)
add_triangle_vertices_plus_normals(verts, normals, b_top, d_mid, c_top)
add_triangle_vertices_plus_normals(verts, normals, a_top, clockwise_culet, d_mid)
add_triangle_vertices_plus_normals(verts, normals, a_top, b_top2, d_mid2)
add_triangle_vertices_plus_normals(verts, normals, b_top2, c_top2, d_mid2)
add_triangle_vertices_plus_normals(verts, normals, a_top, d_mid2, next_culet)
add_triangle_vertices_plus_normals(verts, normals, c_top, d_mid, clockwise_culet)
add_triangle_vertices_plus_normals(verts, normals, c_top, clockwise_culet, counter_culet)
add_triangle_vertices_plus_normals(verts, normals, e_mid, c_top, counter_culet)
add_triangle_vertices_plus_normals(verts, normals, a_top, next_culet, clockwise_culet)
var target_angle = atan2(a_top.x, a_top.z)
var atop_uv := radial_uv(a_top, target_angle)
var btop_uv := radial_uv(b_top, target_angle)
var btop2_uv := radial_uv(b_top2, target_angle)
var ctop_uv := radial_uv(c_top, target_angle)
var ctop2_uv := radial_uv(c_top2, target_angle)
var dmid_uv := radial_uv(d_mid, target_angle)
var dmid2_uv := radial_uv(d_mid2, target_angle)
var emid_uv := radial_uv(e_mid, target_angle)
var clockculet_uv := radial_uv(clockwise_culet, target_angle)
var nextculet_uv := radial_uv(next_culet, target_angle)
var countculet_uv := radial_uv(counter_culet, target_angle)
add_triangle_uv(uvs, atop_uv, dmid_uv, btop_uv) # a_top, d_mid, b_top)
add_triangle_uv(uvs, btop_uv, dmid_uv, ctop_uv) # normals, b_top, d_mid, c_top)
add_triangle_uv(uvs, atop_uv, clockculet_uv, dmid_uv) # a_top, clockwise_culet, d_mid)
add_triangle_uv(uvs, atop_uv, btop2_uv, dmid2_uv) # a_top, b_top2, d_mid2)
add_triangle_uv(uvs, btop2_uv, ctop2_uv, dmid2_uv) # b_top2, c_top2, d_mid2)
add_triangle_uv(uvs, atop_uv, dmid2_uv, nextculet_uv) # a_top, d_mid2, next_culet)
add_triangle_uv(uvs, ctop_uv, dmid_uv, clockculet_uv) # c_top, d_mid, clockwise_culet)
add_triangle_uv(uvs, ctop_uv, clockculet_uv, countculet_uv) # c_top, clockwise_culet, counter_culet)
add_triangle_uv(uvs, emid_uv, ctop_uv, countculet_uv) # e_mid, c_top, counter_culet)
add_triangle_uv(uvs, atop_uv, nextculet_uv, clockculet_uv) # a_top, next_culet, clockwise_culet)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 10)
func radial_uv(vect:Vector3, target_angle:float, x_mult:float = 3.0, y_mult:float = 1.0) -> Vector2:
var angle:float = atan2(vect.x, vect.z)
if abs(target_angle - angle) > PI:
if target_angle > angle:
angle += TAU
else:
angle -= TAU
var result := Vector2(angle / TAU * x_mult, vect.y * y_mult) / radius * 0.5 + Vector2(0.5, 0.5)
return result
func add_mine_culet(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
for strip_index in range(0, 4):
var angle : float = float(strip_index) / 4.0 * TAU
var offset : float = 39.0 / 360.0 * TAU
var y:float = -pavilion * 2.0
var centre:Vector3 = Vector3(0, y, 0) * rad
var counter:Vector3 = Vector3(cos(angle - offset) * culet, y, sin(angle - offset) * culet) * rad
var clockwise:Vector3 = Vector3(cos(angle + offset) * culet, y, sin(angle + offset) * culet) * rad
var next:Vector3 = counter.rotated(Vector3.UP, -PI / 2.0)
add_triangle_vertices(verts, centre, clockwise, counter)
add_triangle_vertices(verts, centre, next, clockwise)
normals.push_back(Vector3.DOWN)
normals.push_back(Vector3.DOWN)
normals.push_back(Vector3.DOWN)
normals.push_back(Vector3.DOWN)
normals.push_back(Vector3.DOWN)
normals.push_back(Vector3.DOWN)
var uv_scale:float = 1.0
var c_uv := Vector2(0.5, 0.5)
var clock_uv := Vector2(0.5 + clockwise.x * uv_scale, 0.5 + clockwise.z * uv_scale)
var count_uv := Vector2(0.5 + counter.x * uv_scale, 0.5 + counter.z * uv_scale)
var next_uv := Vector2(0.5 + next.x * uv_scale, 0.5 + next.z * uv_scale)
add_triangle_uv(uvs, c_uv, clock_uv, count_uv)
add_triangle_uv(uvs, c_uv, next_uv, clock_uv)
calculate_triangle_tangents(verts, normals, uvs, tangents)
calculate_triangle_tangents(verts, normals, uvs, tangents)
func add_point_top(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
var y:float = (crown) * 2.0 * rad
# corners
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 p:Vector3 = Vector3(0.0, y, 0.0)
add_triangle_vertices_plus_normals(verts, normals, v1, v0, p)
add_triangle_vertices_plus_normals(verts, normals, v3, v1, p)
add_triangle_vertices_plus_normals(verts, normals, v2, v3, p)
add_triangle_vertices_plus_normals(verts, normals, v0, v2, p)
var uv0 := Vector2(0.0, 0.0)
var uv1 := Vector2(0.0, 1.0)
var uv2 := Vector2(1.0, 0.0)
var uv3 := Vector2(1.0, 1.0)
var uvp := Vector2(0.5, 0.5)
add_triangle_uv(uvs, uv1, uv0, uvp)
add_triangle_uv(uvs, uv3, uv1, uvp)
add_triangle_uv(uvs, uv2, uv3, uvp)
add_triangle_uv(uvs, uv0, uv2, uvp)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 4)
func add_table_top(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
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)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 10)
func add_table_pavilion(verts : PackedVector3Array, normals : PackedVector3Array, uvs : PackedVector2Array, tangents : PackedFloat32Array):
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)
calculate_triangle_tangents_counter(verts, normals, uvs, tangents, 4)
func _create_mesh_array() -> Array:
#const tetra_angle : float = -19.471220333
var verts := PackedVector3Array()
var uvs := PackedVector2Array()
var normals := PackedVector3Array()
var tangents := PackedFloat32Array()
match cut:
CutType.Table:
add_table_top(verts, normals, uvs, tangents)
add_table_pavilion(verts, normals, uvs, tangents)
CutType.Point:
add_point_top(verts, normals, uvs, tangents)
add_table_pavilion(verts, normals, uvs, tangents)
CutType.OldMine:
add_mine_table(verts, normals, uvs, tangents)
add_mine_crown(verts, normals, uvs, tangents)
add_mine_girdle(verts, normals, uvs, tangents)
add_mine_pavilion(verts, normals, uvs, tangents)
add_mine_culet(verts, normals, uvs, tangents)
CutType.OldEuropean:
add_table(verts, normals, uvs, tangents)
add_crown(verts, normals, uvs, tangents)
add_girdle(verts, normals, uvs, tangents)
add_pavilion(verts, normals, uvs, tangents)
add_culet(verts, normals, uvs, tangents)
_: # default
add_table(verts, normals, uvs, tangents)
add_crown(verts, normals, uvs, tangents)
add_girdle(verts, normals, uvs, tangents)
add_pavilion(verts, normals, uvs, tangents)
add_culet(verts, normals, uvs, tangents)
var arrays = []
arrays.resize(Mesh.ARRAY_MAX)
arrays[Mesh.ARRAY_VERTEX] = verts
arrays[Mesh.ARRAY_TEX_UV] = uvs
arrays[Mesh.ARRAY_NORMAL] = normals
# i have to calculate my own tangents to ensure parallax shader works
print("tangents ", tangents.size(), " vs ", normals.size())
arrays[Mesh.ARRAY_TANGENT] = tangents
#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