diff options
| author | yum <yum.food.vr@gmail.com> | 2022-09-30 18:44:36 -0700 |
|---|---|---|
| committer | yum <yumfood@airmail.cc> | 2022-09-30 18:44:36 -0700 |
| commit | 2fa5bc78b5c4500301327bd6a334ab4fb8e04a17 (patch) | |
| tree | d03c01d929431320686d61f7091b96f6be3d14ca /osc_ctrl.py | |
| parent | 73bbba9de5210ae7f895ae82bd2524eb76e3a38c (diff) | |
Redo FX layer
Apparently the same avatar parameter can only be updated so quickly
before VRChat starts dropping messages. So now we divide the board
into "groups" of 8 characters. Each group can be updated relatively
slowly, but all groups can be updated in parallel. Thus we can update
the board group-by-group, pausing between each group.
* Fix shader bugs - now there are Row05 parameters, and row00 refers
to the topmost row instead of the bottom-most.
* Remove outdated layer/group names files
* Extend osc_ctrl.py to support encoding & sending messages
* Add generate_params.py to handle creating TaSTT_params.asset
* Add generate_utils.py for common code generation facilities &
parameters.
Diffstat (limited to 'osc_ctrl.py')
| -rw-r--r-- | osc_ctrl.py | 103 |
1 files changed, 87 insertions, 16 deletions
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("") + |
