-
Notifications
You must be signed in to change notification settings - Fork 0
/
extract.py
128 lines (102 loc) · 3.24 KB
/
extract.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python
"""Base on UnityPack's unityextract script"""
import os
import pickle
import sys
import glob
import unitypack
from unitypack.export import OBJMesh
from argparse import ArgumentParser
from PIL import ImageOps
import utils
from meshes import JSONMesh, BabylonMesh
EXCLUDES = ["sounds0"]
(debug, info, error) = utils.Echo.echo()
def handle_asset(asset, handle_formats, dir, flip, objMesh):
for id, obj in asset.objects.items():
try:
otype = obj.type
except Exception as e:
error("[Error] %s" % (e))
continue
if otype not in handle_formats:
continue
d = obj.read()
save_path = os.path.join(dir, obj.type, d.name)
utils.make_dirs(save_path)
if otype == "Mesh":
try:
mesh_data = None
if not objMesh:
mesh_data = BabylonMesh(d).export()
utils.write_to_file(save_path + ".babylon", mesh_data, mode="w")
mesh_data = OBJMesh(d).export()
utils.write_to_file(save_path + ".obj", mesh_data, mode="w")
except (NotImplementedError, RuntimeError) as e:
error("WARNING: Could not extract %r (%s)" % (d, e))
mesh_data = pickle.dumps(d._obj)
utils.write_to_file(save_path + ".Mesh.pickle", mesh_data, mode="wb")
elif otype == "TextAsset":
if isinstance(d.script, bytes):
utils.write_to_file(save_path + ".bin", d.script, mode="wb")
else:
utils.write_to_file(save_path + ".txt", d.script)
elif otype == "Texture2D":
filename = d.name + ".png"
try:
image = d.image
if image is None:
info("WARNING: %s is an empty image" % (filename))
utils.write_to_file(save_path + ".empty", "")
else:
info("Decoding %r" % (d))
img = image
if flip:
img = ImageOps.flip(image)
img.save(save_path + ".png")
except Exception as e:
error("Failed to extract texture %s (%s)" % (d.name, e))
def main():
p = ArgumentParser()
p.add_argument("files", nargs="+")
p.add_argument("--output", "-o", required=True)
p.add_argument("--all", action="store_true")
p.add_argument("--images", action="store_true")
p.add_argument("--models", action="store_true")
p.add_argument("--text", action="store_true")
p.add_argument("-q", action="store_true")
p.add_argument("-qq", action="store_true")
# flip images the "right" way up
p.add_argument("--flip", action="store_true")
# option for obj meshes (instead of js)
p.add_argument("--obj", action="store_true")
args = p.parse_args(sys.argv[1:])
utils.Echo.quiet = args.q
utils.Echo.very_quiet = args.qq
format_args = {
"images": "Texture2D",
"models": "Mesh",
"text": "TextAsset",
}
handle_formats = []
for a, classname in format_args.items():
if args.all or getattr(args, a):
handle_formats.append(classname)
files = args.files
if len(args.files) == 1:
if os.path.isdir(args.files[0]):
files = glob.glob(args.files[0] + "/*.unity3d")
for file in files:
bundle_name = utils.filename_no_ext(file)
if bundle_name in EXCLUDES:
info("Skipping %s..." % (bundle_name))
continue
info("Extracting %s..." % (bundle_name))
save_path = os.path.join(args.output, bundle_name)
with open(file, "rb") as f:
bundle = unitypack.load(f)
for asset in bundle.assets:
handle_asset(asset, handle_formats, save_path,
args.flip, args.obj, args.quiet)
if __name__ == "__main__":
main()