summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--TaSTT.cs78
-rw-r--r--TaSTT.shader40
-rw-r--r--TaSTT_params.asset31
-rw-r--r--cell_names.txt84
-rw-r--r--generate_fx.py574
-rw-r--r--generate_params.py61
-rw-r--r--generate_utils.py53
-rw-r--r--group_names.txt24
-rw-r--r--osc_ctrl.py103
10 files changed, 504 insertions, 550 deletions
diff --git a/README.md b/README.md
index 986ca8b..4a6ce42 100644
--- a/README.md
+++ b/README.md
@@ -13,12 +13,6 @@ Features:
* Low-latency.
* Stable.
* Configurable.
-* Very low parameter space usage: 25 bits at the time of writing.
- * u8 TaSTT\_Letter: the letter to write at the current position
- * u8 TaSTT\_Row: the row to write on.
- * u8 TaSTT\_Col: the col to write on.
- * bool TaSTT\_Active: whether or not to overwrite (turn this off while seeking
- to a new spot).
* 6x14 display grid, 80 characters per slot.
* Each parameter - grid size, characters per slot, may be dialed up or down
as desired.
diff --git a/TaSTT.cs b/TaSTT.cs
deleted file mode 100644
index d9901d6..0000000
--- a/TaSTT.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEditor;
-using UnityEditor.Animations;
-using UnityEngine;
-using VRC.SDK3.Avatars.Components;
-using VRC.SDK3.Avatars.ScriptableObjects;
-
-namespace TaSTT
-{
- public class TaSTT : EditorWindow
- {
- private static TaSTT instance_;
- private GameObject avatar_root_;
- private AnimatorController fx_controller_;
-
- [MenuItem("Window/TaSTT")]
- private static void ShowWindow()
- {
- instance_ = GetWindow<TaSTT>();
- instance_.titleContent = new GUIContent("TaSTT");
- }
-
- private void Draw()
- {
- GUILayout.Label("TaSTT: A free VRChat STT");
- GUILayout.Label("Made with love by yum_food");
- GUILayout.Label("");
-
- avatar_root_ = (GameObject)EditorGUILayout.ObjectField(
- new GUIContent("Avatar Root"), avatar_root_,
- typeof(GameObject), true);
- fx_controller_ = (AnimatorController)EditorGUILayout.ObjectField(
- new GUIContent("FX Controller"), fx_controller_,
- typeof(AnimatorController), true);
-
- if (GUILayout.Button("Create animations!"))
- {
- if (avatar_root_ == null || !fx_controller_ == null)
- {
- // TODO(yum_food) why doesn't EditorGUILayout.HelpBox() work here?
- Debug.LogError("Avatar root or FX controller are not set! Cannot create animations.");
- return;
- }
- // TODO(yum_food)
- }
- if (GUILayout.Button("Create FX layer!"))
- {
- if (!avatar_root_ == null || !fx_controller_ == null)
- {
- Debug.LogError("Avatar root or FX controller are not set! Cannot create FX layer.");
- return;
- }
- // TODO(yum_food)
- }
- }
-
- private static void CreateAnimations()
- {
- VRCAvatarDescriptor descriptor = avatar_root_.GetComponent<VRCAvatarDescriptor>();
- if (descriptor == null)
- {
- Debug.LogError("Failed to get avatar descriptor");
- return;
- }
- AnimationClip anim = new AnimationClip();
- clip.frameRate = 1f;
- }
-
- private void OnGUI()
- {
- if (instance_ != null)
- {
- Draw();
- }
- }
- }
-}
diff --git a/TaSTT.shader b/TaSTT.shader
index 8f18dae..f5ec6af 100644
--- a/TaSTT.shader
+++ b/TaSTT.shader
@@ -74,20 +74,20 @@
_Letter_Row04_Col11("_Letter_Row04_Col11", float) = 0
_Letter_Row04_Col12("_Letter_Row04_Col12", float) = 0
_Letter_Row04_Col13("_Letter_Row04_Col13", float) = 0
- _Letter_Row03_Col00("_Letter_Row03_Col00", float) = 0
- _Letter_Row03_Col01("_Letter_Row03_Col01", float) = 0
- _Letter_Row03_Col02("_Letter_Row03_Col02", float) = 0
- _Letter_Row03_Col03("_Letter_Row03_Col03", float) = 0
- _Letter_Row03_Col04("_Letter_Row03_Col04", float) = 0
- _Letter_Row03_Col05("_Letter_Row03_Col05", float) = 0
- _Letter_Row03_Col06("_Letter_Row03_Col06", float) = 0
- _Letter_Row03_Col07("_Letter_Row03_Col07", float) = 0
- _Letter_Row03_Col08("_Letter_Row03_Col08", float) = 0
- _Letter_Row03_Col09("_Letter_Row03_Col09", float) = 0
- _Letter_Row03_Col10("_Letter_Row03_Col10", float) = 0
- _Letter_Row03_Col11("_Letter_Row03_Col11", float) = 0
- _Letter_Row03_Col12("_Letter_Row03_Col12", float) = 0
- _Letter_Row03_Col13("_Letter_Row03_Col13", float) = 0
+ _Letter_Row05_Col00("_Letter_Row05_Col00", float) = 0
+ _Letter_Row05_Col01("_Letter_Row05_Col01", float) = 0
+ _Letter_Row05_Col02("_Letter_Row05_Col02", float) = 0
+ _Letter_Row05_Col03("_Letter_Row05_Col03", float) = 0
+ _Letter_Row05_Col04("_Letter_Row05_Col04", float) = 0
+ _Letter_Row05_Col05("_Letter_Row05_Col05", float) = 0
+ _Letter_Row05_Col06("_Letter_Row05_Col06", float) = 0
+ _Letter_Row05_Col07("_Letter_Row05_Col07", float) = 0
+ _Letter_Row05_Col08("_Letter_Row05_Col08", float) = 0
+ _Letter_Row05_Col09("_Letter_Row05_Col09", float) = 0
+ _Letter_Row05_Col10("_Letter_Row05_Col10", float) = 0
+ _Letter_Row05_Col11("_Letter_Row05_Col11", float) = 0
+ _Letter_Row05_Col12("_Letter_Row05_Col12", float) = 0
+ _Letter_Row05_Col13("_Letter_Row05_Col13", float) = 0
}
SubShader
{
@@ -268,7 +268,7 @@
float CHAR_ROW = floor(i.uv.y * CHAR_ROWS);
// ok now this is epic
- if (CHAR_ROW == 0) {
+ if (CHAR_ROW == 5) {
if (CHAR_COL == 0) {
return _Letter_Row00_Col00;
} else if (CHAR_COL == 1) {
@@ -298,7 +298,7 @@
} else if (CHAR_COL == 13) {
return _Letter_Row00_Col13;
}
- } else if (CHAR_ROW == 1) {
+ } else if (CHAR_ROW == 4) {
if (CHAR_COL == 0) {
return _Letter_Row01_Col00;
} else if (CHAR_COL == 1) {
@@ -328,7 +328,7 @@
} else if (CHAR_COL == 13) {
return _Letter_Row01_Col13;
}
- } else if (CHAR_ROW == 2) {
+ } else if (CHAR_ROW == 3) {
if (CHAR_COL == 0) {
return _Letter_Row02_Col00;
} else if (CHAR_COL == 1) {
@@ -358,7 +358,7 @@
} else if (CHAR_COL == 13) {
return _Letter_Row02_Col13;
}
- } else if (CHAR_ROW == 3) {
+ } else if (CHAR_ROW == 2) {
if (CHAR_COL == 0) {
return _Letter_Row03_Col00;
} else if (CHAR_COL == 1) {
@@ -388,7 +388,7 @@
} else if (CHAR_COL == 13) {
return _Letter_Row03_Col13;
}
- } else if (CHAR_ROW == 4) {
+ } else if (CHAR_ROW == 1) {
if (CHAR_COL == 0) {
return _Letter_Row04_Col00;
} else if (CHAR_COL == 1) {
@@ -418,7 +418,7 @@
} else if (CHAR_COL == 13) {
return _Letter_Row04_Col13;
}
- } else if (CHAR_ROW == 5) {
+ } else if (CHAR_ROW == 0) {
if (CHAR_COL == 0) {
return _Letter_Row05_Col00;
} else if (CHAR_COL == 1) {
diff --git a/TaSTT_params.asset b/TaSTT_params.asset
deleted file mode 100644
index 4c79902..0000000
--- a/TaSTT_params.asset
+++ /dev/null
@@ -1,31 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!114 &11400000
-MonoBehaviour:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 0}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: -1506855854, guid: 67cc4cb7839cd3741b63733d5adf0442, type: 3}
- m_Name: TaSTT_params
- m_EditorClassIdentifier:
- parameters:
- - name: TaSTT_Letter
- valueType: 0
- saved: 0
- defaultValue: 0
- - name: TaSTT_Row
- valueType: 0
- saved: 0
- defaultValue: 0
- - name: TaSTT_Col
- valueType: 0
- saved: 0
- defaultValue: 0
- - name: TaSTT_Active
- valueType: 2
- saved: 0
- defaultValue: 0
diff --git a/cell_names.txt b/cell_names.txt
deleted file mode 100644
index 1000cd1..0000000
--- a/cell_names.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-_Letter_Row00_Col00
-_Letter_Row00_Col01
-_Letter_Row00_Col02
-_Letter_Row00_Col03
-_Letter_Row00_Col04
-_Letter_Row00_Col05
-_Letter_Row00_Col06
-_Letter_Row00_Col07
-_Letter_Row00_Col08
-_Letter_Row00_Col09
-_Letter_Row00_Col10
-_Letter_Row00_Col11
-_Letter_Row00_Col12
-_Letter_Row00_Col13
-_Letter_Row01_Col00
-_Letter_Row01_Col01
-_Letter_Row01_Col02
-_Letter_Row01_Col03
-_Letter_Row01_Col04
-_Letter_Row01_Col05
-_Letter_Row01_Col06
-_Letter_Row01_Col07
-_Letter_Row01_Col08
-_Letter_Row01_Col09
-_Letter_Row01_Col10
-_Letter_Row01_Col11
-_Letter_Row01_Col12
-_Letter_Row01_Col13
-_Letter_Row02_Col00
-_Letter_Row02_Col01
-_Letter_Row02_Col02
-_Letter_Row02_Col03
-_Letter_Row02_Col04
-_Letter_Row02_Col05
-_Letter_Row02_Col06
-_Letter_Row02_Col07
-_Letter_Row02_Col08
-_Letter_Row02_Col09
-_Letter_Row02_Col10
-_Letter_Row02_Col11
-_Letter_Row02_Col12
-_Letter_Row02_Col13
-_Letter_Row03_Col00
-_Letter_Row03_Col01
-_Letter_Row03_Col02
-_Letter_Row03_Col03
-_Letter_Row03_Col04
-_Letter_Row03_Col05
-_Letter_Row03_Col06
-_Letter_Row03_Col07
-_Letter_Row03_Col08
-_Letter_Row03_Col09
-_Letter_Row03_Col10
-_Letter_Row03_Col11
-_Letter_Row03_Col12
-_Letter_Row03_Col13
-_Letter_Row04_Col00
-_Letter_Row04_Col01
-_Letter_Row04_Col02
-_Letter_Row04_Col03
-_Letter_Row04_Col04
-_Letter_Row04_Col05
-_Letter_Row04_Col06
-_Letter_Row04_Col07
-_Letter_Row04_Col08
-_Letter_Row04_Col09
-_Letter_Row04_Col10
-_Letter_Row04_Col11
-_Letter_Row04_Col12
-_Letter_Row04_Col13
-_Letter_Row05_Col00
-_Letter_Row05_Col01
-_Letter_Row05_Col02
-_Letter_Row05_Col03
-_Letter_Row05_Col04
-_Letter_Row05_Col05
-_Letter_Row05_Col06
-_Letter_Row05_Col07
-_Letter_Row05_Col08
-_Letter_Row05_Col09
-_Letter_Row05_Col10
-_Letter_Row05_Col11
-_Letter_Row05_Col12
-_Letter_Row05_Col13
diff --git a/generate_fx.py b/generate_fx.py
index ba1d590..28d6550 100644
--- a/generate_fx.py
+++ b/generate_fx.py
@@ -15,10 +15,18 @@
# where we're transitioning to.
# 12. %TRANSITION_THRESHOLD% - the threshold to use when transitioning.
+from generate_utils import replaceMacros
+from generate_utils import getDummyParam
+from generate_utils import getLayerParam
+from generate_utils import getSelectParam
+from generate_utils import getEnableParam
+from generate_utils import getShaderParam
+from generate_utils import getAnimationPath
+from generate_utils import NUM_LAYERS
+from generate_utils import CHARS_PER_CELL
+
# To debug, I recommend setting these values low and manually moving things
# around in the animator. Then run using Lyuma's avatar 3.0 emulator.
-NUM_ROWS=6
-NUM_COLS=14
NUM_LETTERS=80
params = {}
@@ -34,33 +42,20 @@ def get_u2(class_id, state):
# These !u! and & numbers are, respectively, a class ID and an instance ID.
# The instance ID begins with the class ID then has a 5-digit suffix.
params["ANIMATOR_CONTROLLER_U"] = "91"
-params["ANIMATOR_HEADER_U2"] = "9100000" # this is a special value
+params["ANIMATOR_HEADER_U2"] = "9100000"
params["ANIMATOR_STATE_MACHINE_U"] = "1107"
-params["TASTT_LAYER_U2"] = get_u2("1107", state)
params["MONO_BEHAVIOUR_U"] = "114"
-params["SET_LETTERS_SCRIPT_U2"] = get_u2("114", state)
params["ANIMATOR_STATE_U"] = "1102"
-params["TASTT_DEFAULT_STATE_U2"] = get_u2("1102", state)
-params["TASTT_ACTIVE_STATE_U2"] = get_u2("1102", state)
params["ANIMATOR_STATE_TRANSITION_U"] = "1101"
-params["TASTT_ACTIVE_STATE_TRANSITION_U2"] = get_u2("1101", state)
-params["TASTT_RESTART_TRANSITION_U2"] = get_u2("1101", state)
HEADER="""
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
-"""[1:]
-
-# Generates the sed cmd args required to replace all parameters defined in
-# $1, which is an associative array like `params`.
-def replaceMacros(lines, macro_defs):
- for k,v in macro_defs.items():
- lines = lines.replace("%" + k + "%", v)
- return lines
+"""[1:][:-1]
def genHeader():
return replaceMacros(HEADER, params)
@@ -75,11 +70,11 @@ AnimatorController:
m_PrefabAsset: {fileID: 0}
m_Name: TaSTT_fx
serializedVersion: 5
-"""[1:]
+"""[1:][:-1]
ANIMATOR_PARAMETER_HEADER = """
m_AnimatorParameters:
-"""[1:]
+"""[1:][:-1]
ANIMATOR_PARAMETER_INT = """
- m_Name: %ANIMATOR_PARAMETER_NAME%
@@ -88,7 +83,7 @@ ANIMATOR_PARAMETER_INT = """
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
-"""[1:]
+"""[1:][:-1]
ANIMATOR_PARAMETER_BOOL = """
- m_Name: %ANIMATOR_PARAMETER_NAME%
@@ -97,42 +92,26 @@ ANIMATOR_PARAMETER_BOOL = """
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 0}
-"""[1:]
+"""[1:][:-1]
ANIMATOR_LAYER_HEADER = """
m_AnimatorLayers:
-"""[1:]
+"""[1:][:-1]
-# We have a single animator layer which does everything.
ANIMATOR_LAYER_TASTT = """
- serializedVersion: 5
- m_Name: TaSTT
+ m_Name: %TASTT_LAYER_NAME%
m_StateMachine: {fileID: %TASTT_LAYER_U2%}
m_Mask: {fileID: 0}
m_Motions: []
m_Behaviours: []
m_BlendingMode: 0
m_SyncedLayerIndex: -1
- m_DefaultWeight: 0
- m_IKPass: 0
- m_SyncedLayerAffectsTiming: 0
- m_Controller: {fileID: %ANIMATOR_HEADER_U2%}
-"""[1:]
-
-ANIMATOR_LAYER_CELL_ANIM = """
- - serializedVersion: 5
- m_Name: %LAYER_NAME%
- m_StateMachine: {fileID: %LAYER_STATE_MACHINE_U2%}
- m_Mask: {fileID: 0}
- m_Motions: []
- m_Behaviours: []
- m_BlendingMode: 0
- m_SyncedLayerIndex: -1
m_DefaultWeight: 1
m_IKPass: 0
m_SyncedLayerAffectsTiming: 0
m_Controller: {fileID: %ANIMATOR_HEADER_U2%}
-"""[1:]
+"""[1:][:-1]
GROUP_NAMES = [
"_Letter_Row00_Col00_03",
@@ -252,19 +231,33 @@ def genAnimator(state):
print(replaceMacros(ANIMATOR_HEADER, params))
print(ANIMATOR_PARAMETER_HEADER)
- params["ANIMATOR_PARAMETER_NAME"] = "TaSTT_Letter"
- print(replaceMacros(ANIMATOR_PARAMETER_INT, params))
- params["ANIMATOR_PARAMETER_NAME"] = "TaSTT_Row"
- print(replaceMacros(ANIMATOR_PARAMETER_INT, params))
- params["ANIMATOR_PARAMETER_NAME"] = "TaSTT_Col"
- print(replaceMacros(ANIMATOR_PARAMETER_INT, params))
- params["ANIMATOR_PARAMETER_NAME"] = "TaSTT_Active"
- print(replaceMacros(ANIMATOR_PARAMETER_BOOL, params))
- params["ANIMATOR_PARAMETER_NAME"] = "TaSTT_Dummy"
+ params["ANIMATOR_PARAMETER_NAME"] = getDummyParam()
print(replaceMacros(ANIMATOR_PARAMETER_BOOL, params))
+ for i in range(0, NUM_LAYERS):
+ params["ANIMATOR_PARAMETER_NAME"] = getLayerParam(i)
+ print(replaceMacros(ANIMATOR_PARAMETER_INT, params))
+
+ params["ANIMATOR_PARAMETER_NAME"] = getSelectParam(i, 0)
+ print(replaceMacros(ANIMATOR_PARAMETER_BOOL, params))
+
+ params["ANIMATOR_PARAMETER_NAME"] = getSelectParam(i, 1)
+ print(replaceMacros(ANIMATOR_PARAMETER_BOOL, params))
+
+ params["ANIMATOR_PARAMETER_NAME"] = getSelectParam(i, 2)
+ print(replaceMacros(ANIMATOR_PARAMETER_BOOL, params))
+
+ params["ANIMATOR_PARAMETER_NAME"] = getEnableParam(i)
+ print(replaceMacros(ANIMATOR_PARAMETER_BOOL, params))
+
+
print(replaceMacros(ANIMATOR_LAYER_HEADER, params))
- print(replaceMacros(ANIMATOR_LAYER_TASTT, params))
+
+ for i in range(0, NUM_LAYERS):
+ params[getLayerParam(i) + "_LAYER_U2"] = get_u2("1107", state)
+ params["TASTT_LAYER_U2"] = params[getLayerParam(i) + "_LAYER_U2"]
+ params["TASTT_LAYER_NAME"] = getLayerParam(i)
+ print(replaceMacros(ANIMATOR_LAYER_TASTT, params))
genAnimator(state)
TASTT_LAYER_HEADER = """
@@ -275,15 +268,15 @@ AnimatorStateMachine:
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_Name: TaSTT
+ m_Name: %TASTT_LAYER_NAME%
m_ChildStates:
-"""[1:]
+"""[1:][:-1]
TASTT_LAYER_HEADER_CHILD_STATE = """
- serializedVersion: 1
m_State: {fileID: %TASTT_STATE_U2%}
m_Position: {x: 330, y: -60, z: 0}
-"""[1:]
+"""[1:][:-1]
TASTT_LAYER_FOOTER = """
m_ChildStateMachines: []
@@ -296,23 +289,26 @@ TASTT_LAYER_FOOTER = """
m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: %TASTT_DEFAULT_STATE_U2%}
-"""[1:]
+"""[1:][:-1]
-# Default state.
-# One transition to TaSTT_Active.
-TASTT_DEFAULT_STATE = """
---- !u!%ANIMATOR_STATE_U% &%TASTT_DEFAULT_STATE_U2%
+# State with one transition.
+# Params:
+# %TASTT_STATE_NAME%: the name of this state
+# %TASTT_STATE_TRANSITION_U2%: the U2 of the transition to the next state
+# %TASTT_STATE_TRANSITION_U2%
+TASTT_UNARY_STATE = """
+--- !u!%ANIMATOR_STATE_U% &%TASTT_STATE_U2%
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_Name: TaSTT_Do_Nothing
+ m_Name: %TASTT_STATE_NAME%
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- - {fileID: %TASTT_ACTIVE_STATE_TRANSITION_U2%}
+ - {fileID: %TASTT_STATE_TRANSITION_U2%}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@@ -328,61 +324,28 @@ AnimatorState:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
-"""[1:]
+"""[1:][:-1]
-# Transition from TaSTT_Do_nothing. to TaSTT_Active.
+# State with two transitions.
# Params:
-# %TASTT_ACTIVE_STATE_TRANSITION_U2%
-# %TASTT_ROW_STATE_U2% - address of row state we're transitioning to
-TASTT_ACTIVE_STATE_TRANSITION = """
---- !u!1101 &%TASTT_ACTIVE_STATE_TRANSITION_U2%
-AnimatorStateTransition:
- m_ObjectHideFlags: 1
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_Name:
- m_Conditions:
- - m_ConditionMode: 1
- m_ConditionEvent: TaSTT_Active
- m_EventTreshold: 1
- m_DstStateMachine: {fileID: 0}
- m_DstState: {fileID: %TASTT_ACTIVE_STATE_U2%}
- m_Solo: 0
- m_Mute: 0
- m_IsExit: 0
- serializedVersion: 3
- m_TransitionDuration: 0
- m_TransitionOffset: 0
- m_ExitTime: 0.75
- m_HasExitTime: 0
- m_HasFixedDuration: 1
- m_InterruptionSource: 0
- m_OrderedInterruption: 1
- m_CanTransitionToSelf: 1
-"""[1:]
-
-# State reached when TaSTT_Active = True.
-# One transition per row.
-TASTT_ACTIVE_STATE_HEADER = """
---- !u!1102 &%TASTT_ACTIVE_STATE_U2%
+# %TASTT_STATE_NAME%: the name of this state
+# %TASTT_STATE_TRANSITION_0_U2%
+# %TASTT_STATE_TRANSITION_1_U2%
+# %TASTT_STATE_TRANSITION_U2%
+TASTT_BINARY_STATE = """
+--- !u!%ANIMATOR_STATE_U% &%TASTT_STATE_U2%
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_Name: TaSTT_Active
+ m_Name: %TASTT_STATE_NAME%
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
-"""[1:]
-
-TASTT_ACTIVE_STATE_HEADER_TRANSITION = """
- - {fileID: %TASTT_TRANSITION_U2%}
-"""[1:]
-
-TASTT_ACTIVE_STATE_FOOTER = """
+ - {fileID: %TASTT_STATE_TRANSITION_0_U2%}
+ - {fileID: %TASTT_STATE_TRANSITION_1_U2%}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@@ -398,47 +361,40 @@ TASTT_ACTIVE_STATE_FOOTER = """
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
-"""[1:]
+"""[1:][:-1]
-# Transition from TaSTT_Active to TaSTT_Row*.
-# Params:
-# TRANSITION_THRESHOLD: The row to transition to (int).
-# DST_STATE_U2
-TASTT_ROW_STATE_TRANSITION = """
---- !u!1101 &%TRANSITION_U2%
-AnimatorStateTransition:
+TASTT_UNARY_STATE = """
+--- !u!%ANIMATOR_STATE_U% &%TASTT_STATE_U2%
+AnimatorState:
+ serializedVersion: 6
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
- m_Name:
- m_Conditions:
- - m_ConditionMode: 6
- m_ConditionEvent: TaSTT_Row
- m_EventTreshold: %TRANSITION_THRESHOLD%
- m_DstStateMachine: {fileID: 0}
- m_DstState: {fileID: %DST_STATE_U2%}
- m_Solo: 0
- m_Mute: 0
- m_IsExit: 0
- serializedVersion: 3
- m_TransitionDuration: 0
- m_TransitionOffset: 0
- m_ExitTime: 0.75
- m_HasExitTime: 0
- m_HasFixedDuration: 1
- m_InterruptionSource: 0
- m_OrderedInterruption: 1
- m_CanTransitionToSelf: 1
-"""[1:]
+ m_Name: %TASTT_STATE_NAME%
+ m_Speed: 1
+ m_CycleOffset: 0
+ m_Transitions:
+ - {fileID: %TASTT_STATE_TRANSITION_U2%}
+ m_StateMachineBehaviours: []
+ m_Position: {x: 50, y: 50, z: 0}
+ m_IKOnFeet: 0
+ m_WriteDefaultValues: 0
+ m_Mirror: 0
+ m_SpeedParameterActive: 0
+ m_MirrorParameterActive: 0
+ m_CycleOffsetParameterActive: 0
+ m_TimeParameterActive: 0
+ m_Motion: {fileID: 0}
+ m_Tag:
+ m_SpeedParameter:
+ m_MirrorParameter:
+ m_CycleOffsetParameter:
+ m_TimeParameter:
+"""[1:][:-1]
-# State reached after TaSTT_Active.
-# One transition per column.
-# Params:
-# %TASTT_STATE_NAME%: TaSTT_Row[0-9][0-9].
-# %TASTT_TRANSITION_U2%
-TASTT_ROW_STATE_HEADER = """
---- !u!1102 &%TASTT_STATE_U2%
+TASTT_NARY_STATE_HEADER = """
+--- !u!%ANIMATOR_STATE_U% &%TASTT_STATE_U2%
AnimatorState:
serializedVersion: 6
m_ObjectHideFlags: 1
@@ -449,13 +405,13 @@ AnimatorState:
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
-"""[1:]
+"""[1:][:-1]
-TASTT_ROW_STATE_HEADER_TRANSITION = """
- - {fileID: %TASTT_TRANSITION_U2%}
-"""[1:]
+TASTT_NARY_STATE_HEADER_TRANSITION = """
+ - {fileID: %TASTT_STATE_TRANSITION_U2%}
+"""[1:][:-1]
-TASTT_ROW_STATE_FOOTER = """
+TASTT_NARY_STATE_FOOTER = """
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@@ -471,14 +427,18 @@ TASTT_ROW_STATE_FOOTER = """
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
-"""[1:]
+"""[1:][:-1]
-# Transition from TaSTT_Row* to TaSTT_Row*_Col*.
+# Transition from TaSTT_Do_nothing. to TaSTT_Active.
# Params:
-# TRANSITION_THRESHOLD: The col to transition to (int).
-# DST_STATE_U2
-TASTT_COL_STATE_TRANSITION = """
---- !u!1101 &%TASTT_TRANSITION_U2%
+# %BOOL_PARAM% - the name of the parameter to branch on
+# %THRESHOLD% - the condition to branch on (1 == true)
+# %TASTT_ACTIVE_STATE_TRANSITION_U2%
+# %TASTT_ROW_STATE_U2% - address of row state we're transitioning to
+# A bizarre quirk: when branching false, m_ConditionMode = 2; else
+# m_ConditionMode = 1.
+TASTT_BOOL_STATE_TRANSITION = """
+--- !u!1101 &%TASTT_STATE_TRANSITION_U2%
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
@@ -486,9 +446,9 @@ AnimatorStateTransition:
m_PrefabAsset: {fileID: 0}
m_Name:
m_Conditions:
- - m_ConditionMode: 6
- m_ConditionEvent: TaSTT_Col
- m_EventTreshold: %TRANSITION_THRESHOLD%
+ - m_ConditionMode: %MODE%
+ m_ConditionEvent: %BOOL_PARAM%
+ m_EventTreshold: %THRESHOLD%
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: %DST_STATE_U2%}
m_Solo: 0
@@ -503,55 +463,10 @@ AnimatorStateTransition:
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
-"""[1:]
+"""[1:][:-1]
-# State reached after TaSTT_Row*.
-# One transition per letter.
-# Params:
-# %TASTT_STATE_NAME%: TaSTT_Row[0-9][0-9]_Col[0-9][0-9]
-# %TASTT_TRANSITION_U2%
-TASTT_COL_STATE_HEADER = """
---- !u!1102 &%TASTT_STATE_U2%
-AnimatorState:
- serializedVersion: 6
- m_ObjectHideFlags: 1
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_Name: %TASTT_STATE_NAME%
- m_Speed: 1
- m_CycleOffset: 0
- m_Transitions:
-"""[1:]
-
-TASTT_COL_STATE_HEADER_TRANSITION = """
- - {fileID: %TASTT_TRANSITION_U2%}
-"""[1:]
-
-TASTT_COL_STATE_FOOTER = """
- m_StateMachineBehaviours: []
- m_Position: {x: 50, y: 50, z: 0}
- m_IKOnFeet: 0
- m_WriteDefaultValues: 0
- m_Mirror: 0
- m_SpeedParameterActive: 0
- m_MirrorParameterActive: 0
- m_CycleOffsetParameterActive: 0
- m_TimeParameterActive: 0
- m_Motion: {fileID: 0}
- m_Tag:
- m_SpeedParameter:
- m_MirrorParameter:
- m_CycleOffsetParameter:
- m_TimeParameter:
-"""
-
-# Transition from TaSTT_Row*_Col* to TaSTT_Row*_Col*_Letter*.
-# Params:
-# TRANSITION_THRESHOLD: The row to transition to (int).
-# DST_STATE_U2
-TASTT_LETTER_STATE_TRANSITION = """
---- !u!1101 &%TASTT_TRANSITION_U2%
+TASTT_INT_STATE_TRANSITION = """
+--- !u!1101 &%TASTT_STATE_TRANSITION_U2%
AnimatorStateTransition:
m_ObjectHideFlags: 1
m_CorrespondingSourceObject: {fileID: 0}
@@ -560,7 +475,7 @@ AnimatorStateTransition:
m_Name:
m_Conditions:
- m_ConditionMode: 6
- m_ConditionEvent: TaSTT_Letter
+ m_ConditionEvent: %INT_PARAM%
m_EventTreshold: %TRANSITION_THRESHOLD%
m_DstStateMachine: {fileID: 0}
m_DstState: {fileID: %DST_STATE_U2%}
@@ -568,7 +483,7 @@ AnimatorStateTransition:
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
- m_TransitionDuration: 0
+ m_TransitionDuration: 0.02
m_TransitionOffset: 0
m_ExitTime: 0.75
m_HasExitTime: 0
@@ -576,7 +491,7 @@ AnimatorStateTransition:
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
-"""[1:]
+"""[1:][:-1]
# State reached after TaSTT_Row*_Col*.
# One transition back up to TaSTT_Do_Nothing.
@@ -597,7 +512,7 @@ AnimatorState:
m_Speed: 1
m_CycleOffset: 0
m_Transitions:
- - {fileID: %TASTT_RESTART_TRANSITION_U2%}
+ - {fileID: %TASTT_STATE_TRANSITION_U2%}
m_StateMachineBehaviours: []
m_Position: {x: 50, y: 50, z: 0}
m_IKOnFeet: 0
@@ -613,7 +528,7 @@ AnimatorState:
m_MirrorParameter:
m_CycleOffsetParameter:
m_TimeParameter:
-"""[1:]
+"""[1:][:-1]
TASTT_RESTART_TRANSITION = """
--- !u!1101 &%TASTT_RESTART_TRANSITION_U2%
@@ -641,7 +556,7 @@ AnimatorStateTransition:
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1
-"""
+"""[1:][:-1]
def getAnimationGuid(anim_meta_filename):
with open(anim_meta_filename, 'r') as f:
@@ -649,108 +564,185 @@ def getAnimationGuid(anim_meta_filename):
if "guid" in line:
return line.split()[1]
-def genTasttLayer(state):
+def getDefaultStateName(which_layer):
+ return "TaSTT_Do_Nothing"
+
+def getActiveStateName(which_layer):
+ return "TaSTT_Active"
+
+def getS0StateName(which_layer, s0):
+ return "TaSTT_S%02d" % (s0)
+
+def getS1StateName(which_layer, s0, s1):
+ return "TaSTT_S%02d_S%02d" % (s0, s1)
+
+def getS2StateName(which_layer, s0, s1, s2):
+ return "TaSTT_S%02d_S%02d_S%02d" % (s0, s1, s2)
+
+def getLetterStateName(which_layer, s0, s1, s2, letter):
+ return "TaSTT_S%02d_S%02d_S%02d_L%03d" % (s0, s1, s2, letter)
+
+def genTasttLayer(state, which_layer):
# Generate return-home transition
- print(replaceMacros(TASTT_RESTART_TRANSITION, params))
+ params["TASTT_RETURN_HOME_TRANSITION_%02d_U2" % which_layer] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_U2"] = params["TASTT_RETURN_HOME_TRANSITION_%02d_U2" % which_layer]
+ params["BOOL_PARAM"] = getDummyParam()
+ params["THRESHOLD"] = str(0)
+ params["MODE"] = str(2) # See comment above TASTT_BOOL_STATE_TRANSITION.
+ params["DEFAULT_STATE_U2"] = get_u2("1102", state)
+ params["DST_STATE_U2"] = params["DEFAULT_STATE_U2"]
+ print(replaceMacros(TASTT_BOOL_STATE_TRANSITION, params))
# Default state.
- print(replaceMacros(TASTT_DEFAULT_STATE, params))
+ params["TASTT_STATE_U2"] = params["DEFAULT_STATE_U2"]
+ params["TASTT_STATE_NAME"] = getDefaultStateName(which_layer)
+ params["TASTT_STATE_TRANSITION_U2"] = get_u2("1101", state)
+ print(replaceMacros(TASTT_UNARY_STATE, params))
# Active state transition.
- print(replaceMacros(TASTT_ACTIVE_STATE_TRANSITION, params))
+ params["BOOL_PARAM"] = getEnableParam(which_layer)
+ params["THRESHOLD"] = str(1)
+ params["MODE"] = str(1) # See comment above TASTT_BOOL_STATE_TRANSITION.
+ params["ACTIVE_STATE_U2"] = get_u2("1102", state)
+ params["DST_STATE_U2"] = params["ACTIVE_STATE_U2"]
+ print(replaceMacros(TASTT_BOOL_STATE_TRANSITION, params))
# Active state.
- print(replaceMacros(TASTT_ACTIVE_STATE_HEADER, params))
- for row in range(0, NUM_ROWS):
- params["TASTT_TRANSITION_ROW%02d_U2" % row] = get_u2("1101", state)
- params["TASTT_TRANSITION_U2"] = params["TASTT_TRANSITION_ROW%02d_U2" % row]
- print(replaceMacros(TASTT_ACTIVE_STATE_HEADER_TRANSITION, params))
- print(replaceMacros(TASTT_ACTIVE_STATE_FOOTER, params))
-
- # Row state transitions (one per row).
- for row in range(0, NUM_ROWS):
- params["TRANSITION_U2"] = params["TASTT_TRANSITION_ROW%02d_U2" % row]
- params["TRANSITION_THRESHOLD"] = str(row)
- params["TASTT_ROW%02d_STATE_U2" % row] = get_u2("1102", state)
- params["DST_STATE_U2"] = params["TASTT_ROW%02d_STATE_U2" % row]
- print(replaceMacros(TASTT_ROW_STATE_TRANSITION, params))
-
- # Row states (one per row)..
- for row in range(0, NUM_ROWS):
- params["TASTT_STATE_U2"] = params["TASTT_ROW%02d_STATE_U2" % row]
- params["TASTT_STATE_NAME"] = "TaSTT_Row%02d" % row
- print(replaceMacros(TASTT_ROW_STATE_HEADER, params))
- for col in range(0, NUM_COLS):
- params["TASTT_TRANSITION_ROW%02d_COL%02d_U2" % (row, col)] = get_u2("1101", state)
- params["TASTT_TRANSITION_U2"] = params["TASTT_TRANSITION_ROW%02d_COL%02d_U2" % (row, col)]
- print(replaceMacros(TASTT_ROW_STATE_HEADER_TRANSITION, params))
- print(replaceMacros(TASTT_ROW_STATE_FOOTER, params))
-
- # Column state transitions (one per row * column).
- for row in range(0, NUM_ROWS):
- for col in range(0, NUM_COLS):
- params["TASTT_TRANSITION_U2"] = params["TASTT_TRANSITION_ROW%02d_COL%02d_U2" % (row, col)]
- params["TRANSITION_THRESHOLD"] = str(col)
- params["TASTT_ROW%02d_COL%02d_STATE_U2" % (row, col)] = get_u2("1102", state)
- params["DST_STATE_U2"] = params["TASTT_ROW%02d_COL%02d_STATE_U2" % (row, col)]
- print(replaceMacros(TASTT_COL_STATE_TRANSITION, params))
-
- # Column states (one per row * column).
- for row in range(0, NUM_ROWS):
- for col in range(0, NUM_COLS):
- params["TASTT_STATE_U2"] = params["TASTT_ROW%02d_COL%02d_STATE_U2" % (row, col)]
- params["TASTT_STATE_NAME"] = "TaSTT_Row%02d_Col%02d" % (row,
- col)
- print(replaceMacros(TASTT_COL_STATE_HEADER, params))
- for letter in range(0, NUM_LETTERS):
- params["TASTT_TRANSITION_ROW%02d_COL%02d_LETTER%02d_U2" % (row, col, letter)] = get_u2("1101", state)
- params["TASTT_TRANSITION_U2"] = params["TASTT_TRANSITION_ROW%02d_COL%02d_LETTER%02d_U2" % (row, col, letter)]
- print(replaceMacros(TASTT_COL_STATE_HEADER_TRANSITION, params))
- print(replaceMacros(TASTT_COL_STATE_FOOTER, params))
-
- # Letter state transitions (one per row * column * letter).
- for row in range(0, NUM_ROWS):
- for col in range(0, NUM_COLS):
- for letter in range(0, NUM_LETTERS):
- params["TASTT_TRANSITION_U2"] = params["TASTT_TRANSITION_ROW%02d_COL%02d_LETTER%02d_U2" % (row, col, letter)]
- params["TRANSITION_THRESHOLD"] = str(letter)
- params["TASTT_ROW%02d_COL%02d_LETTER%02d_STATE_U2" % (row, col, letter)] = get_u2("1102", state)
- params["DST_STATE_U2"] = params["TASTT_ROW%02d_COL%02d_LETTER%02d_STATE_U2" % (row, col, letter)]
- print(replaceMacros(TASTT_LETTER_STATE_TRANSITION, params))
-
- # Letter states (one per row * column * letter).
- for row in range(0, NUM_ROWS):
- for col in range(0, NUM_COLS):
- for letter in range(0, NUM_LETTERS):
- params["TASTT_STATE_U2"] = params["TASTT_ROW%02d_COL%02d_LETTER%02d_STATE_U2" % (row, col, letter)]
- params["TASTT_STATE_NAME"] = "TaSTT_Row%02d_Col%02d_Letter%02d" % (row, col, letter)
- # Get the GUID of the animation we will play here.
- anim_meta_filename = "generated/animations/_Letter_Row%02d_Col%02d_Letter%02d.anim.meta" % (row, col, letter)
- params["TASTT_ANIM_GUID"] = getAnimationGuid(anim_meta_filename)
- print(replaceMacros(TASTT_LETTER_STATE, params))
+ params["TASTT_STATE_U2"] = params["ACTIVE_STATE_U2"]
+ params["TASTT_STATE_NAME"] = getActiveStateName(which_layer)
+ params[getS0StateName(which_layer, 0) + "_TRANSITION_U2"] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_0_U2"] = params[getS0StateName(which_layer, 0) + "_TRANSITION_U2"]
+ params[getS0StateName(which_layer, 1) + "_TRANSITION_U2"] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_1_U2"] = params[getS0StateName(which_layer, 1) + "_TRANSITION_U2"]
+ print(replaceMacros(TASTT_BINARY_STATE, params))
+
+ # S0 state transition.
+ for s0 in range(0,2):
+ params["TASTT_STATE_TRANSITION_U2"] = params[getS0StateName(which_layer, s0) + "_TRANSITION_U2"]
+ params["BOOL_PARAM"] = getSelectParam(which_layer, 0)
+ params["THRESHOLD"] = str(s0)
+ params["MODE"] = str(2 - s0) # See comment above TASTT_BOOL_STATE_TRANSITION.
+ params[getS0StateName(which_layer, s0) + "_U2"] = get_u2("1102", state)
+ params["DST_STATE_U2"] = params[getS0StateName(which_layer, s0) + "_U2"]
+ print(replaceMacros(TASTT_BOOL_STATE_TRANSITION, params))
+
+ # S0 state.
+ for s0 in range(0,2):
+ params["TASTT_STATE_U2"] = params[getS0StateName(which_layer, s0) + "_U2"]
+ params["TASTT_STATE_NAME"] = getS0StateName(which_layer, s0)
+ params[getS1StateName(which_layer, s0, 0) + "_TRANSITION_U2"] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_0_U2"] = params[getS1StateName(which_layer, s0, 0) + "_TRANSITION_U2"]
+ params[getS1StateName(which_layer, s0, 1) + "_TRANSITION_U2"] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_1_U2"] = params[getS1StateName(which_layer, s0, 1) + "_TRANSITION_U2"]
+ print(replaceMacros(TASTT_BINARY_STATE, params))
+
+ # S1 state transition.
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ params["TASTT_STATE_TRANSITION_U2"] = params[getS1StateName(which_layer, s0, s1) + "_TRANSITION_U2"]
+ params["BOOL_PARAM"] = getSelectParam(which_layer, 1)
+ params["THRESHOLD"] = str(s1)
+ params["MODE"] = str(2 - s1) # See comment above TASTT_BOOL_STATE_TRANSITION.
+ params[getS1StateName(which_layer, s0, s1) + "_U2"] = get_u2("1102", state)
+ params["DST_STATE_U2"] = params[getS1StateName(which_layer, s0, s1) + "_U2"]
+ print(replaceMacros(TASTT_BOOL_STATE_TRANSITION, params))
+
+ # S1 state.
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ params["TASTT_STATE_U2"] = params[getS1StateName(which_layer, s0, s1) + "_U2"]
+ params["TASTT_STATE_NAME"] = getS1StateName(which_layer, s0, s1)
+ params[getS2StateName(which_layer, s0, s1, 0) + "_TRANSITION_U2"] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_0_U2"] = params[getS2StateName(which_layer, s0, s1, 0) + "_TRANSITION_U2"]
+ params[getS2StateName(which_layer, s0, s1, 1) + "_TRANSITION_U2"] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_1_U2"] = params[getS2StateName(which_layer, s0, s1, 1) + "_TRANSITION_U2"]
+ print(replaceMacros(TASTT_BINARY_STATE, params))
+
+ # S2 state transition.
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ for s2 in range(0,2):
+ params["TASTT_STATE_TRANSITION_U2"] = params[getS2StateName(which_layer, s0, s1, s2) + "_TRANSITION_U2"]
+ params["BOOL_PARAM"] = getSelectParam(which_layer, 2)
+ params["THRESHOLD"] = str(s2)
+ params["MODE"] = str(2 - s2) # See comment above TASTT_BOOL_STATE_TRANSITION.
+ params[getS2StateName(which_layer, s0, s1, s2) + "_U2"] = get_u2("1102", state)
+ params["DST_STATE_U2"] = params[getS2StateName(which_layer, s0, s1, s2) + "_U2"]
+ print(replaceMacros(TASTT_BOOL_STATE_TRANSITION, params))
+
+ # S2 state.
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ for s2 in range(0,2):
+ params["TASTT_STATE_U2"] = params[getS2StateName(which_layer, s0, s1, s2) + "_U2"]
+ params["TASTT_STATE_NAME"] = getS2StateName(which_layer, s0, s1, s2)
+ print(replaceMacros(TASTT_NARY_STATE_HEADER, params))
+ for letter in range(0, CHARS_PER_CELL):
+ params[getLetterStateName(which_layer, s0, s1, s2, letter) + "_TRANSITION_U2"] = get_u2("1101", state)
+ params["TASTT_STATE_TRANSITION_U2"] = params[getLetterStateName(which_layer, s0, s1, s2, letter) + "_TRANSITION_U2"]
+ print(replaceMacros(TASTT_NARY_STATE_HEADER_TRANSITION, params))
+ print(replaceMacros(TASTT_NARY_STATE_FOOTER, params))
+
+ # Letter state transition.
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ for s2 in range(0,2):
+ for letter in range(0, CHARS_PER_CELL):
+ params["TASTT_STATE_TRANSITION_U2"] = params[getLetterStateName(which_layer, s0, s1, s2, letter) + "_TRANSITION_U2"]
+ params["INT_PARAM"] = getLayerParam(which_layer)
+ params["TRANSITION_THRESHOLD"] = str(letter)
+ params[getLetterStateName(which_layer, s0, s1, s2, letter) + "_U2"] = get_u2("1102", state)
+ params["DST_STATE_U2"] = params[getLetterStateName(which_layer, s0, s1, s2, letter) + "_U2"]
+ print(replaceMacros(TASTT_INT_STATE_TRANSITION, params))
+
+ # Letter state.
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ for s2 in range(0,2):
+ for letter in range(0, CHARS_PER_CELL):
+ params["TASTT_STATE_U2"] = params[getLetterStateName(which_layer, s0, s1, s2, letter) + "_U2"]
+ params["TASTT_STATE_NAME"] = getLetterStateName(which_layer, s0, s1, s2, letter)
+ params["TASTT_STATE_TRANSITION_U2"] = params["TASTT_RETURN_HOME_TRANSITION_%02d_U2" % which_layer]
+ anim_meta_filename = getAnimationPath(getShaderParam(which_layer, s0, s1, s2), letter) + ".meta"
+ params["TASTT_ANIM_GUID"] = getAnimationGuid(anim_meta_filename)
+ print(replaceMacros(TASTT_LETTER_STATE, params))
# TaSTT layer.
+ params["TASTT_LAYER_U2"] = params[getLayerParam(which_layer) + "_LAYER_U2"]
+
+ params["TASTT_LAYER_NAME"] = getLayerParam(which_layer)
print(replaceMacros(TASTT_LAYER_HEADER, params))
- params["TASTT_STATE_U2"] = params["TASTT_DEFAULT_STATE_U2"]
+ params["TASTT_STATE_U2"] = params["DEFAULT_STATE_U2"]
print(replaceMacros(TASTT_LAYER_HEADER_CHILD_STATE, params))
- params["TASTT_STATE_U2"] = params["TASTT_ACTIVE_STATE_U2"]
+ params["TASTT_STATE_U2"] = params["ACTIVE_STATE_U2"]
print(replaceMacros(TASTT_LAYER_HEADER_CHILD_STATE, params))
- for row in range(0, NUM_ROWS):
- params["TASTT_STATE_U2"] = params["TASTT_ROW%02d_STATE_U2" % row]
+ for s0 in range(0,2):
+ params["TASTT_STATE_U2"] = params[getS0StateName(which_layer, s0) + "_U2"]
print(replaceMacros(TASTT_LAYER_HEADER_CHILD_STATE, params))
- for row in range(0, NUM_ROWS):
- for col in range(0, NUM_COLS):
- params["TASTT_STATE_U2"] = params["TASTT_ROW%02d_COL%02d_STATE_U2" % (row, col)]
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ params["TASTT_STATE_U2"] = params[getS1StateName(which_layer, s0, s1) + "_U2"]
print(replaceMacros(TASTT_LAYER_HEADER_CHILD_STATE, params))
- for row in range(0, NUM_ROWS):
- for col in range(0, NUM_COLS):
- for letter in range(0, NUM_LETTERS):
- params["TASTT_STATE_U2"] = params["TASTT_ROW%02d_COL%02d_LETTER%02d_STATE_U2" % (row, col, letter)]
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ for s2 in range(0,2):
+ params["TASTT_STATE_U2"] = params[getS2StateName(which_layer, s0, s1, s2) + "_U2"]
print(replaceMacros(TASTT_LAYER_HEADER_CHILD_STATE, params))
-genTasttLayer(state)
+ for s0 in range(0,2):
+ for s1 in range(0,2):
+ for s2 in range(0,2):
+ for letter in range(0, CHARS_PER_CELL):
+ params["TASTT_STATE_U2"] = params[getLetterStateName(which_layer, s0, s1, s2, letter) + "_U2"]
+ print(replaceMacros(TASTT_LAYER_HEADER_CHILD_STATE, params))
+
+ params["TASTT_DEFAULT_STATE_U2"] = params["DEFAULT_STATE_U2"]
+ print(replaceMacros(TASTT_LAYER_FOOTER, params))
+
+for i in range(0, NUM_LAYERS):
+ genTasttLayer(state, i)
diff --git a/generate_params.py b/generate_params.py
new file mode 100644
index 0000000..665a439
--- /dev/null
+++ b/generate_params.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+
+import generate_utils
+
+PARAM_HEADER = """
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &11400000
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: -1506855854, guid: 67cc4cb7839cd3741b63733d5adf0442, type: 3}
+ m_Name: TaSTT_params
+ m_EditorClassIdentifier:
+ parameters:
+"""[1:][0:-1]
+
+INT_PARAM = """
+ - name: %PARAM_NAME%
+ valueType: 0
+ saved: 0
+ defaultValue: 0
+"""[1:][0:-1]
+
+BOOL_PARAM = """
+ - name: %PARAM_NAME%
+ valueType: 2
+ saved: 0
+ defaultValue: 0
+"""[1:][0:-1]
+
+# We're working with an 84-character board, and each FX layer is responsible
+# for 8 of those characters.
+params = {}
+print(generate_utils.replaceMacros(PARAM_HEADER, params))
+
+# Implementation detail. We use this parameter to return from the terminal
+# state of the FX layer to the starting state.
+params["PARAM_NAME"] = "TaSTT_Dummy"
+print(generate_utils.replaceMacros(BOOL_PARAM, params))
+
+for i in range(0, generate_utils.NUM_LAYERS):
+ params["PARAM_NAME"] = generate_utils.getLayerParam(i)
+ print(generate_utils.replaceMacros(INT_PARAM, params))
+
+ params["PARAM_NAME"] = generate_utils.getSelectParam(i, 0)
+ print(generate_utils.replaceMacros(BOOL_PARAM, params))
+
+ params["PARAM_NAME"] = generate_utils.getSelectParam(i, 1)
+ print(generate_utils.replaceMacros(BOOL_PARAM, params))
+
+ params["PARAM_NAME"] = generate_utils.getSelectParam(i, 2)
+ print(generate_utils.replaceMacros(BOOL_PARAM, params))
+
+ params["PARAM_NAME"] = generate_utils.getEnableParam(i)
+ print(generate_utils.replaceMacros(BOOL_PARAM, params))
diff --git a/generate_utils.py b/generate_utils.py
new file mode 100644
index 0000000..1abb694
--- /dev/null
+++ b/generate_utils.py
@@ -0,0 +1,53 @@
+from math import ceil
+from math import floor
+
+def replaceMacros(lines, macro_defs):
+ for k,v in macro_defs.items():
+ lines = lines.replace("%" + k + "%", v)
+ return lines
+
+BOARD_ROWS=6
+BOARD_COLS=14
+INDEX_BITS=3
+CHARS_PER_CELL=80
+
+NUM_LAYERS=ceil((BOARD_ROWS * BOARD_COLS) / (2**INDEX_BITS))
+
+# The bits per layer are:
+# 8 bits: letter selection (256 possible letters per slot)
+# 3 bits: slot selection (each layer controls 8 slots)
+# 1 bit: enable bit (turns layer off while we index to a new slot)
+NUM_PARAM_BITS=(NUM_LAYERS * (8 + INDEX_BITS + 1))
+
+def getDummyParam():
+ return "TaSTT_Dummy"
+
+# Each layer controls a group of cells. There's only one letter per layer, thus
+# this is also the name of the parameter which sets the letter for a layer.
+def getLayerParam(which_layer):
+ return "TaSTT_L%02d" % which_layer
+
+def getSelectParam(which_layer, which_select):
+ return "TaSTT_L%02d_S%02d" % (which_layer, which_select)
+
+def getEnableParam(which_layer):
+ return "TaSTT_L%02d_E" % which_layer
+
+def getBoardIndex(which_layer, s0, s1, s2):
+ # TODO(yum_food) because we divide the board into a multiple of 8 cells,
+ # some cells describe animations which don't exist. We work around this by
+ # simply wrapping those animations back to the top of the board, and rely
+ # on the OSC controller to simply not reference those cells. Clean this up.
+ return ((s0 * 4 + s1 * 2 + s2) * NUM_LAYERS + which_layer) % (BOARD_ROWS * BOARD_COLS)
+
+# Mapping from layer to shader param.
+def getShaderParam(which_layer, s0, s1, s2):
+ index = getBoardIndex(which_layer, s0, s1, s2)
+
+ col = index % BOARD_COLS
+ row = floor(index / BOARD_COLS)
+ return "_Letter_Row%02d_Col%02d" % (row, col)
+
+# Returns the path to the animation for the given shader parameter + letter.
+def getAnimationPath(shader_param, letter):
+ return "generated/animations/%s_Letter%02d.anim" % (shader_param, letter)
diff --git a/group_names.txt b/group_names.txt
deleted file mode 100644
index 0c39082..0000000
--- a/group_names.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-_Letter_Row00_Col00_03
-_Letter_Row00_Col04_07
-_Letter_Row00_Col08_11
-_Letter_Row00_Col12_13
-_Letter_Row01_Col00_03
-_Letter_Row01_Col04_07
-_Letter_Row01_Col08_11
-_Letter_Row01_Col12_13
-_Letter_Row02_Col00_03
-_Letter_Row02_Col04_07
-_Letter_Row02_Col08_11
-_Letter_Row02_Col12_13
-_Letter_Row03_Col00_03
-_Letter_Row03_Col04_07
-_Letter_Row03_Col08_11
-_Letter_Row03_Col12_13
-_Letter_Row04_Col00_03
-_Letter_Row04_Col04_07
-_Letter_Row04_Col08_11
-_Letter_Row04_Col12_13
-_Letter_Row05_Col00_03
-_Letter_Row05_Col04_07
-_Letter_Row05_Col08_11
-_Letter_Row05_Col12_13
diff --git a/osc_ctrl.py b/osc_ctrl.py
index 21386c4..3c19cd9 100644
--- a/osc_ctrl.py
+++ b/osc_ctrl.py
@@ -6,6 +6,15 @@ import time
import fileinput
from pythonosc import udp_client
+from math import ceil
+from math import floor
+from generate_utils import getLayerParam
+from generate_utils import getSelectParam
+from generate_utils import getEnableParam
+from generate_utils import getBoardIndex
+from generate_utils import NUM_LAYERS
+from generate_utils import BOARD_ROWS
+from generate_utils import BOARD_COLS
def usage():
print("python3 -m pip install python-osc")
@@ -18,26 +27,88 @@ args = parser.parse_args()
client = udp_client.SimpleUDPClient(args.i, args.p)
-seed = random.randrange(3) * 26
-for row in range(0, 6):
- addr="/avatar/parameters/TaSTT_Row"
- client.send_message(addr, row)
- for col in range(0, 14):
- addr="/avatar/parameters/TaSTT_Col"
- client.send_message(addr, col)
+def encodeMessage(msg):
+ result = []
+ for char in msg:
+ char_int = ord(char)
+ if char_int >= ord('A') and char_int <= ord('Z'):
+ result.append(ord(char) - ord('A'))
+ elif char >= 'a' and char <= 'z':
+ result.append((ord(char) - ord('a')) + 26)
+ elif char >= '0' and char <= '9':
+ result.append((ord(char) - ord('0')) + 52)
+ elif char == '.':
+ result.append(62)
+ elif char == ',':
+ result.append(63)
+ elif char == ' ':
+ result.append(64)
+ # Pad message with spaces so that it overwrites any leftover text.
+ result += [65] * (BOARD_ROWS * BOARD_COLS - len(result))
+ return result
- time.sleep(.5)
+# `which_cell` is an integer in the range [0,8).
+def sendMessageCell(msg_cell, which_cell):
- addr="/avatar/parameters/TaSTT_Active"
- client.send_message(addr, True)
+ s0 = ((floor(which_cell / 4) % 2) == 1)
+ s1 = ((floor(which_cell / 2) % 2) == 1)
+ s2 = ((floor(which_cell / 1) % 2) == 1)
+
+ print("Cell s0/s1/s2: {}/{}/{}".format(s0,s1,s2))
+ # Seek each layer to the current cell.
+ for i in range(0, len(msg_cell)):
+ print("Board index: {}".format(getBoardIndex(i, s0, s1, s2)))
+
+ addr="/avatar/parameters/" + getLayerParam(i)
+ client.send_message(addr, msg_cell[i])
+
+ addr="/avatar/parameters/" + getSelectParam(i, 0)
+ client.send_message(addr, (floor(which_cell / 4) % 2) == 1)
- addr="/avatar/parameters/TaSTT_Letter"
- client.send_message(addr, (seed + row * 14 + col) % 65)
- print("sent {} at {},{}".format((seed + row * 14 + col) % 65, row, col))
+ addr="/avatar/parameters/" + getSelectParam(i, 1)
+ client.send_message(addr, (floor(which_cell / 2) % 2) == 1)
- time.sleep(.5)
+ addr="/avatar/parameters/" + getSelectParam(i, 2)
+ client.send_message(addr, (which_cell % 2) == 1)
+
+ # Wait for convergence.
+ time.sleep(0.3)
+
+ # Enable each layer.
+ # TODO(yum_food) for some reason, if we don't active every layer, the
+ # desired subset won't reliably fire. Why?
+ for i in range(0, NUM_LAYERS):
+ addr="/avatar/parameters/" + getEnableParam(i)
+ client.send_message(addr, True)
- addr="/avatar/parameters/TaSTT_Active"
+ # Wait for convergence.
+ time.sleep(0.3)
+
+ # Disable each layer.
+ for i in range(0, NUM_LAYERS):
+ addr="/avatar/parameters/" + getEnableParam(i)
client.send_message(addr, False)
-time.sleep(1000)
+ # Wait for convergence.
+ time.sleep(0.3)
+
+def sendMessage(msg):
+ # The board is broken down into contiguous collections of characters called
+ # cells. Each cell contains `NUM_LAYERS` characters. We can update one cell
+ # every ~1.0 seconds; going faster causes the board to display garbage to
+ # remote players.
+ msg = encodeMessage(msg)
+
+ n_cells = ceil(len(msg) / NUM_LAYERS)
+ for cell in range(0, n_cells):
+ cell_begin = cell * NUM_LAYERS
+ cell_end = (cell + 1) * NUM_LAYERS
+ cell_msg = msg[cell_begin:cell_end]
+ print("Send cell {}".format(cell))
+ sendMessageCell(cell_msg, cell)
+
+for line in fileinput.input():
+ sendMessage(line)
+
+sendMessage("")
+