This commit is contained in:
ImUrX
2023-06-14 12:34:24 -03:00
parent a14a2ea253
commit d14a7bb5e7
20 changed files with 423 additions and 416 deletions

View File

@@ -15,18 +15,19 @@ plugins {
id("com.diffplug.spotless")
}
// FIXME: Please replace these to Java 11 as that's what they actually are
kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(11))
languageVersion.set(JavaLanguageVersion.of(17))
}
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
languageVersion.set(JavaLanguageVersion.of(17))
}
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "11"
kotlinOptions.jvmTarget = "17"
}
// Set compiler to use UTF-8

View File

@@ -39,386 +39,403 @@ import java.util.concurrent.atomic.AtomicInteger
import java.util.function.Consumer
class VRServer @JvmOverloads constructor(configPath: String? = "vrconfig.yml") : Thread("VRServer") {
@JvmField
val humanPoseManager: HumanPoseManager
val hmdTracker: Tracker
private val trackers: MutableList<Tracker> = FastList()
val trackersServer: TrackersUDPServer
private val bridges: MutableList<Bridge> = FastList()
private val tasks: Queue<Runnable> = LinkedBlockingQueue()
private val newTrackersConsumers: MutableList<Consumer<Tracker>> = FastList()
private val onTick: MutableList<Runnable> = FastList()
val oSCRouter: OSCRouter
@JvmField
val vrcOSCHandler: VRCOSCHandler
val vMCHandler: VMCHandler
@JvmField
val deviceManager: DeviceManager
@JvmField
val bvhRecorder: BVHRecorder
@JvmField
val serialHandler: SerialHandler
@JvmField
val autoBoneHandler: AutoBoneHandler
@JvmField
val tapSetupHandler: TapSetupHandler
@JvmField
val protocolAPI: ProtocolAPI
@JvmField
@JvmField
val configManager: ConfigManager
private val timer = Timer()
val fpsTimer = NanoTimer()
@JvmField
@JvmField
val humanPoseManager: HumanPoseManager
val hmdTracker: Tracker
private val trackers: MutableList<Tracker> = FastList()
val trackersServer: TrackersUDPServer
private val bridges: MutableList<Bridge> = FastList()
private val tasks: Queue<Runnable> = LinkedBlockingQueue()
private val newTrackersConsumers: MutableList<Consumer<Tracker>> = FastList()
private val onTick: MutableList<Runnable> = FastList()
val oSCRouter: OSCRouter
@JvmField
val vrcOSCHandler: VRCOSCHandler
val vMCHandler: VMCHandler
@JvmField
val deviceManager: DeviceManager
@JvmField
val bvhRecorder: BVHRecorder
@JvmField
val serialHandler: SerialHandler
@JvmField
val autoBoneHandler: AutoBoneHandler
@JvmField
val tapSetupHandler: TapSetupHandler
@JvmField
val protocolAPI: ProtocolAPI
private val timer = Timer()
val fpsTimer = NanoTimer()
@JvmField
val provisioningHandler: ProvisioningHandler
@JvmField
@JvmField
val resetHandler: ResetHandler
@JvmField
@JvmField
val statusSystem = StatusSystem()
/**
* This function is used by VRWorkout, do not remove!
*/
init {
// UwU
configManager = ConfigManager(configPath)
configManager.loadConfig()
deviceManager = DeviceManager(this)
serialHandler = SerialHandler()
provisioningHandler = ProvisioningHandler(this)
resetHandler = ResetHandler()
tapSetupHandler = TapSetupHandler()
autoBoneHandler = AutoBoneHandler(this)
protocolAPI = ProtocolAPI(this)
hmdTracker = Tracker(
null,
0,
"HMD",
"HMD",
TrackerPosition.HEAD,
null,
true,
true,
false,
false,
false,
true
)
humanPoseManager = HumanPoseManager(this)
val computedTrackers = humanPoseManager.computedTrackers
/**
* This function is used by VRWorkout, do not remove!
*/
init {
// UwU
configManager = ConfigManager(configPath)
configManager.loadConfig()
deviceManager = DeviceManager(this)
serialHandler = SerialHandler()
provisioningHandler = ProvisioningHandler(this)
resetHandler = ResetHandler()
tapSetupHandler = TapSetupHandler()
autoBoneHandler = AutoBoneHandler(this)
protocolAPI = ProtocolAPI(this)
hmdTracker = Tracker(
null,
0,
"HMD",
"HMD",
TrackerPosition.HEAD,
null,
true,
true,
false,
false,
false,
true
)
humanPoseManager = HumanPoseManager(this)
val computedTrackers = humanPoseManager.computedTrackers
// Start server for SlimeVR trackers
val trackerPort = configManager.vrConfig.server.trackerPort
LogManager.info("Starting the tracker server on port $trackerPort...")
trackersServer = TrackersUDPServer(
trackerPort,
"Sensors UDP server"
) { tracker: Tracker -> registerTracker(tracker) }
val driverBridge: SteamVRBridge?
if (OperatingSystem.getCurrentPlatform() == OperatingSystem.WINDOWS) {
// Start server for SlimeVR trackers
val trackerPort = configManager.vrConfig.server.trackerPort
LogManager.info("Starting the tracker server on port $trackerPort...")
trackersServer = TrackersUDPServer(
trackerPort,
"Sensors UDP server"
) { tracker: Tracker -> registerTracker(tracker) }
val driverBridge: SteamVRBridge?
if (OperatingSystem.getCurrentPlatform() == OperatingSystem.WINDOWS) {
// Create named pipe bridge for SteamVR driver
driverBridge = WindowsNamedPipeBridge(
this,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
"\\\\.\\pipe\\SlimeVRDriver",
computedTrackers
)
tasks.add(Runnable { driverBridge.startBridge() })
bridges.add(driverBridge)
// Create named pipe bridge for SteamVR driver
driverBridge = WindowsNamedPipeBridge(
this,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
"\\\\.\\pipe\\SlimeVRDriver",
computedTrackers
)
tasks.add(Runnable { driverBridge.startBridge() })
bridges.add(driverBridge)
// Create named pipe bridge for SteamVR input
// TODO: how do we want to handle HMD input from the feeder app?
val feederBridge = WindowsNamedPipeBridge(
this,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
"\\\\.\\pipe\\SlimeVRInput",
FastList()
)
tasks.add(Runnable { feederBridge.startBridge() })
bridges.add(feederBridge)
} else if (OperatingSystem.getCurrentPlatform() == OperatingSystem.LINUX) {
var linuxBridge: SteamVRBridge? = null
try {
linuxBridge = UnixSocketBridge(
this,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRDriver").toString(),
computedTrackers
)
} catch (ex: Exception) {
LogManager.severe("Failed to initiate Unix socket, disabling driver bridge...", ex)
}
driverBridge = linuxBridge
if (driverBridge != null) {
tasks.add(Runnable { driverBridge.startBridge() })
bridges.add(driverBridge)
}
try {
val feederBridge: SteamVRBridge = UnixSocketBridge(
this,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRInput").toString(),
FastList()
)
tasks.add(Runnable { feederBridge.startBridge() })
bridges.add(feederBridge)
} catch (ex: Exception) {
LogManager.severe("Failed to initiate Unix socket, disabling feeder bridge...", ex)
}
} else {
driverBridge = null
}
// Create named pipe bridge for SteamVR input
// TODO: how do we want to handle HMD input from the feeder app?
val feederBridge = WindowsNamedPipeBridge(
this,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
"\\\\.\\pipe\\SlimeVRInput",
FastList()
)
tasks.add(Runnable { feederBridge.startBridge() })
bridges.add(feederBridge)
} else if (OperatingSystem.getCurrentPlatform() == OperatingSystem.LINUX) {
var linuxBridge: SteamVRBridge? = null
try {
linuxBridge = UnixSocketBridge(
this,
hmdTracker,
"steamvr",
"SteamVR Driver Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRDriver").toString(),
computedTrackers
)
} catch (ex: Exception) {
LogManager.severe("Failed to initiate Unix socket, disabling driver bridge...", ex)
}
driverBridge = linuxBridge
if (driverBridge != null) {
tasks.add(Runnable { driverBridge.startBridge() })
bridges.add(driverBridge)
}
try {
val feederBridge: SteamVRBridge = UnixSocketBridge(
this,
null,
"steamvr_feeder",
"SteamVR Feeder Bridge",
Paths.get(OperatingSystem.getTempDirectory(), "SlimeVRInput").toString(),
FastList()
)
tasks.add(Runnable { feederBridge.startBridge() })
bridges.add(feederBridge)
} catch (ex: Exception) {
LogManager.severe("Failed to initiate Unix socket, disabling feeder bridge...", ex)
}
} else {
driverBridge = null
}
// Add shutdown hook
Runtime.getRuntime().addShutdownHook(Thread {
try {
(driverBridge as? UnixSocketBridge)?.close()
} catch (e: Exception) {
throw RuntimeException(e)
}
})
// Add shutdown hook
Runtime.getRuntime().addShutdownHook(
Thread {
try {
(driverBridge as? UnixSocketBridge)?.close()
} catch (e: Exception) {
throw RuntimeException(e)
}
}
)
// Create WebSocket server
val wsBridge = WebSocketVRBridge(hmdTracker, computedTrackers, this)
tasks.add(Runnable { wsBridge.startBridge() })
bridges.add(wsBridge)
// Create WebSocket server
val wsBridge = WebSocketVRBridge(hmdTracker, computedTrackers, this)
tasks.add(Runnable { wsBridge.startBridge() })
bridges.add(wsBridge)
// Initialize OSC handlers
vrcOSCHandler = VRCOSCHandler(
this,
humanPoseManager,
driverBridge,
configManager.vrConfig.vrcOSC,
computedTrackers
)
vMCHandler = VMCHandler(
this,
humanPoseManager,
configManager.vrConfig.vmc,
computedTrackers
)
// Initialize OSC handlers
vrcOSCHandler = VRCOSCHandler(
this,
humanPoseManager,
driverBridge,
configManager.vrConfig.vrcOSC,
computedTrackers
)
vMCHandler = VMCHandler(
this,
humanPoseManager,
configManager.vrConfig.vmc,
computedTrackers
)
// Initialize OSC router
val oscHandlers = FastList<OSCHandler>()
oscHandlers.add(vrcOSCHandler)
oscHandlers.add(vMCHandler)
oSCRouter = OSCRouter(configManager.vrConfig.oscRouter, oscHandlers)
bvhRecorder = BVHRecorder(this)
registerTracker(hmdTracker)
for (tracker in computedTrackers) {
registerTracker(tracker)
}
}
// Initialize OSC router
val oscHandlers = FastList<OSCHandler>()
oscHandlers.add(vrcOSCHandler)
oscHandlers.add(vMCHandler)
oSCRouter = OSCRouter(configManager.vrConfig.oscRouter, oscHandlers)
bvhRecorder = BVHRecorder(this)
registerTracker(hmdTracker)
for (tracker in computedTrackers) {
registerTracker(tracker)
}
instance = this
}
fun hasBridge(bridgeClass: Class<out Bridge?>): Boolean {
for (bridge in bridges) {
if (bridgeClass.isAssignableFrom(bridge.javaClass)) {
return true
}
}
return false
}
fun hasBridge(bridgeClass: Class<out Bridge?>): Boolean {
for (bridge in bridges) {
if (bridgeClass.isAssignableFrom(bridge.javaClass)) {
return true
}
}
return false
}
@ThreadSafe
fun <E : Bridge?> getVRBridge(bridgeClass: Class<E>): E? {
for (bridge in bridges) {
if (bridgeClass.isAssignableFrom(bridge.javaClass)) {
return bridgeClass.cast(bridge)
}
}
return null
}
@ThreadSafe
fun <E : Bridge?> getVRBridge(bridgeClass: Class<E>): E? {
for (bridge in bridges) {
if (bridgeClass.isAssignableFrom(bridge.javaClass)) {
return bridgeClass.cast(bridge)
}
}
return null
}
fun addOnTick(runnable: Runnable) {
onTick.add(runnable)
}
fun addOnTick(runnable: Runnable) {
onTick.add(runnable)
}
@ThreadSafe
fun addNewTrackerConsumer(consumer: Consumer<Tracker>) {
queueTask {
newTrackersConsumers.add(consumer)
for (tracker in trackers) {
consumer.accept(tracker)
}
}
}
@ThreadSafe
fun addNewTrackerConsumer(consumer: Consumer<Tracker>) {
queueTask {
newTrackersConsumers.add(consumer)
for (tracker in trackers) {
consumer.accept(tracker)
}
}
}
@ThreadSafe
fun trackerUpdated(tracker: Tracker?) {
queueTask {
humanPoseManager.trackerUpdated(tracker)
configManager.vrConfig.writeTrackerConfig(tracker)
configManager.saveConfig()
}
}
@ThreadSafe
fun trackerUpdated(tracker: Tracker?) {
queueTask {
humanPoseManager.trackerUpdated(tracker)
configManager.vrConfig.writeTrackerConfig(tracker)
configManager.saveConfig()
}
}
@ThreadSafe
fun addSkeletonUpdatedCallback(consumer: Consumer<HumanSkeleton?>?) {
queueTask { humanPoseManager.addSkeletonUpdatedCallback(consumer) }
}
@ThreadSafe
fun addSkeletonUpdatedCallback(consumer: Consumer<HumanSkeleton?>?) {
queueTask { humanPoseManager.addSkeletonUpdatedCallback(consumer) }
}
@VRServerThread
override fun run() {
trackersServer.start()
while (true) {
// final long start = System.currentTimeMillis();
fpsTimer.update()
do {
val task = tasks.poll() ?: break
task.run()
} while (true)
for (task in onTick) {
task.run()
}
for (bridge in bridges) {
bridge.dataRead()
}
for (tracker in trackers) {
tracker.tick()
}
humanPoseManager.update()
for (bridge in bridges) {
bridge.dataWrite()
}
vrcOSCHandler.update()
vMCHandler.update()
// final long time = System.currentTimeMillis() - start;
try {
sleep(1) // 1000Hz
} catch (error: InterruptedException) {
LogManager.info("VRServer thread interrupted")
break
}
}
}
@VRServerThread
override fun run() {
trackersServer.start()
while (true) {
// final long start = System.currentTimeMillis();
fpsTimer.update()
do {
val task = tasks.poll() ?: break
task.run()
} while (true)
for (task in onTick) {
task.run()
}
for (bridge in bridges) {
bridge.dataRead()
}
for (tracker in trackers) {
tracker.tick()
}
humanPoseManager.update()
for (bridge in bridges) {
bridge.dataWrite()
}
vrcOSCHandler.update()
vMCHandler.update()
// final long time = System.currentTimeMillis() - start;
try {
sleep(1) // 1000Hz
} catch (error: InterruptedException) {
LogManager.info("VRServer thread interrupted")
break
}
}
}
@ThreadSafe
fun queueTask(r: Runnable) {
tasks.add(r)
}
@ThreadSafe
fun queueTask(r: Runnable) {
tasks.add(r)
}
@VRServerThread
private fun trackerAdded(tracker: Tracker) {
humanPoseManager.trackerAdded(tracker)
}
@VRServerThread
private fun trackerAdded(tracker: Tracker) {
humanPoseManager.trackerAdded(tracker)
}
@ThreadSecure
fun registerTracker(tracker: Tracker) {
configManager.vrConfig.readTrackerConfig(tracker)
queueTask {
trackers.add(tracker)
trackerAdded(tracker)
for (tc in newTrackersConsumers) {
tc.accept(tracker)
}
}
}
@ThreadSecure
fun registerTracker(tracker: Tracker) {
configManager.vrConfig.readTrackerConfig(tracker)
queueTask {
trackers.add(tracker)
trackerAdded(tracker)
for (tc in newTrackersConsumers) {
tc.accept(tracker)
}
}
}
@ThreadSafe
fun updateSkeletonModel() {
queueTask { humanPoseManager.updateSkeletonModelFromServer() }
}
@ThreadSafe
fun updateSkeletonModel() {
queueTask { humanPoseManager.updateSkeletonModelFromServer() }
}
fun resetTrackersFull(resetSourceName: String?) {
queueTask { humanPoseManager.resetTrackersFull(resetSourceName) }
}
fun resetTrackersFull(resetSourceName: String?) {
queueTask { humanPoseManager.resetTrackersFull(resetSourceName) }
}
fun resetTrackersYaw(resetSourceName: String?) {
queueTask { humanPoseManager.resetTrackersYaw(resetSourceName) }
}
fun resetTrackersYaw(resetSourceName: String?) {
queueTask { humanPoseManager.resetTrackersYaw(resetSourceName) }
}
fun resetTrackersMounting(resetSourceName: String?) {
queueTask { humanPoseManager.resetTrackersMounting(resetSourceName) }
}
fun resetTrackersMounting(resetSourceName: String?) {
queueTask { humanPoseManager.resetTrackersMounting(resetSourceName) }
}
fun scheduleResetTrackersFull(resetSourceName: String?, delay: Long) {
val resetTask: TimerTask = object : TimerTask() {
override fun run() {
queueTask { humanPoseManager.resetTrackersFull(resetSourceName) }
}
}
timer.schedule(resetTask, delay)
}
fun scheduleResetTrackersFull(resetSourceName: String?, delay: Long) {
val resetTask: TimerTask = object : TimerTask() {
override fun run() {
queueTask { humanPoseManager.resetTrackersFull(resetSourceName) }
}
}
timer.schedule(resetTask, delay)
}
fun scheduleResetTrackersYaw(resetSourceName: String?, delay: Long) {
val yawResetTask: TimerTask = object : TimerTask() {
override fun run() {
queueTask { humanPoseManager.resetTrackersYaw(resetSourceName) }
}
}
timer.schedule(yawResetTask, delay)
}
fun scheduleResetTrackersYaw(resetSourceName: String?, delay: Long) {
val yawResetTask: TimerTask = object : TimerTask() {
override fun run() {
queueTask { humanPoseManager.resetTrackersYaw(resetSourceName) }
}
}
timer.schedule(yawResetTask, delay)
}
fun scheduleResetTrackersMounting(resetSourceName: String?, delay: Long) {
val resetMountingTask: TimerTask = object : TimerTask() {
override fun run() {
queueTask { humanPoseManager.resetTrackersMounting(resetSourceName) }
}
}
timer.schedule(resetMountingTask, delay)
}
fun scheduleResetTrackersMounting(resetSourceName: String?, delay: Long) {
val resetMountingTask: TimerTask = object : TimerTask() {
override fun run() {
queueTask { humanPoseManager.resetTrackersMounting(resetSourceName) }
}
}
timer.schedule(resetMountingTask, delay)
}
fun setLegTweaksEnabled(value: Boolean) {
queueTask { humanPoseManager.setLegTweaksEnabled(value) }
}
fun setLegTweaksEnabled(value: Boolean) {
queueTask { humanPoseManager.setLegTweaksEnabled(value) }
}
fun setSkatingReductionEnabled(value: Boolean) {
queueTask { humanPoseManager.setSkatingCorrectionEnabled(value) }
}
fun setSkatingReductionEnabled(value: Boolean) {
queueTask { humanPoseManager.setSkatingCorrectionEnabled(value) }
}
fun setFloorClipEnabled(value: Boolean) {
queueTask { humanPoseManager.setFloorClipEnabled(value) }
}
fun setFloorClipEnabled(value: Boolean) {
queueTask { humanPoseManager.setFloorClipEnabled(value) }
}
val trackersCount: Int
get() = trackers.size
val allTrackers: List<Tracker>
get() = FastList(trackers)
val trackersCount: Int
get() = trackers.size
val allTrackers: List<Tracker>
get() = FastList(trackers)
fun getTrackerById(id: TrackerIdT): Tracker? {
for (tracker in trackers) {
if (tracker.trackerNum != id.trackerNum) {
continue
}
fun getTrackerById(id: TrackerIdT): Tracker? {
for (tracker in trackers) {
if (tracker.trackerNum != id.trackerNum) {
continue
}
// Handle synthetic devices
if (id.deviceId == null && tracker.device == null) {
return tracker
}
if (tracker.device != null && id.deviceId != null && id.deviceId.id == tracker.device.id) {
// This is a physical tracker, and both device id and the
// tracker num match
return tracker
}
}
return null
}
// Handle synthetic devices
if (id.deviceId == null && tracker.device == null) {
return tracker
}
if (tracker.device != null && id.deviceId != null && id.deviceId.id == tracker.device.id) {
// This is a physical tracker, and both device id and the
// tracker num match
return tracker
}
}
return null
}
fun clearTrackersDriftCompensation() {
for (t in allTrackers) {
if (t.isImu()) {
t.resetsHandler.clearDriftCompensation()
}
}
}
fun clearTrackersDriftCompensation() {
for (t in allTrackers) {
if (t.isImu()) {
t.resetsHandler.clearDriftCompensation()
}
}
}
companion object {
private val nextLocalTrackerId = AtomicInteger()
@JvmStatic
companion object {
private val nextLocalTrackerId = AtomicInteger()
lateinit var instance: VRServer
private set
@JvmStatic
fun getNextLocalTrackerId(): Int {
return nextLocalTrackerId.incrementAndGet()
}
return nextLocalTrackerId.incrementAndGet()
}
@JvmStatic
@JvmStatic
val currentLocalTrackerId: Int
get() = nextLocalTrackerId.get()
}
get() = nextLocalTrackerId.get()
}
}

View File

@@ -1,6 +1,6 @@
package dev.slimevr.bridge;
import dev.slimevr.Main;
import dev.slimevr.VRServer;
import dev.slimevr.bridge.ProtobufMessages.*;
import dev.slimevr.tracking.trackers.Tracker;
import dev.slimevr.tracking.trackers.TrackerRole;
@@ -203,7 +203,7 @@ public abstract class ProtobufBridge implements Bridge {
if (trackerAdded.getTrackerRole() == TrackerRole.HMD.getId()) {
hmdTracker = tracker;
} else {
Main.getVrServer().registerTracker(tracker);
VRServer.Companion.getInstance().registerTracker(tracker);
}
}
@@ -216,10 +216,10 @@ public abstract class ProtobufBridge implements Bridge {
.warning("[" + bridgeName + "] Received deprecated user action 'calibrate'!");
case "reset":
// TODO : Check pose field
Main.getVrServer().resetTrackersFull(resetSourceName);
VRServer.Companion.getInstance().resetTrackersFull(resetSourceName);
break;
case "fast_reset":
Main.getVrServer().resetTrackersYaw(resetSourceName);
VRServer.Companion.getInstance().resetTrackersYaw(resetSourceName);
break;
}
}

View File

@@ -1,6 +1,6 @@
package dev.slimevr.config
import dev.slimevr.vrServer
import dev.slimevr.VRServer
class DriftCompensationConfig {
@@ -13,7 +13,7 @@ class DriftCompensationConfig {
// Max resets for the calculated average drift
var maxResets = 6
fun updateTrackersDriftCompensation() {
for (t in vrServer.allTrackers) {
for (t in VRServer.instance.allTrackers) {
if (t.allowFiltering) {
t.resetsHandler.readDriftCompensationConfig(this)
}

View File

@@ -1,6 +1,6 @@
package dev.slimevr.config
import dev.slimevr.vrServer
import dev.slimevr.VRServer
class FiltersConfig {
@@ -11,7 +11,7 @@ class FiltersConfig {
var amount = 0.2f
fun updateTrackersFilters() {
for (tracker in vrServer.allTrackers) {
for (tracker in VRServer.instance.allTrackers) {
if (tracker.allowFiltering) {
tracker.filteringHandler.readFilteringConfig(this, tracker.getRawRotation())
}

View File

@@ -1,7 +1,7 @@
package dev.slimevr.filtering
import com.jme3.system.NanoTimer
import dev.slimevr.vrServer
import dev.slimevr.VRServer
import io.github.axisangles.ktmath.Quaternion
import io.github.axisangles.ktmath.Quaternion.Companion.IDENTITY
@@ -27,7 +27,7 @@ class QuaternionMovingAverage(
private var latestQuaternion = IDENTITY
private var smoothingQuaternion = IDENTITY
var filteredQuaternion = IDENTITY
private val fpsTimer: NanoTimer = vrServer.fpsTimer
private val fpsTimer: NanoTimer = VRServer.instance.fpsTimer
private var smoothingCounter = 0
init {

View File

@@ -6,11 +6,13 @@ import com.illposed.osc.argument.handler.Activator;
import java.util.List;
public class OSCStatic {
public static OSCSerializerAndParserBuilder serializer;
static {
// Really hacky workaround for getting the OSC library to work on Android
// Really hacky workaround for getting the OSC library to work on
// Android
// (Removes reference to java.awt.Color)
// https://github.com/hoijui/JavaOSC/issues/60#issuecomment-960713779
OSCSerializerAndParserBuilder serializer = new OSCSerializerAndParserBuilder();

View File

@@ -1,8 +1,6 @@
package dev.slimevr.osc;
import com.illposed.osc.*;
import com.illposed.osc.argument.ArgumentHandler;
import com.illposed.osc.argument.handler.Activator;
import com.illposed.osc.messageselector.OSCPatternAddressMessageSelector;
import com.illposed.osc.transport.OSCPortIn;
import com.illposed.osc.transport.OSCPortOut;

View File

@@ -1,6 +1,5 @@
package dev.slimevr.platform;
import dev.slimevr.Main;
import dev.slimevr.VRServer;
import dev.slimevr.bridge.ProtobufBridge;
import dev.slimevr.bridge.ProtobufMessages;
@@ -83,7 +82,7 @@ public abstract class SteamVRBridge extends ProtobufBridge implements Runnable {
removeSharedTracker(tr);
}
config.setBridgeTrackerRole(role, share);
Main.getVrServer().getConfigManager().saveConfig();
VRServer.Companion.getInstance().configManager.saveConfig();
}
}
}
@@ -92,9 +91,7 @@ public abstract class SteamVRBridge extends ProtobufBridge implements Runnable {
@VRServerThread
protected Tracker createNewTracker(ProtobufMessages.TrackerAdded trackerAdded) {
// Todo: We need the manufacturer
Device device = Main
.getVrServer()
.getDeviceManager()
Device device = VRServer.Companion.getInstance().deviceManager
.createDevice(
trackerAdded.getTrackerName(),
trackerAdded.getTrackerSerial(),
@@ -133,7 +130,7 @@ public abstract class SteamVRBridge extends ProtobufBridge implements Runnable {
);
device.getTrackers().put(0, tracker);
Main.getVrServer().getDeviceManager().addDevice(device);
VRServer.Companion.getInstance().deviceManager.addDevice(device);
TrackerRole role = TrackerRole.getById(trackerAdded.getTrackerRole());
if (role != null) {
tracker.setTrackerPosition(TrackerPosition.getByTrackerRole(role));
@@ -153,7 +150,7 @@ public abstract class SteamVRBridge extends ProtobufBridge implements Runnable {
// devices do not have a tracker voltage.
boolean isCharging = false;
List<Tracker> allTrackers = Main.getVrServer().getAllTrackers();
List<Tracker> allTrackers = VRServer.Companion.getInstance().getAllTrackers();
TrackerRole role = localTracker.getTrackerPosition().getTrackerRole();
Tracker primaryTracker = null;
@@ -350,7 +347,8 @@ public abstract class SteamVRBridge extends ProtobufBridge implements Runnable {
var status = new StatusDataUnion();
status.setType(StatusData.StatusSteamVRDisconnected);
status.setValue(statusData);
lastSteamVRStatus = Main.getVrServer().getStatusSystem().addStatusInt(status, false);
lastSteamVRStatus = VRServer.Companion.getInstance().statusSystem
.addStatusInt(status, false);
}

View File

@@ -1,7 +1,6 @@
package dev.slimevr.platform.linux;
import com.google.protobuf.InvalidProtocolBufferException;
import dev.slimevr.Main;
import dev.slimevr.VRServer;
import dev.slimevr.bridge.BridgeThread;
import dev.slimevr.bridge.ProtobufMessages;
@@ -10,9 +9,7 @@ import dev.slimevr.tracking.trackers.Tracker;
import io.eiren.util.ann.ThreadSafe;
import io.eiren.util.logging.LogManager;
import java.io.File;
import java.io.IOException;
import java.net.StandardProtocolFamily;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.ServerSocketChannel;
@@ -60,7 +57,7 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
this.channel.register(this.selector, SelectionKey.OP_READ);
if (this.channel == null)
continue;
Main.getVrServer().queueTask(this::reconnected);
VRServer.Companion.getInstance().queueTask(this::reconnected);
LogManager
.info(
"["
@@ -80,7 +77,8 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
if (!updated) {
this.waitForData(10);
} else if (lastSteamVRStatus != 0) {
Main.getVrServer().getStatusSystem().removeStatusInt(lastSteamVRStatus);
VRServer.Companion.getInstance().statusSystem
.removeStatusInt(lastSteamVRStatus);
lastSteamVRStatus = 0;
}
} catch (IOException ioError) {
@@ -216,7 +214,7 @@ public class UnixSocketBridge extends SteamVRBridge implements AutoCloseable {
this.channel = null;
this.socketError = false;
this.dst.clear();
Main.getVrServer().queueTask(this::disconnected);
VRServer.Companion.getInstance().queueTask(this::disconnected);
}
private ServerSocketChannel createSocket() throws IOException {

View File

@@ -7,7 +7,6 @@ import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APIOptions;
import dev.slimevr.Main;
import dev.slimevr.VRServer;
import dev.slimevr.bridge.BridgeThread;
import dev.slimevr.bridge.PipeState;
@@ -83,7 +82,8 @@ public class WindowsNamedPipeBridge extends SteamVRBridge {
if (pipe.state == PipeState.OPEN) {
pipesUpdated = updatePipe();
if (lastSteamVRStatus != 0 && pipesUpdated) {
Main.getVrServer().getStatusSystem().removeStatusInt(lastSteamVRStatus);
VRServer.Companion.getInstance().statusSystem
.removeStatusInt(lastSteamVRStatus);
lastSteamVRStatus = 0;
}
updateMessageQueue();
@@ -250,7 +250,7 @@ public class WindowsNamedPipeBridge extends SteamVRBridge {
private void resetPipe() {
WindowsPipe.safeDisconnect(pipe);
pipe.state = PipeState.CREATED;
Main.getVrServer().queueTask(this::disconnected);
VRServer.Companion.getInstance().queueTask(this::disconnected);
}
private void createPipe() throws IOException {
@@ -302,7 +302,7 @@ public class WindowsNamedPipeBridge extends SteamVRBridge {
pipe.state = PipeState.OPEN;
LogManager.info("[" + bridgeName + "] Pipe " + pipe.name + " is open");
Main.getVrServer().queueTask(this::reconnected);
VRServer.Companion.getInstance().queueTask(this::reconnected);
return true;
}

View File

@@ -1,6 +1,6 @@
package dev.slimevr.tracking.processor.config;
import dev.slimevr.Main;
import dev.slimevr.VRServer;
import dev.slimevr.autobone.errors.BodyProportionError;
import dev.slimevr.autobone.errors.proportions.ProportionLimiter;
import dev.slimevr.config.ConfigManager;
@@ -374,9 +374,7 @@ public class SkeletonConfigManager {
// Remove from config to use default if they change in the future.
Arrays.fill(changedToggles, false);
for (SkeletonConfigToggles value : SkeletonConfigToggles.values) {
Main
.getVrServer()
.getConfigManager()
VRServer.Companion.getInstance().configManager
.getVrConfig()
.getSkeleton()
.getToggles()
@@ -399,9 +397,7 @@ public class SkeletonConfigManager {
// Remove from config to use default if they change in the future.
Arrays.fill(changedValues, false);
for (SkeletonConfigValues value : SkeletonConfigValues.values) {
Main
.getVrServer()
.getConfigManager()
VRServer.Companion.getInstance().configManager
.getVrConfig()
.getSkeleton()
.getValues()
@@ -488,11 +484,10 @@ public class SkeletonConfigManager {
}
public void save() {
dev.slimevr.config.SkeletonConfig skeletonConfig = Main
.getVrServer()
.getConfigManager()
.getVrConfig()
.getSkeleton();
dev.slimevr.config.SkeletonConfig skeletonConfig = VRServer.Companion
.getInstance().configManager
.getVrConfig()
.getSkeleton();
// Write all possible values to keep consistent even if defaults changed
for (SkeletonConfigOffsets value : SkeletonConfigOffsets.values) {

View File

@@ -23,7 +23,6 @@ import io.github.axisangles.ktmath.Vector3;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class HumanSkeleton {
@@ -179,8 +178,8 @@ public class HumanSkeleton {
this,
humanPoseManager,
server.configManager.getVrConfig().getTapDetection(),
server.resetHandler,
server.tapSetupHandler,
server.resetHandler,
server.tapSetupHandler,
server.getAllTrackers()
);
legTweaks.setConfig(server.configManager.getVrConfig().getLegTweaks());

View File

@@ -1,9 +1,9 @@
package dev.slimevr.tracking.trackers
import dev.slimevr.VRServer
import dev.slimevr.config.TrackerConfig
import dev.slimevr.tracking.trackers.TrackerPosition.Companion.getByDesignation
import dev.slimevr.tracking.trackers.udp.IMUType
import dev.slimevr.vrServer
import io.eiren.util.BufferedTimer
import io.github.axisangles.ktmath.Quaternion
import io.github.axisangles.ktmath.Vector3
@@ -64,7 +64,7 @@ class Tracker @JvmOverloads constructor(
// If the status of a non-internal tracker has changed, inform
// the VRServer to recreate the skeleton, as it may need to
// assign or un-assign the tracker to a body part
vrServer.updateSkeletonModel()
VRServer.instance.updateSkeletonModel()
checkReportErrorStatus()
checkReportRequireReset()
@@ -106,7 +106,7 @@ class Tracker @JvmOverloads constructor(
if (needsReset && trackerPosition != null && lastResetStatus == 0u && status.sendData) {
reportRequireReset()
} else if (lastResetStatus != 0u && (trackerPosition == null || !status.sendData)) {
vrServer.statusSystem.removeStatus(lastResetStatus)
VRServer.instance.statusSystem.removeStatus(lastResetStatus)
lastResetStatus = 0u
}
}
@@ -133,14 +133,14 @@ class Tracker @JvmOverloads constructor(
type = StatusData.StatusTrackerReset
value = statusMsg
}
lastResetStatus = vrServer.statusSystem.addStatus(status, true)
lastResetStatus = VRServer.instance.statusSystem.addStatus(status, true)
}
private fun checkReportErrorStatus() {
if (status == TrackerStatus.ERROR && lastErrorStatus == 0u) {
reportErrorStatus()
} else if (lastErrorStatus != 0u && status != TrackerStatus.ERROR) {
vrServer.statusSystem.removeStatus(lastErrorStatus)
VRServer.instance.statusSystem.removeStatus(lastErrorStatus)
lastErrorStatus = 0u
}
}
@@ -164,7 +164,7 @@ class Tracker @JvmOverloads constructor(
type = StatusData.StatusTrackerError
value = statusMsg
}
lastErrorStatus = vrServer.statusSystem.addStatus(status, true)
lastErrorStatus = VRServer.instance.statusSystem.addStatus(status, true)
}
/**
@@ -183,8 +183,8 @@ class Tracker @JvmOverloads constructor(
if (this.isImu() && config.allowDriftCompensation == null) {
// If value didn't exist, default to true and save
resetsHandler.allowDriftCompensation = true
vrServer.configManager.vrConfig.getTracker(this).allowDriftCompensation = true
vrServer.configManager.saveConfig()
VRServer.instance.configManager.vrConfig.getTracker(this).allowDriftCompensation = true
VRServer.instance.configManager.saveConfig()
} else {
config.allowDriftCompensation?.let {
resetsHandler.allowDriftCompensation = it

View File

@@ -1,9 +1,9 @@
package dev.slimevr.tracking.trackers
import com.jme3.math.FastMath
import dev.slimevr.VRServer
import dev.slimevr.config.DriftCompensationConfig
import dev.slimevr.filtering.CircularArrayList
import dev.slimevr.vrServer
import io.github.axisangles.ktmath.EulerAngles
import io.github.axisangles.ktmath.EulerOrder
import io.github.axisangles.ktmath.Quaternion
@@ -161,7 +161,7 @@ class TrackerResetsHandler(val tracker: Tracker) {
calculateDrift(rot)
if (this.tracker.lastResetStatus != 0u) {
vrServer.statusSystem.removeStatus(this.tracker.lastResetStatus)
VRServer.instance.statusSystem.removeStatus(this.tracker.lastResetStatus)
this.tracker.lastResetStatus = 0u
}
}

View File

@@ -5,7 +5,6 @@ import dev.slimevr.NetworkProtocol
import dev.slimevr.VRServer
import dev.slimevr.tracking.trackers.Tracker
import dev.slimevr.tracking.trackers.TrackerStatus
import dev.slimevr.vrServer
import io.eiren.util.Util
import io.eiren.util.collections.FastList
import io.eiren.util.logging.LogManager
@@ -66,7 +65,7 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
handshake.boardType,
handshake.mcuType
)
vrServer.deviceManager.addDevice(connection)
VRServer.instance.deviceManager.addDevice(connection)
connection.firmwareBuild = handshake.firmwareBuild
connection.protocol = if (handshake.firmware?.isEmpty() == true) {
// Only old owoTrack doesn't report firmware and have different packet IDs with SlimeVR
@@ -145,7 +144,7 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
connection,
VRServer.getNextLocalTrackerId(),
connection.name + "/" + trackerId,
"IMU Tracker #" + VRServer.getCurrentLocalTrackerId(),
"IMU Tracker #" + VRServer.currentLocalTrackerId,
null,
trackerNum = trackerId,
hasRotation = true,
@@ -366,22 +365,23 @@ class TrackersUDPServer(private val port: Int, name: String, private val tracker
when (packet.type) {
UDPPacket21UserAction.RESET_FULL -> {
name = "Full"
vrServer.resetHandler.sendStarted(ResetType.Full)
vrServer.resetTrackersFull(resetSourceName)
VRServer.instance.resetHandler.sendStarted(ResetType.Full)
VRServer.instance.resetTrackersFull(resetSourceName)
}
UDPPacket21UserAction.RESET_YAW -> {
name = "Yaw"
vrServer.resetHandler.sendStarted(ResetType.Yaw)
vrServer.resetTrackersYaw(resetSourceName)
VRServer.instance.resetHandler.sendStarted(ResetType.Yaw)
VRServer.instance.resetTrackersYaw(resetSourceName)
}
UDPPacket21UserAction.RESET_MOUNTING -> {
name = "Mounting"
vrServer
VRServer
.instance
.resetHandler
.sendStarted(ResetType.Mounting)
vrServer.resetTrackersMounting(resetSourceName)
VRServer.instance.resetTrackersMounting(resetSourceName)
}
}

View File

@@ -2,7 +2,6 @@ package dev.slimevr.websocketapi;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import dev.slimevr.Main;
import dev.slimevr.VRServer;
import dev.slimevr.bridge.Bridge;
import dev.slimevr.tracking.trackers.Tracker;
@@ -200,8 +199,10 @@ public class WebSocketVRBridge extends WebsocketAPI implements Bridge {
private void parseAction(ObjectNode json, WebSocket conn) {
switch (json.get("name").asText()) {
case "calibrate" -> Main.getVrServer().resetTrackersYaw(resetSourceName);
case "full_calibrate" -> Main.getVrServer().resetTrackersFull(resetSourceName);
case "calibrate" -> VRServer.Companion.getInstance().resetTrackersYaw(resetSourceName);
case "full_calibrate" -> VRServer.Companion
.getInstance()
.resetTrackersFull(resetSourceName);
}
}

View File

@@ -10,7 +10,6 @@ import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.nio.file.Path;
public class LogManager {

View File

@@ -16,7 +16,6 @@ import io.github.axisangles.ktmath.Vector3;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;

View File

@@ -79,7 +79,7 @@ tasks.shadowJar {
archiveVersion.set("")
}
application {
mainClass.set("dev.slimevr.Main")
mainClass.set("dev.slimevr.desktop.Main")
}
fun String.runCommand(currentWorkingDir: File = file("./")): String {