Added character customization tools
This commit is contained in:
BIN
proto2/assets/blender-2.80/common-all.blend
Normal file
BIN
proto2/assets/blender-2.80/common-all.blend
Normal file
Binary file not shown.
10
proto2/assets/blender-2.80/common-all.json
Normal file
10
proto2/assets/blender-2.80/common-all.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"outpath": "characters/common",
|
||||||
|
"split": true,
|
||||||
|
"files": [
|
||||||
|
"common_part1.blend",
|
||||||
|
"common_part2.blend",
|
||||||
|
"common_part3.blend",
|
||||||
|
"common_part4.blend"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
proto2/assets/blender-2.80/female_2018.blend
Normal file
BIN
proto2/assets/blender-2.80/female_2018.blend
Normal file
Binary file not shown.
3
proto2/assets/blender-2.80/female_2018.json
Normal file
3
proto2/assets/blender-2.80/female_2018.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"outpath": "characters"
|
||||||
|
}
|
||||||
BIN
proto2/assets/blender-2.80/male_2018.blend
Normal file
BIN
proto2/assets/blender-2.80/male_2018.blend
Normal file
Binary file not shown.
3
proto2/assets/blender-2.80/male_2018.json
Normal file
3
proto2/assets/blender-2.80/male_2018.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"outpath": "characters"
|
||||||
|
}
|
||||||
664
proto2/characters/common/common_part0.escn
Normal file
664
proto2/characters/common/common_part0.escn
Normal file
File diff suppressed because one or more lines are too long
1062
proto2/characters/common/common_part0.escn.import
Normal file
1062
proto2/characters/common/common_part0.escn.import
Normal file
File diff suppressed because it is too large
Load Diff
664
proto2/characters/common/common_part1.escn
Normal file
664
proto2/characters/common/common_part1.escn
Normal file
File diff suppressed because one or more lines are too long
1062
proto2/characters/common/common_part1.escn.import
Normal file
1062
proto2/characters/common/common_part1.escn.import
Normal file
File diff suppressed because it is too large
Load Diff
664
proto2/characters/common/common_part2.escn
Normal file
664
proto2/characters/common/common_part2.escn
Normal file
File diff suppressed because one or more lines are too long
1062
proto2/characters/common/common_part2.escn.import
Normal file
1062
proto2/characters/common/common_part2.escn.import
Normal file
File diff suppressed because it is too large
Load Diff
664
proto2/characters/common/common_part3.escn
Normal file
664
proto2/characters/common/common_part3.escn
Normal file
File diff suppressed because one or more lines are too long
1062
proto2/characters/common/common_part3.escn.import
Normal file
1062
proto2/characters/common/common_part3.escn.import
Normal file
File diff suppressed because it is too large
Load Diff
664
proto2/characters/common/common_part4.escn
Normal file
664
proto2/characters/common/common_part4.escn
Normal file
File diff suppressed because one or more lines are too long
1062
proto2/characters/common/common_part4.escn.import
Normal file
1062
proto2/characters/common/common_part4.escn.import
Normal file
File diff suppressed because it is too large
Load Diff
664
proto2/characters/common/common_part5.escn
Normal file
664
proto2/characters/common/common_part5.escn
Normal file
File diff suppressed because one or more lines are too long
1062
proto2/characters/common/common_part5.escn.import
Normal file
1062
proto2/characters/common/common_part5.escn.import
Normal file
File diff suppressed because it is too large
Load Diff
312
proto2/characters/common/common_part6.escn
Normal file
312
proto2/characters/common/common_part6.escn
Normal file
File diff suppressed because one or more lines are too long
1062
proto2/characters/common/common_part6.escn.import
Normal file
1062
proto2/characters/common/common_part6.escn.import
Normal file
File diff suppressed because it is too large
Load Diff
BIN
proto2/characters/common/config.bin
Normal file
BIN
proto2/characters/common/config.bin
Normal file
Binary file not shown.
11
proto2/characters/common/data.json
Normal file
11
proto2/characters/common/data.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"characters/common/common_part0.escn",
|
||||||
|
"characters/common/common_part1.escn",
|
||||||
|
"characters/common/common_part2.escn",
|
||||||
|
"characters/common/common_part3.escn",
|
||||||
|
"characters/common/common_part4.escn",
|
||||||
|
"characters/common/common_part5.escn",
|
||||||
|
"characters/common/common_part6.escn"
|
||||||
|
]
|
||||||
|
}
|
||||||
26
proto2/characters/drawable.gd
Normal file
26
proto2/characters/drawable.gd
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
extends ColorRect
|
||||||
|
|
||||||
|
const TEX_SIZE = 512
|
||||||
|
var triangles : Array = []
|
||||||
|
var min_point: Vector3 = Vector3(-1, -1, -1)
|
||||||
|
var max_point: Vector3 = Vector3(-1, -1, -1)
|
||||||
|
var normals = false
|
||||||
|
|
||||||
|
func _draw():
|
||||||
|
var default_color = Color(0.5, 0.5, 0.5, 1.0)
|
||||||
|
default_color.r = range_lerp(0, min_point.x, max_point.x, 0.0, 1.0)
|
||||||
|
default_color.g = range_lerp(0, min_point.y, max_point.y, 0.0, 1.0)
|
||||||
|
default_color.b = range_lerp(0, min_point.z, max_point.z, 0.0, 1.0)
|
||||||
|
draw_rect(Rect2(0, 0, TEX_SIZE, TEX_SIZE), default_color, true)
|
||||||
|
for t in triangles:
|
||||||
|
var colors = []
|
||||||
|
var uvs = []
|
||||||
|
for k in t:
|
||||||
|
# print(k.shape)
|
||||||
|
# print(k.uv)
|
||||||
|
if normals:
|
||||||
|
colors.push_back(Color(k.normal.x, k.normal.y, k.normal.z, 1))
|
||||||
|
else:
|
||||||
|
colors.push_back(Color(k.shape.x, k.shape.y, k.shape.z, 1))
|
||||||
|
uvs.push_back(k.uv * TEX_SIZE)
|
||||||
|
draw_polygon(PoolVector2Array(uvs), PoolColorArray(colors))
|
||||||
399
proto2/characters/generate_maps.gd
Normal file
399
proto2/characters/generate_maps.gd
Normal file
@@ -0,0 +1,399 @@
|
|||||||
|
extends Control
|
||||||
|
|
||||||
|
const TEX_SIZE: int = 512
|
||||||
|
var min_point = Vector3()
|
||||||
|
var max_point = Vector3()
|
||||||
|
var min_normal = Vector3()
|
||||||
|
var max_normal = Vector3()
|
||||||
|
var maps = {}
|
||||||
|
var vert_indices = {}
|
||||||
|
var draw_data_list : = []
|
||||||
|
|
||||||
|
onready var characters = [load("res://characters/female_2018.escn"), load("res://characters/male_2018.escn")]
|
||||||
|
|
||||||
|
func find_mesh_name(base: Node, mesh_name: String) -> MeshInstance:
|
||||||
|
var queue = [base]
|
||||||
|
var mi: MeshInstance
|
||||||
|
while queue.size() > 0:
|
||||||
|
var item = queue[0]
|
||||||
|
queue.pop_front()
|
||||||
|
if item is MeshInstance && item.name == mesh_name:
|
||||||
|
mi = item
|
||||||
|
break
|
||||||
|
for c in item.get_children():
|
||||||
|
queue.push_back(c)
|
||||||
|
return mi
|
||||||
|
|
||||||
|
func find_same_verts():
|
||||||
|
for chdata in range(characters.size()):
|
||||||
|
var ch_scene = characters[chdata].instance()
|
||||||
|
var bmesh = find_mesh_name(ch_scene, "body")
|
||||||
|
if !vert_indices.has(chdata):
|
||||||
|
vert_indices[chdata] = {}
|
||||||
|
for surface in range(bmesh.mesh.get_surface_count()):
|
||||||
|
var arrays: Array = bmesh.mesh.surface_get_arrays(surface).duplicate(true)
|
||||||
|
for index1 in range(arrays[ArrayMesh.ARRAY_VERTEX].size()):
|
||||||
|
var v1: Vector3 = arrays[ArrayMesh.ARRAY_VERTEX][index1]
|
||||||
|
var ok = false
|
||||||
|
for rk in vert_indices[chdata].keys():
|
||||||
|
if (v1 - rk).length() < 0.001:
|
||||||
|
ok = true
|
||||||
|
vert_indices[chdata][rk].push_back(index1)
|
||||||
|
if !ok:
|
||||||
|
vert_indices[chdata][v1] = [index1]
|
||||||
|
|
||||||
|
func find_min_max(mesh: ArrayMesh):
|
||||||
|
min_point = mesh.surface_get_blend_shape_arrays(0)[0][ArrayMesh.ARRAY_VERTEX][0] - mesh.surface_get_arrays(0)[ArrayMesh.ARRAY_VERTEX][0]
|
||||||
|
max_point = mesh.surface_get_blend_shape_arrays(0)[0][ArrayMesh.ARRAY_VERTEX][0] - mesh.surface_get_arrays(0)[ArrayMesh.ARRAY_VERTEX][0]
|
||||||
|
for sc in range(mesh.get_surface_count()):
|
||||||
|
var bshapes: Array = mesh.surface_get_blend_shape_arrays(sc).duplicate(true)
|
||||||
|
var arrays: Array = mesh.surface_get_arrays(sc).duplicate(true)
|
||||||
|
for src in bshapes:
|
||||||
|
for index in range(arrays[ArrayMesh.ARRAY_VERTEX].size()):
|
||||||
|
var v: Vector3 = src[ArrayMesh.ARRAY_VERTEX][index] - arrays[ArrayMesh.ARRAY_VERTEX][index]
|
||||||
|
var n: Vector3 = src[ArrayMesh.ARRAY_NORMAL][index] - arrays[ArrayMesh.ARRAY_NORMAL][index]
|
||||||
|
for ipos in range(3):
|
||||||
|
if min_point[ipos] > v[ipos]:
|
||||||
|
min_point[ipos] = v[ipos]
|
||||||
|
if max_point[ipos] < v[ipos]:
|
||||||
|
max_point[ipos] = v[ipos]
|
||||||
|
if min_normal[ipos] > n[ipos]:
|
||||||
|
min_normal[ipos] = n[ipos]
|
||||||
|
if max_normal[ipos] < n[ipos]:
|
||||||
|
max_normal[ipos] = n[ipos]
|
||||||
|
print("min: ", min_point, "max: ", max_point)
|
||||||
|
static func check_triangle(verts: Array) -> bool:
|
||||||
|
var uv1 = verts[0].uv
|
||||||
|
var uv2 = verts[1].uv
|
||||||
|
var uv3 = verts[2].uv
|
||||||
|
var v1 = uv1 - uv3
|
||||||
|
var v2 = uv1 - uv3
|
||||||
|
if v1.length() * TEX_SIZE < 1.2:
|
||||||
|
return false
|
||||||
|
if v2.length() * TEX_SIZE < 1.2:
|
||||||
|
return false
|
||||||
|
var sumdata = Vector3()
|
||||||
|
for k in range(2):
|
||||||
|
for ks in range(verts[k].shape.size()):
|
||||||
|
sumdata += verts[k].shape[ks]
|
||||||
|
if sumdata.length() < 0.001:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
static func pad_morphs(morphs: Dictionary, nshapes: Dictionary, min_point: Vector3, max_point: Vector3, min_normal: Vector3, max_normal: Vector3):
|
||||||
|
for mesh in morphs.keys():
|
||||||
|
for m in morphs[mesh].keys():
|
||||||
|
var ns = nshapes[mesh][m]
|
||||||
|
for t in range(morphs[mesh][m].size()):
|
||||||
|
for v in range(morphs[mesh][m][t].size()):
|
||||||
|
# print(morphs[m][t][v])
|
||||||
|
for s in range(morphs[mesh][m][t][v].shape.size()):
|
||||||
|
for u in range(2):
|
||||||
|
var cd : float = max_point[u] - min_point[u]
|
||||||
|
var ncd : float = max_normal[u] - min_normal[u]
|
||||||
|
var d = morphs[mesh][m][t][v].shape[s][u]
|
||||||
|
morphs[mesh][m][t][v].shape[s][u] = (d - min_point[u]) / cd
|
||||||
|
var ew = morphs[mesh][m][t][v].shape[s][u] * cd + min_point[u]
|
||||||
|
assert abs(ew - d) < 0.001
|
||||||
|
morphs[mesh][m][t][v].normal[s][u] = (morphs[mesh][m][t][v].normal[s][u] - min_normal[u]) / ncd
|
||||||
|
static func fill_draw_data(morphs: Dictionary, draw_data: Dictionary, morph_names: Dictionary, nshapes: Dictionary, rects: Dictionary):
|
||||||
|
var offset : = 0
|
||||||
|
for mesh in morphs.keys():
|
||||||
|
for m in morphs[mesh].keys():
|
||||||
|
if !draw_data.has(m):
|
||||||
|
draw_data[m] = {}
|
||||||
|
var ns = nshapes[mesh][m]
|
||||||
|
for sh in range(ns):
|
||||||
|
print(morph_names[mesh][m][sh], ": ", m, " ", sh + offset)
|
||||||
|
draw_data[m][sh + offset] = {"name": morph_names[mesh][m][sh], "triangles": [], "rects": []}
|
||||||
|
for t in range(morphs[mesh][m].size()):
|
||||||
|
var tri : = []
|
||||||
|
var midp = Vector2()
|
||||||
|
var sp = Vector3()
|
||||||
|
|
||||||
|
for v in range(morphs[mesh][m][t].size()):
|
||||||
|
midp += morphs[mesh][m][t][v].uv
|
||||||
|
midp /= 3.0
|
||||||
|
for v in range(morphs[mesh][m][t].size()):
|
||||||
|
var pt = morphs[mesh][m][t][v].uv - midp
|
||||||
|
var dpt = pt.normalized() * (3.5 / TEX_SIZE)
|
||||||
|
tri.push_back({"uv": morphs[mesh][m][t][v].uv + dpt, "shape": morphs[mesh][m][t][v].shape[sh], "normal": morphs[mesh][m][t][v].normal[sh]})
|
||||||
|
draw_data[m][sh + offset].triangles.push_back(tri)
|
||||||
|
draw_data[m][sh + offset].rect = rects[mesh][m][sh]
|
||||||
|
offset = draw_data[m].keys().size()
|
||||||
|
|
||||||
|
var common = []
|
||||||
|
var common_path = "characters/common"
|
||||||
|
func load_data():
|
||||||
|
var fd = File.new()
|
||||||
|
fd.open("characters/common/data.json", File.READ)
|
||||||
|
var json = fd.get_as_text()
|
||||||
|
var json_result = JSON.parse(json)
|
||||||
|
var json_data = json_result.result
|
||||||
|
fd.close()
|
||||||
|
for e in json_data.files:
|
||||||
|
var load_path = "res://" + e
|
||||||
|
var item = load(load_path)
|
||||||
|
assert item
|
||||||
|
common.push_back(item)
|
||||||
|
|
||||||
|
static func update_rects(arrays: Array, bshapes: Array) -> Dictionary:
|
||||||
|
var rects = {}
|
||||||
|
for idx in range(0, arrays[ArrayMesh.ARRAY_INDEX].size(), 3):
|
||||||
|
for t in range(3):
|
||||||
|
var index_base = arrays[ArrayMesh.ARRAY_INDEX][idx + t]
|
||||||
|
var vertex_base = arrays[ArrayMesh.ARRAY_VERTEX][index_base]
|
||||||
|
var normal_base = arrays[ArrayMesh.ARRAY_NORMAL][index_base]
|
||||||
|
var uv_base = arrays[ArrayMesh.ARRAY_TEX_UV][index_base]
|
||||||
|
for bsc in range(bshapes.size()):
|
||||||
|
if !rects.has(bsc):
|
||||||
|
rects[bsc] = Rect2(uv_base, Vector2())
|
||||||
|
var vertex_mod = bshapes[bsc][ArrayMesh.ARRAY_VERTEX][index_base] - vertex_base
|
||||||
|
if vertex_mod.length() > 0.0001:
|
||||||
|
rects[bsc] = rects[bsc].expand(uv_base)
|
||||||
|
return rects
|
||||||
|
static func update_triangles(arrays: Array, bshapes: Array) -> Array:
|
||||||
|
var triangles: Array = []
|
||||||
|
var ntriangles : = 0
|
||||||
|
var skipped : = 0
|
||||||
|
for idx in range(0, arrays[ArrayMesh.ARRAY_INDEX].size(), 3):
|
||||||
|
var verts = []
|
||||||
|
for t in range(3):
|
||||||
|
var index_base = arrays[ArrayMesh.ARRAY_INDEX][idx + t]
|
||||||
|
var vertex_base = arrays[ArrayMesh.ARRAY_VERTEX][index_base]
|
||||||
|
var normal_base = arrays[ArrayMesh.ARRAY_NORMAL][index_base]
|
||||||
|
var uv_base = arrays[ArrayMesh.ARRAY_TEX_UV][index_base]
|
||||||
|
var index_shape = []
|
||||||
|
var vertex_shape = []
|
||||||
|
var normal_shape = []
|
||||||
|
var uv_shape = []
|
||||||
|
for bsc in range(bshapes.size()):
|
||||||
|
index_shape.push_back(bshapes[bsc][ArrayMesh.ARRAY_INDEX][idx + t])
|
||||||
|
var index = index_shape[index_shape.size() - 1]
|
||||||
|
if index != index_base:
|
||||||
|
print("index mismatch", bsc, " ", index_base, " ", index)
|
||||||
|
var vertex_mod = bshapes[bsc][ArrayMesh.ARRAY_VERTEX][index] - vertex_base
|
||||||
|
var normal_mod = bshapes[bsc][ArrayMesh.ARRAY_NORMAL][index] - normal_base
|
||||||
|
vertex_shape.push_back(vertex_mod)
|
||||||
|
normal_shape.push_back(normal_mod)
|
||||||
|
uv_shape.push_back(bshapes[bsc][ArrayMesh.ARRAY_TEX_UV][index])
|
||||||
|
if (uv_shape[uv_shape.size() - 1] - uv_base).length() != 0:
|
||||||
|
print("uv mismatch", bsc, " ", idx)
|
||||||
|
var vdata = {}
|
||||||
|
vdata.shape = vertex_shape
|
||||||
|
vdata.normal = normal_shape
|
||||||
|
vdata.uv = uv_base
|
||||||
|
verts.push_back(vdata)
|
||||||
|
if check_triangle(verts):
|
||||||
|
triangles.push_back(verts)
|
||||||
|
ntriangles += 1
|
||||||
|
else:
|
||||||
|
skipped += 1
|
||||||
|
if skipped > 0:
|
||||||
|
print("ntriangles: ", ntriangles, " skipped: ", skipped)
|
||||||
|
return triangles
|
||||||
|
static func get_shape_names(mesh: ArrayMesh) -> PoolStringArray:
|
||||||
|
var shape_names: Array = []
|
||||||
|
for r in range(mesh.get_blend_shape_count()):
|
||||||
|
shape_names.push_back(mesh.get_blend_shape_name(r))
|
||||||
|
return PoolStringArray(shape_names)
|
||||||
|
static func process_morph_meshes(mesh: ArrayMesh, morphs: Dictionary, rects: Dictionary, mesh_data: Dictionary, nshapes: Dictionary):
|
||||||
|
for sc in range(mesh.get_surface_count()):
|
||||||
|
if !morphs.has(sc):
|
||||||
|
morphs[sc] = []
|
||||||
|
mesh_data[sc] = PoolStringArray()
|
||||||
|
rects[sc] = {}
|
||||||
|
var bshapes: Array = mesh.surface_get_blend_shape_arrays(sc)
|
||||||
|
var arrays: Array = mesh.surface_get_arrays(sc)
|
||||||
|
print("vertices: ", arrays[ArrayMesh.ARRAY_VERTEX].size())
|
||||||
|
print("indices: ", arrays[ArrayMesh.ARRAY_INDEX].size())
|
||||||
|
print("surf: ", sc, " shapes: ", bshapes.size())
|
||||||
|
var shape_names : = get_shape_names(mesh)
|
||||||
|
rects[sc] = update_rects(arrays, bshapes)
|
||||||
|
var triangles : = update_triangles(arrays, bshapes)
|
||||||
|
morphs[sc] += triangles
|
||||||
|
mesh_data[sc] += shape_names
|
||||||
|
nshapes[sc] = bshapes.size()
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var morphs = {}
|
||||||
|
var morphs_helper = {}
|
||||||
|
var mesh_data = {}
|
||||||
|
var mesh_data_helper = {}
|
||||||
|
var nshapes = {}
|
||||||
|
var rects = {}
|
||||||
|
var rects_helper = {}
|
||||||
|
var nshapes_helper = {}
|
||||||
|
load_data()
|
||||||
|
var base_shapes : = PoolStringArray()
|
||||||
|
var file_shapes = {}
|
||||||
|
for mesh_no in range(common.size()):
|
||||||
|
var ch: Node = common[mesh_no].instance()
|
||||||
|
var mi: MeshInstance = find_mesh_name(ch, "base")
|
||||||
|
var mesh: ArrayMesh = mi.mesh
|
||||||
|
var morph_list = get_shape_names(mesh)
|
||||||
|
base_shapes += morph_list
|
||||||
|
file_shapes[common[mesh_no].resource_path] = morph_list
|
||||||
|
for helper in ["robe_helper", "tights_helper", "skirt_helper"]:
|
||||||
|
var helper_shapes : = PoolStringArray()
|
||||||
|
for mesh_no in range(common.size()):
|
||||||
|
var ch: Node = common[mesh_no].instance()
|
||||||
|
var mi: MeshInstance = find_mesh_name(ch, helper)
|
||||||
|
var mesh: ArrayMesh = mi.mesh
|
||||||
|
var morph_list = get_shape_names(mesh)
|
||||||
|
helper_shapes += morph_list
|
||||||
|
for e in base_shapes:
|
||||||
|
assert e in helper_shapes
|
||||||
|
|
||||||
|
for mesh_no in range(common.size()):
|
||||||
|
# var skipped : = 0
|
||||||
|
# var ntriangles : = 0
|
||||||
|
var ch: Node = common[mesh_no].instance()
|
||||||
|
# add_child(ch)
|
||||||
|
var mi: MeshInstance = find_mesh_name(ch, "base")
|
||||||
|
if !mi:
|
||||||
|
return
|
||||||
|
var mesh: ArrayMesh = mi.mesh
|
||||||
|
if !mesh:
|
||||||
|
return
|
||||||
|
find_min_max(mesh)
|
||||||
|
if !morphs.has(mesh_no):
|
||||||
|
morphs[mesh_no] = {}
|
||||||
|
mesh_data[mesh_no] = {}
|
||||||
|
nshapes[mesh_no] = {}
|
||||||
|
rects[mesh_no] = {}
|
||||||
|
process_morph_meshes(mesh, morphs[mesh_no], rects[mesh_no], mesh_data[mesh_no], nshapes[mesh_no])
|
||||||
|
pad_morphs(morphs, nshapes, min_point, max_point, min_normal, max_normal)
|
||||||
|
for mesh_no in range(common.size()):
|
||||||
|
var ch: Node = common[mesh_no].instance()
|
||||||
|
# var mi: MeshInstance = find_mesh_name(ch, "base")
|
||||||
|
var mi_robe: MeshInstance = find_mesh_name(ch, "robe_helper")
|
||||||
|
assert mi_robe != null
|
||||||
|
var mesh: ArrayMesh = mi_robe.mesh
|
||||||
|
# var mesh_skirt: ArrayMesh = mi_skirt.mesh
|
||||||
|
morphs_helper[mesh_no] = {}
|
||||||
|
rects_helper[mesh_no] = {}
|
||||||
|
mesh_data_helper[mesh_no] = {}
|
||||||
|
nshapes_helper[mesh_no] = {}
|
||||||
|
process_morph_meshes(mesh, morphs_helper[mesh_no], rects_helper[mesh_no], mesh_data_helper[mesh_no], nshapes_helper[mesh_no])
|
||||||
|
pad_morphs(morphs_helper, nshapes_helper, min_point, max_point, min_normal, max_normal)
|
||||||
|
# TODO: combine helpers here
|
||||||
|
var draw_data: Dictionary = {}
|
||||||
|
fill_draw_data(morphs, draw_data, mesh_data, nshapes, rects)
|
||||||
|
draw_data_list.push_back(draw_data)
|
||||||
|
var draw_data_helper: Dictionary = {}
|
||||||
|
fill_draw_data(morphs_helper, draw_data_helper, mesh_data_helper, nshapes_helper, rects_helper)
|
||||||
|
draw_data_list.push_back(draw_data_helper)
|
||||||
|
print("data count: ", draw_data.keys(), " ", draw_data[0].keys())
|
||||||
|
$gen/drawable.triangles = draw_data[0][0].triangles
|
||||||
|
$gen/drawable.min_point = min_point
|
||||||
|
$gen/drawable.max_point = max_point
|
||||||
|
$gen/drawable.normals = false
|
||||||
|
# print("done ", mesh.get_surface_count(), " ", mesh.get_blend_shape_count(), " ", min_point, " ", max_point, " added: ", ntriangles, " skipped: ", skipped)
|
||||||
|
var helper : = 0
|
||||||
|
var surface : = 0
|
||||||
|
var shape : = 0
|
||||||
|
var exit_delay : = 3.0
|
||||||
|
var draw_delay : = 2.0
|
||||||
|
func save_viewport(shape_name: String, rect: Rect2):
|
||||||
|
var viewport: Viewport = $gen
|
||||||
|
var vtex : = viewport.get_texture()
|
||||||
|
var tex_img : = vtex.get_data()
|
||||||
|
var fn = ""
|
||||||
|
if !maps.has(shape_name):
|
||||||
|
maps[shape_name] = {}
|
||||||
|
maps[shape_name].width = tex_img.get_width()
|
||||||
|
maps[shape_name].height = tex_img.get_height()
|
||||||
|
maps[shape_name].format = tex_img.get_format()
|
||||||
|
var byte_data = tex_img.duplicate(true).get_data()
|
||||||
|
var image_size = byte_data.size()
|
||||||
|
if $gen/drawable.normals:
|
||||||
|
maps[shape_name].image_normal_data = byte_data.compress(File.COMPRESSION_FASTLZ)
|
||||||
|
maps[shape_name].image_normal_size = image_size
|
||||||
|
else:
|
||||||
|
maps[shape_name].image_data = byte_data.compress(File.COMPRESSION_FASTLZ)
|
||||||
|
maps[shape_name].rect = rect.grow(0.003)
|
||||||
|
maps[shape_name].image_size = image_size
|
||||||
|
|
||||||
|
var helpers = ["", "robe_"]
|
||||||
|
func finish_map_gen():
|
||||||
|
print("generating same vert indices...")
|
||||||
|
find_same_verts()
|
||||||
|
var fd = File.new()
|
||||||
|
fd.open("res://characters/common/config.bin", File.WRITE)
|
||||||
|
fd.store_var(min_point)
|
||||||
|
fd.store_var(max_point)
|
||||||
|
fd.store_var(min_normal)
|
||||||
|
fd.store_var(max_normal)
|
||||||
|
fd.store_var(maps)
|
||||||
|
fd.store_var(vert_indices)
|
||||||
|
fd.close()
|
||||||
|
get_tree().quit()
|
||||||
|
# get_tree().change_scene("res://map_test.tscn")
|
||||||
|
func next_surface():
|
||||||
|
shape = 0
|
||||||
|
surface += 1
|
||||||
|
draw_delay = 1.0
|
||||||
|
$gen_maps/ProgressBar.value = 100.0
|
||||||
|
$gen/drawable.normals = false
|
||||||
|
func next_helper():
|
||||||
|
shape = 0
|
||||||
|
surface = 0
|
||||||
|
draw_delay = 1.0
|
||||||
|
helper += 1
|
||||||
|
$gen/drawable.normals = false
|
||||||
|
func setup_draw():
|
||||||
|
$gen/drawable.normals = !$gen/drawable.normals
|
||||||
|
if $gen/drawable.normals:
|
||||||
|
$gen/drawable.min_point = min_normal
|
||||||
|
$gen/drawable.max_point = max_normal
|
||||||
|
else:
|
||||||
|
$gen/drawable.min_point = min_point
|
||||||
|
$gen/drawable.max_point = max_point
|
||||||
|
$gen/drawable.triangles = draw_data_list[helper][surface][shape].triangles
|
||||||
|
$gen/drawable.update()
|
||||||
|
func _process(delta):
|
||||||
|
match(helper):
|
||||||
|
0:
|
||||||
|
if surface == draw_data_list[helper].size():
|
||||||
|
if exit_delay > 0:
|
||||||
|
exit_delay -= delta
|
||||||
|
print(exit_delay)
|
||||||
|
else:
|
||||||
|
next_helper()
|
||||||
|
elif shape == draw_data_list[helper][surface].size():
|
||||||
|
next_surface()
|
||||||
|
else:
|
||||||
|
$gen_maps/ProgressBar.value = 100.0 * shape / draw_data_list[helper][surface].size()
|
||||||
|
print("value ", $gen_maps/ProgressBar.value)
|
||||||
|
if draw_delay > 0:
|
||||||
|
draw_delay -= delta
|
||||||
|
else:
|
||||||
|
save_viewport(helpers[helper] + draw_data_list[helper][surface][shape].name, draw_data_list[helper][surface][shape].rect)
|
||||||
|
if $gen/drawable.normals:
|
||||||
|
shape += 1
|
||||||
|
draw_delay = 1.0
|
||||||
|
print("shape ", shape)
|
||||||
|
if shape < draw_data_list[helper][surface].size():
|
||||||
|
setup_draw()
|
||||||
|
1:
|
||||||
|
if surface == draw_data_list[helper].size():
|
||||||
|
if exit_delay > 0:
|
||||||
|
exit_delay -= delta
|
||||||
|
print(exit_delay)
|
||||||
|
else:
|
||||||
|
finish_map_gen()
|
||||||
|
elif shape == draw_data_list[helper][surface].size():
|
||||||
|
next_surface()
|
||||||
|
else:
|
||||||
|
$gen_maps/ProgressBar.value = 100.0 * shape / draw_data_list[helper][surface].size()
|
||||||
|
print("value ", $gen_maps/ProgressBar.value)
|
||||||
|
if draw_delay > 0:
|
||||||
|
draw_delay -= delta
|
||||||
|
else:
|
||||||
|
save_viewport(helpers[helper] + draw_data_list[helper][surface][shape].name, draw_data_list[helper][surface][shape].rect)
|
||||||
|
if $gen/drawable.normals:
|
||||||
|
shape += 1
|
||||||
|
draw_delay = 1.0
|
||||||
|
print("shape ", shape)
|
||||||
|
if shape < draw_data_list[helper][surface].size():
|
||||||
|
setup_draw()
|
||||||
44
proto2/characters/generate_maps.tscn
Normal file
44
proto2/characters/generate_maps.tscn
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
[gd_scene load_steps=3 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://characters/drawable.gd" type="Script" id=1]
|
||||||
|
[ext_resource path="res://characters/generate_maps.gd" type="Script" id=2]
|
||||||
|
|
||||||
|
[node name="generate_maps" type="Control"]
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
script = ExtResource( 2 )
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": true
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="gen" type="Viewport" parent="."]
|
||||||
|
size = Vector2( 512, 512 )
|
||||||
|
disable_3d = true
|
||||||
|
usage = 0
|
||||||
|
render_target_v_flip = true
|
||||||
|
render_target_update_mode = 3
|
||||||
|
|
||||||
|
[node name="drawable" type="ColorRect" parent="gen"]
|
||||||
|
margin_right = 40.0
|
||||||
|
margin_bottom = 40.0
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
|
[node name="gen_maps" type="VBoxContainer" parent="."]
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
margin_top = -16.0
|
||||||
|
margin_bottom = 16.0
|
||||||
|
__meta__ = {
|
||||||
|
"_edit_use_anchors_": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="gen_maps"]
|
||||||
|
margin_right = 1024.0
|
||||||
|
margin_bottom = 14.0
|
||||||
|
text = "Generating maps..."
|
||||||
|
|
||||||
|
[node name="ProgressBar" type="ProgressBar" parent="gen_maps"]
|
||||||
|
margin_top = 18.0
|
||||||
|
margin_right = 1024.0
|
||||||
|
margin_bottom = 32.0
|
||||||
Reference in New Issue
Block a user