81 lines
2.7 KiB
GDScript
81 lines
2.7 KiB
GDScript
extends Object
|
|
|
|
func new_array_from_typeid(typeid: Variant.Type) -> Variant:
|
|
return type_convert(null, typeid)
|
|
|
|
|
|
func array_custom_granularity(custom_format: Mesh.ArrayCustomFormat) -> int:
|
|
match custom_format:
|
|
Mesh.ARRAY_CUSTOM_RGBA8_UNORM, Mesh.ARRAY_CUSTOM_RGBA8_SNORM, Mesh.ARRAY_CUSTOM_RG_HALF:
|
|
return 4
|
|
Mesh.ARRAY_CUSTOM_RGBA_HALF:
|
|
return 8
|
|
Mesh.ARRAY_CUSTOM_R_FLOAT:
|
|
return 1
|
|
Mesh.ARRAY_CUSTOM_RG_FLOAT:
|
|
return 2
|
|
Mesh.ARRAY_CUSTOM_RGB_FLOAT:
|
|
return 3
|
|
Mesh.ARRAY_CUSTOM_RGBA_FLOAT:
|
|
return 4
|
|
return 0
|
|
|
|
|
|
func array_granularity(arr_id: Mesh.ArrayType, format: Mesh.ArrayFormat) -> int:
|
|
match arr_id:
|
|
Mesh.ARRAY_VERTEX, Mesh.ARRAY_NORMAL, Mesh.ARRAY_COLOR, Mesh.ARRAY_TEX_UV, Mesh.ARRAY_TEX_UV2:
|
|
return 1
|
|
Mesh.ARRAY_TANGENT:
|
|
return 4
|
|
Mesh.ARRAY_CUSTOM0:
|
|
return array_custom_granularity((format >> Mesh.ARRAY_FORMAT_CUSTOM0_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK)
|
|
Mesh.ARRAY_CUSTOM1:
|
|
return array_custom_granularity((format >> Mesh.ARRAY_FORMAT_CUSTOM1_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK)
|
|
Mesh.ARRAY_CUSTOM2:
|
|
return array_custom_granularity((format >> Mesh.ARRAY_FORMAT_CUSTOM2_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK)
|
|
Mesh.ARRAY_CUSTOM3:
|
|
return array_custom_granularity((format >> Mesh.ARRAY_FORMAT_CUSTOM3_SHIFT) & Mesh.ARRAY_FORMAT_CUSTOM_MASK)
|
|
Mesh.ARRAY_BONES, Mesh.ARRAY_WEIGHTS:
|
|
if (format & Mesh.ARRAY_FLAG_USE_8_BONE_WEIGHTS) != 0:
|
|
return 8
|
|
else:
|
|
return 4
|
|
# Unhandled:
|
|
# ARRAY_INDEX
|
|
return 0
|
|
|
|
## "Unroll" array mesh.
|
|
## Known limitations:
|
|
## - ignores blend shapes
|
|
## - ignores LODs
|
|
func duplicate_vertices(input: ArrayMesh) -> ArrayMesh:
|
|
var output: ArrayMesh = ArrayMesh.new()
|
|
for surf: int in input.get_surface_count():
|
|
var arrays: Array = input.surface_get_arrays(surf)
|
|
var indices: int = arrays[Mesh.ARRAY_INDEX]
|
|
var format: Mesh.ArrayFormat = input.surface_get_format(surf)
|
|
var new_arrays: Array = []
|
|
new_arrays.resize(Mesh.ARRAY_MAX)
|
|
|
|
for arr_id: int in len(arrays):
|
|
if arr_id == Mesh.ARRAY_INDEX: # this is the one we want to eliminate
|
|
continue
|
|
if arrays[arr_id] == null:
|
|
continue
|
|
var arr_in: Array = arrays[arr_id]
|
|
var typeid: int = typeof(arr_in)
|
|
var new_arr: Variant = new_array_from_typeid(typeid)
|
|
assert(typeof(new_arr) == typeid)
|
|
var granularity: int = array_granularity(arr_id, format)
|
|
for idx: int in indices:
|
|
for subidx: int in granularity:
|
|
new_arr.push_back(arr_in[idx * granularity + subidx])
|
|
|
|
print(arr_id, ' ', typeid, ' ', granularity, ' ', len(arr_in), '->', len(new_arr))
|
|
|
|
new_arrays[arr_id] = new_arr
|
|
|
|
output.add_surface_from_arrays(input.surface_get_primitive_type(surf), new_arrays, [], {}, format & ~Mesh.ARRAY_FORMAT_INDEX)
|
|
|
|
return output
|