Skip to content

Commit

Permalink
Merge pull request #7 from uzair-ashraf/uzair/add-a-gui
Browse files Browse the repository at this point in the history
Setup UI, Intensity based muscle groups, 1.0.0 release
  • Loading branch information
shadorki committed Sep 25, 2023
2 parents 738bf3a + 890b549 commit fefd564
Show file tree
Hide file tree
Showing 16 changed files with 568 additions and 108 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
pip install -r requirements.txt
- name: Build with pyinstaller
run: pyinstaller --hidden-import=clr --add-binary "./owo/OWO.dll;owo" --onefile --distpath ./build --name=vrc-owo-suit main.py
run: pyinstaller --hidden-import=clr --add-data "./img/logo.png;img" --add-binary "./owo/OWO.dll;owo" --onefile --distpath ./build --name=vrc-owo-suit main.py

- name: Deploy EXE
uses: actions/upload-artifact@v3
Expand Down
79 changes: 58 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,84 @@

A python application for VRChat players to use OWO Suits in game

## Demo

https://user-images.githubusercontent.com/52118958/216754614-c2474c91-88a2-465a-9aa3-b570dde76173.mp4


## Table of Contents

- [Installation](#installation)
- [Settings](#settings)
- [Contributing](#contributing)

## Installation

---

Head over to the [Releases](https://github.com/uzair-ashraf/vrc-owo-suit/releases) page to get the latest release.

1. Download the executable.

1. Download the Unity Package.

1. In the same directory where you put your executable, create a new file named `vrc-owo-suit.config.json`.
1. Open your Unity Project, open the provided Unity package, and setup your avatar ([More Instructions](#setting-up-your-avatar) on this below)

1. Run the executable

<p align="center">
<img width="300px" src="./img/screenshot-app-1.png">
</p>

1. Open the OWO app and head to Games > Scan Game

1. In `vrc-owo-suit.config.json` paste the following values:
<p align="center">
<img width="300px" src="./img/screenshot-owo-app-1.png">
</p>

```json
{
"server_port": 9001,
"owo_ip": "",
"frequency": 100,
"intensity": 20
}
```
1. Click connect in the application

<p align="center">
<img width="300px" src="./img/screenshot-app-2.png">
</p>

1. In your OWO Suit's application, copy the IP Address and replace the provided value in the `owo_ip` property.
1. Click connect in the OWO app

<p align="center">
<img src="./img/screenshot-app-3.png">
</p>

1. If everything works, both applications should say that they are connected!

<p align="center">
<img src="./img/screenshot-app-4.png">
</p>

1. Open your Unity Project and open the provided Unity package. ([More Instructions](#setting-up-your-avatar) on this below)
## Settings

1. OWO Suit IP Address

You should leave this empty and leave the checkbox below checked, the OWO app can detect your suit fairly easily. I'm not sure what their usecase is for an IP address, maybe multiple suits on one machine?

1. Server Port Number

Leave this at `9001`, only change if you know what you're doing!

1. Frequency Settings

I keep this at 100, I think it's for how abrupt the sensation is?

1. Intensity Settings

When calibrating your suit with the OWO app you will set some limitations for each muscle group, to prevent from shocking yourself too much.

When you enter VRChat, you'll realize that you have a higher tolerance for some muscles rather than others.

## Contributing
<p align="center">
<img src="./img/screenshot-app-5.png">
</p>

You can adjust the intensity settings in real time, and when you are done, you can click `Save Settings` to keep the app's settings for the next time you start it.

---
Also, if you're having trouble telling which muscle is active when you're feeling them, the intensity settings labels will change when your muscles are being interacted with.

In other words, if your `Left Pectoral` is touched, it will update in the UI as `[Left Pectoral]`


## Contributing

### Requirements

Expand Down
87 changes: 57 additions & 30 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,63 @@
import json
import params
import os
import json


class Config:
def __init__(self, server_port: int, owo_ip: str, intensity: int, frequency: int):
self.server_port = server_port
self.owo_ip = owo_ip
self.intensity = intensity
self.frequency = frequency
def __init__(self):
self.APP_NAME = 'VRChatOWOSuit'
self.default_config = {
"server_port": 9001,
"owo_ip": "",
"should_detect_ip": True,
"should_connect_on_startup": False,
"frequency": 100,
"intensities": {
params.owo_suit_Pectoral_L: 60,
params.owo_suit_Pectoral_R: 60,
params.owo_suit_Abdominal_L: 60,
params.owo_suit_Abdominal_R: 60,
params.owo_suit_Arm_L: 60,
params.owo_suit_Arm_R: 60,
params.owo_suit_Dorsal_L: 60,
params.owo_suit_Dorsal_R: 60,
params.owo_suit_Lumbar_L: 60,
params.owo_suit_Lumbar_R: 60,
}
}
self.current_config = None

def get_by_key(self, key: str):
return self.current_config.get(key)

def update(self, key: str, nextValue):
if (key in self.current_config):
self.current_config[key] = nextValue

def read_config_from_disk(self):
appdata_path = os.environ.get('LOCALAPPDATA')
app_directory = os.path.join(appdata_path, self.APP_NAME)
os.makedirs(app_directory, exist_ok=True)
config_path = os.path.join(app_directory, 'config.json')
if os.path.exists(config_path):
with open(config_path, 'r') as file:
data = json.load(file)
return data
else:
with open(config_path, 'w') as file:
json.dump(self.default_config, file, indent=4)
return self.default_config

def write_config_to_disk(self):
if self.current_config == None:
return
appdata_path = os.environ.get('LOCALAPPDATA')
app_directory = os.path.join(appdata_path, self.APP_NAME)
os.makedirs(app_directory, exist_ok=True)
config_path = os.path.join(app_directory, 'config.json')
with open(config_path, 'w') as file:
json.dump(self.current_config, file, indent=4)

def get() -> Config:
server_port = 9001
owo_ip = ""
intensity = 10
frequency = 100
try:
f = open('./vrc-owo-suit.config.json')
data = json.load(f)
f.close()
if ("server_port" in data and type(data['server_port']) is int):
print(f"Using server_port {data['server_port']}.")
server_port = data['server_port']
if ("owo_ip" in data and type(data['owo_ip']) is str):
print(f"Using owo_ip {data['owo_ip']}.")
owo_ip = data['owo_ip']
if ("intensity" in data and type(data['intensity']) is int):
print(f"Using intensity {data['intensity']}.")
intensity = data['intensity']
if ("frequency" in data and type(data['frequency']) is int):
print(f"Using frequency {data['frequency']}.")
frequency = data['frequency']
except:
print("Config file not found, using default settings")
finally:
return Config(server_port, owo_ip, intensity, frequency)
def init(self):
self.current_config = self.read_config_from_disk()
19 changes: 19 additions & 0 deletions event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import atexit
from concurrent.futures import ThreadPoolExecutor


class Event:
def __init__(self, max_workers=3):
self.listeners = []
self.executor = ThreadPoolExecutor(max_workers=max_workers)
atexit.register(self.executor.shutdown)

def add_listener(self, func):
self.listeners.append(func)

def remove_listener(self, func):
self.listeners.remove(func)

def dispatch(self, *args, **kwargs):
for listener in self.listeners:
self.executor.submit(listener, *args, **kwargs)
Loading

0 comments on commit fefd564

Please sign in to comment.