summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2022-12-20 14:20:17 -0800
committeryum <yum.food.vr@gmail.com>2022-12-20 14:20:17 -0800
commita048e2c1b1940805c0dcb29bc162f804ca463214 (patch)
tree3c8d35007fcc4e3470650b80db72a3ce3c04fa28
parent8d225cfd66dfb60998b4eab43d8aa3b287375695 (diff)
GUI can now generate animator
Still need to generate params & merge menus. Getting close....
-rw-r--r--GUI/GUI/GUI/PythonWrapper.cpp147
-rw-r--r--GUI/package.ps11
-rw-r--r--Scripts/generate_params.py1
-rw-r--r--Scripts/libtastt.py38
-rw-r--r--Scripts/libunity.py70
5 files changed, 226 insertions, 31 deletions
diff --git a/GUI/GUI/GUI/PythonWrapper.cpp b/GUI/GUI/GUI/PythonWrapper.cpp
index 62a002a..a2e1313 100644
--- a/GUI/GUI/GUI/PythonWrapper.cpp
+++ b/GUI/GUI/GUI/PythonWrapper.cpp
@@ -158,8 +158,43 @@ bool PythonWrapper::GenerateAnimator(
tastt_generated_dir_path / unity_parameters_generated_name;
std::filesystem::path tastt_menu_path =
tastt_generated_dir_path / unity_menu_generated_name;
+ // This is the initial, pre-merge FX controller.
+ std::filesystem::path tastt_fx0_path =
+ tastt_generated_dir_path / "FX0.controller";
+ std::filesystem::path tastt_fx1_path =
+ tastt_generated_dir_path / "FX1.controller";
+ std::filesystem::path tastt_fx2_path =
+ tastt_generated_dir_path / "FX2.controller";
+ std::filesystem::path tastt_fx3_path =
+ tastt_generated_dir_path / "FX3.controller";
{
+ if (std::filesystem::exists(tastt_generated_dir_path)) {
+ std::ostringstream oss;
+ oss << "Erasing " << tastt_generated_dir_path << std::endl;
+ out->AppendText(oss.str());
+ std::filesystem::remove_all(tastt_generated_dir_path);
+ }
+ std::ostringstream oss;
+ oss << "Creating " << tastt_generated_dir_path << std::endl;
+ out->AppendText(oss.str());
+ std::filesystem::create_directories(tastt_generated_dir_path);
+ }
+ {
+ out->AppendText("Copying canned animations... ");
+ auto opts = std::filesystem::copy_options();
+ opts |= std::filesystem::copy_options::overwrite_existing;
+ opts |= std::filesystem::copy_options::recursive;
+ std::error_code error;
+ std::filesystem::copy("Resources/Animations", tastt_animations_path, opts, error);
+ if (error.value()) {
+ wxLogError("Failed to copy animations: %s (%d)", error.message(), error.value());
+ out->AppendText("failed!\n");
+ return false;
+ }
+ out->AppendText("success!\n");
+ }
+ {
out->AppendText("Generating guid.map... ");
std::string py_stdout, py_stderr;
if (InvokeWithArgs({ libunity_path, "guid_map",
@@ -168,11 +203,18 @@ bool PythonWrapper::GenerateAnimator(
&py_stdout, &py_stderr)) {
out->AppendText("success!\n");
out->AppendText(py_stdout.c_str());
+ if (!py_stdout.empty()) {
+ out->AppendText("\n");
+ }
out->AppendText(py_stderr.c_str());
+ if (!py_stderr.empty()) {
+ out->AppendText("\n");
+ }
}
else {
wxLogError("Failed to generate guid.map: %s", py_stderr.c_str());
out->AppendText("failed!\n");
+ return false;
}
}
{
@@ -184,11 +226,116 @@ bool PythonWrapper::GenerateAnimator(
&py_stdout, &py_stderr)) {
out->AppendText("success!\n");
out->AppendText(py_stdout.c_str());
+ if (!py_stdout.empty()) {
+ out->AppendText("\n");
+ }
out->AppendText(py_stderr.c_str());
+ if (!py_stderr.empty()) {
+ out->AppendText("\n");
+ }
}
else {
wxLogError("Failed to generate animations: %s", py_stderr.c_str());
out->AppendText("failed!\n");
+ return false;
+ }
+ }
+ {
+ out->AppendText("Generating FX layer... ");
+ std::string py_stdout, py_stderr;
+ if (InvokeWithArgs({ libtastt_path, "gen_fx",
+ "--fx_dest", tastt_fx0_path.string(),
+ "--gen_anim_dir", tastt_animations_path.string(),
+ "--guid_map", guid_map_path.string() },
+ &py_stdout, &py_stderr)) {
+ out->AppendText("success!\n");
+ out->AppendText(py_stdout.c_str());
+ if (!py_stdout.empty()) {
+ out->AppendText("\n");
+ }
+ out->AppendText(py_stderr.c_str());
+ if (!py_stderr.empty()) {
+ out->AppendText("\n");
+ }
+ }
+ else {
+ wxLogError("Failed to generate FX layer: %s", py_stderr.c_str());
+ out->AppendText("failed!\n");
+ return false;
+ }
+ }
+ {
+ out->AppendText("Adding enable/disable toggle... ");
+ std::string py_stdout, py_stderr;
+ if (InvokeWithArgs({ libunity_path, "add_toggle",
+ "--fx0", tastt_fx0_path.string(),
+ "--fx_dest", tastt_fx1_path.string(),
+ "--gen_anim_dir", tastt_animations_path.string(),
+ "--guid_map", guid_map_path.string() },
+ &py_stdout, &py_stderr)) {
+ out->AppendText("success!\n");
+ out->AppendText(py_stdout.c_str());
+ if (!py_stdout.empty()) {
+ out->AppendText("\n");
+ }
+ out->AppendText(py_stderr.c_str());
+ if (!py_stderr.empty()) {
+ out->AppendText("\n");
+ }
+ }
+ else {
+ wxLogError("Failed to add enable/disable toggle: %s", py_stderr.c_str());
+ out->AppendText("failed!\n");
+ return false;
+ }
+ }
+ {
+ out->AppendText("Merging with user animator... ");
+ std::string py_stdout, py_stderr;
+ if (InvokeWithArgs({ libunity_path, "merge",
+ "--fx0", unity_animator_path,
+ "--fx1", tastt_fx1_path.string(),
+ "--fx_dest", tastt_fx2_path.string() },
+ &py_stdout, &py_stderr)) {
+ out->AppendText("success!\n");
+ out->AppendText(py_stdout.c_str());
+ if (!py_stdout.empty()) {
+ out->AppendText("\n");
+ }
+ out->AppendText(py_stderr.c_str());
+ if (!py_stderr.empty()) {
+ out->AppendText("\n");
+ }
+ }
+ else {
+ wxLogError("Failed to merge animators: %s", py_stderr.c_str());
+ out->AppendText("failed!\n");
+ return false;
+ }
+ }
+ {
+ out->AppendText("Setting noop animations... ");
+ std::string py_stdout, py_stderr;
+ if (InvokeWithArgs({ libunity_path, "set_noop_anim",
+ "--fx0", tastt_fx2_path.string(),
+ "--fx_dest", tastt_fx3_path.string(),
+ "--gen_anim_dir", tastt_animations_path.string(),
+ "--guid_map", guid_map_path.string() },
+ &py_stdout, &py_stderr)) {
+ out->AppendText("success!\n");
+ out->AppendText(py_stdout.c_str());
+ if (!py_stdout.empty()) {
+ out->AppendText("\n");
+ }
+ out->AppendText(py_stderr.c_str());
+ if (!py_stderr.empty()) {
+ out->AppendText("\n");
+ }
+ }
+ else {
+ wxLogError("Failed to set noop animations: %s", py_stderr.c_str());
+ out->AppendText("failed!\n");
+ return false;
}
}
diff --git a/GUI/package.ps1 b/GUI/package.ps1
index 703518a..fc51b41 100644
--- a/GUI/package.ps1
+++ b/GUI/package.ps1
@@ -6,6 +6,7 @@ if (Test-Path $install_dir) {
mkdir $install_dir > $null
mkdir $install_dir/Resources > $null
+cp -Recurse ../Animations TaSTT/Resources/Animations
cp -Recurse ../Images TaSTT/Resources/Images
cp -Recurse ../Python TaSTT/Resources/Python
cp -Recurse ../Scripts TaSTT/Resources/Scripts
diff --git a/Scripts/generate_params.py b/Scripts/generate_params.py
index 323502c..0444780 100644
--- a/Scripts/generate_params.py
+++ b/Scripts/generate_params.py
@@ -89,3 +89,4 @@ for byte in range(0, generate_utils.BYTES_PER_CHAR):
for i in range(0, generate_utils.NUM_LAYERS):
params["PARAM_NAME"] = generate_utils.getBlendParam(i, byte)
print(generate_utils.replaceMacros(FLOAT_PARAM, params))
+
diff --git a/Scripts/libtastt.py b/Scripts/libtastt.py
index f448117..cc9c751 100644
--- a/Scripts/libtastt.py
+++ b/Scripts/libtastt.py
@@ -419,7 +419,8 @@ def generateToggle(layer_name: str,
gen_anim_dir: str,
off_anim_basename: str,
on_anim_basename: str,
- anim: libunity.UnityAnimator) -> typing.Dict[str,
+ anim: libunity.UnityAnimator,
+ guid_map: typing.Dict[str, str]) -> typing.Dict[str,
libunity.UnityDocument]:
layer = anim.addLayer(layer_name)
@@ -434,13 +435,13 @@ def generateToggle(layer_name: str,
if off_anim_basename:
off_anim_path = os.path.join(gen_anim_dir, off_anim_basename)
off_anim_meta = libunity.Metadata()
- off_anim_meta.load(off_anim_path)
+ off_anim_meta.loadOrCreate(off_anim_path, guid_map)
anim.setAnimatorStateAnimation(off_state, off_anim_meta.guid)
if on_anim_basename:
on_anim_path = os.path.join(gen_anim_dir, on_anim_basename)
on_anim_meta = libunity.Metadata()
- on_anim_meta.load(on_anim_path)
+ on_anim_meta.loadOrCreate(on_anim_path, guid_map)
anim.setAnimatorStateAnimation(on_state, on_anim_meta.guid)
off_to_on_trans = anim.addTransition(on_state)
@@ -496,10 +497,10 @@ def generateFX(guid_map, gen_anim_dir):
states = generateToggle(
generate_utils.getSpeechNoiseToggleParam(),
- "Animations/",
+ gen_anim_dir,
"TaSTT_Speech_Noise_Off.anim",
"TaSTT_Speech_Noise_On.anim",
- anim)
+ anim, guid_map)
# Enable beeping only if user has turned it on.
anim.addTransitionBooleanCondition(states["off"],
states["off_to_on"], generate_utils.getSpeechNoiseEnableParam(), True)
@@ -508,31 +509,31 @@ def generateFX(guid_map, gen_anim_dir):
states["off_to_on"], generate_utils.getToggleParam(), True)
generateToggle(generate_utils.getToggleParam(),
- "Animations/",
+ gen_anim_dir,
"TaSTT_Toggle_Off.anim",
"TaSTT_Toggle_On.anim",
- anim)
+ anim, guid_map)
generateToggle(generate_utils.getLockWorldParam(),
- "Animations/",
+ gen_anim_dir,
"TaSTT_Lock_World_Disable.anim",
"TaSTT_Lock_World_Enable.anim",
- anim)
+ anim, guid_map)
generateToggle(
generate_utils.getClearBoardParam(),
gen_anim_dir,
None, # No animation in the `off` state.
generate_utils.getClearAnimationName() + ".anim",
- anim)
+ anim, guid_map)
generateToggle(generate_utils.getIndicator0Param(),
gen_anim_dir,
generate_utils.getIndicator0Param() + "_Off.anim",
generate_utils.getIndicator0Param() + "_On.anim",
- anim)
+ anim, guid_map)
generateToggle(generate_utils.getIndicator1Param(),
gen_anim_dir,
generate_utils.getIndicator1Param() + "_Off.anim",
generate_utils.getIndicator1Param() + "_On.anim",
- anim)
+ anim, guid_map)
generateScaleLayer(anim, gen_anim_dir, guid_map)
return anim
@@ -545,6 +546,7 @@ def parseArgs():
parser.add_argument("--gen_anim_dir", type=str, help="The directory under " +
"which all generated animations are placed.")
parser.add_argument("--guid_map", type=str, help="The path to a file which will store guids")
+ parser.add_argument("--fx_dest", type=str, help="The path at which to save the generated FX controller")
args = parser.parse_args()
if not args.gen_dir:
@@ -556,9 +558,14 @@ def parseArgs():
if not args.guid_map:
args.guid_map = "guid.map"
+ if not args.fx_dest:
+ args.fx_dest = args.gen_dir + "TaSTT_fx.controller"
+
return args
if __name__ == "__main__":
+ os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
args = parseArgs()
if args.cmd == "gen_anims":
@@ -575,6 +582,9 @@ if __name__ == "__main__":
guid_map = {}
with open(args.guid_map, 'rb') as f:
guid_map = pickle.load(f)
-
- print(str(generateFX(guid_map, args.gen_anim_dir)))
+ os.makedirs(os.path.dirname(args.fx_dest), exist_ok=True)
+ with open(args.fx_dest, "w") as f:
+ f.write(str(generateFX(guid_map, args.gen_anim_dir)))
+ with open(args.guid_map, 'wb') as f:
+ pickle.dump(guid_map, f)
diff --git a/Scripts/libunity.py b/Scripts/libunity.py
index 7223568..0c5228a 100644
--- a/Scripts/libunity.py
+++ b/Scripts/libunity.py
@@ -228,6 +228,23 @@ class Metadata:
if line.startswith("guid"):
self.guid = line.split()[1]
+ def loadOrCreate(self, path, guid_map):
+ if not path.endswith(".meta"):
+ path = path + ".meta"
+
+ if os.path.exists(path):
+ self.load(path)
+ return
+
+ self.persist(path, guid_map)
+
+ def persist(self, path, guid_map):
+ with open(path, "w") as f:
+ f.write(str(self))
+
+ guid_map[self.guid] = path
+ guid_map[path] = self.guid
+
def __str__(self):
return METADATA_TEMPLATE.replace("REPLACEME_GUID", self.guid)
@@ -911,14 +928,15 @@ class UnityAnimator():
from_state_trans.mapping['fileID'] = trans.anchor
# TODO(yum) this should be factored out into generate_fx.py
- def addTasttToggle(self, off_anim_path, on_anim_path, toggle_param):
+ def addTasttToggle(self, off_anim_path, on_anim_path, toggle_param,
+ guid_map):
self.addParameter(toggle_param, bool)
off_anim_meta = Metadata()
- off_anim_meta.load(off_anim_path)
+ off_anim_meta.loadOrCreate(off_anim_path, guid_map)
on_anim_meta = Metadata()
- on_anim_meta.load(on_anim_path)
+ on_anim_meta.loadOrCreate(on_anim_path, guid_map)
layer = self.addLayer('TaSTT_Toggle')
off_anim = self.addAnimatorState(layer, 'TaSTT_Toggle_Off', is_default_state = True)
@@ -936,7 +954,7 @@ class UnityAnimator():
def setNoopAnimations(self, guid_map, noop_anim_path):
noop_anim_meta = Metadata()
- noop_anim_meta.load(noop_anim_path)
+ noop_anim_meta.loadOrCreate(noop_anim_path, guid_map)
for node in self.nodes:
if node.class_id != "1102":
@@ -1215,10 +1233,14 @@ def getGuidMap(d):
return result
if __name__ == "__main__":
+ os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
parser = argparse.ArgumentParser()
parser.add_argument("cmd", type=str, help="One of merge, guid_map, fix_write_defaults")
parser.add_argument("--fx0", type=str, help="The first animator to merge")
parser.add_argument("--fx1", type=str, help="The second animator to merge")
+ parser.add_argument("--fx_dest", type=str, help="The path at which to " +
+ "save the generated/merged animator")
parser.add_argument("--project_root", type=str, help="The path to the " +
"Unity project Assets folder")
parser.add_argument("--save_to", type=str, help="The path to save the " +
@@ -1227,11 +1249,12 @@ if __name__ == "__main__":
"generated by a previous call to `guid_map`")
parser.add_argument("--guid_map_append", type=bool, help="If set, " +
"append to GUID map instead of overwriting.")
+ parser.add_argument("--gen_anim_dir", type=str, help="The folder under which generated animations are stored")
args = parser.parse_args()
if args.cmd == "merge":
- if not args.fx0 or not args.fx1:
- print("--fx0 and --fx1 required", file=sys.stderr)
+ if not args.fx0 or not args.fx1 or not args.fx_dest:
+ print("--fx0, --fx1, and --fx_dest required", file=sys.stderr)
parser.print_help()
parser.exit(1)
@@ -1247,8 +1270,9 @@ if __name__ == "__main__":
print("Merging animators", file=sys.stderr)
anim0.merge(anim1)
- print("Serializing", file=sys.stderr)
- print(unityYamlToString(anim0.nodes))
+ print("Serializing to {}".format(args.fx_dest), file=sys.stderr)
+ with open(args.fx_dest, "w") as f:
+ f.write(unityYamlToString(anim0.nodes))
elif args.cmd == "guid_map":
if not args.project_root or not args.save_to:
@@ -1312,19 +1336,30 @@ if __name__ == "__main__":
anim.generateOffAnimations(guid_map, "generated/animations")
elif args.cmd == "add_toggle":
- if not args.fx0:
- print("--fx0 required")
+ if not args.fx0 or not args.fx_dest or not args.gen_anim_dir or not args.guid_map:
+ print("--fx0, --fx_dest, --gen_anim_dir and --guid_map required")
parser.print_help()
parser.exit(1)
+ guid_map = {}
+ with open(args.guid_map, 'rb') as f:
+ guid_map = pickle.load(f)
+
print("Parsing {}".format(args.fx0), file=sys.stderr)
parser0 = MulticoreUnityParser()
anim = parser0.parseFile(args.fx0)
print("Adding toggle", file=sys.stderr)
- anim.addTasttToggle("Animations/TaSTT_Toggle_Off.anim",
- "Animations/TaSTT_Toggle_On.anim", "TaSTT_Toggle")
- print(str(anim))
+ anim.addTasttToggle(args.gen_anim_dir + "/TaSTT_Toggle_Off.anim",
+ args.gen_anim_dir + "/TaSTT_Toggle_On.anim", "TaSTT_Toggle",
+ guid_map)
+
+ print("Serializing to {}".format(args.fx_dest), file=sys.stderr)
+ with open(args.fx_dest, "w") as f:
+ f.write(str(anim))
+
+ with open(args.guid_map, 'wb') as f:
+ pickle.dump(guid_map, f)
elif args.cmd == "fast_parse_test":
if not args.fx0:
@@ -1338,8 +1373,8 @@ if __name__ == "__main__":
print(str(anim))
elif args.cmd == "set_noop_anim":
- if not args.fx0 or not args.guid_map:
- print("--fx0 and --guid_map required")
+ if not args.fx0 or not args.fx_dest or not args.gen_anim_dir or not args.guid_map:
+ print("--fx0, --fx_dest, --gen_anim_dir and --guid_map required")
parser.print_help()
parser.exit(1)
@@ -1351,9 +1386,10 @@ if __name__ == "__main__":
parser = MulticoreUnityParser()
anim = parser.parseFile(args.fx0)
- anim.setNoopAnimations(guid_map, "Animations/TaSTT_Do_Nothing.anim")
+ anim.setNoopAnimations(guid_map, args.gen_anim_dir + "/TaSTT_Do_Nothing.anim")
- print(str(anim))
+ with open(args.fx_dest, "w") as f:
+ f.write(str(anim))
else:
print("Unrecognized command: {}".format(args.cmd))