Files
blender-portable-repo/scripts/addons/rokoko-studio-live-blender-master/operators/receiver.py
T
2026-03-17 14:58:51 -06:00

101 lines
2.9 KiB
Python

import bpy
import time
from threading import Thread
from ..core import state_manager
from ..core.receiver import Receiver
from ..core.utils import ui_refresh_all
from ..core.animations import clear_animations
timer = None
receiver: Receiver = Receiver()
receiver_enabled = False
class ReceiverStart(bpy.types.Operator):
bl_idname = "rsl.receiver_start"
bl_label = "Start Receiver"
bl_description = "Start receiving data from Rokoko Studio"
bl_options = {'INTERNAL'}
def modal(self, context, event):
# If ECS or F8 is pressed, cancel
if event.type == 'ESC' or event.type == 'F8' or not receiver_enabled:
return self.cancel(context)
# This gets run every frame
if event.type == 'TIMER':
if bpy.context.screen.is_animation_playing:
return self.cancel(context)
receiver.run()
return {'PASS_THROUGH'}
def execute(self, context):
global receiver_enabled, receiver, timer
# Start the receiver
try:
receiver.start(context.scene.rsl_receiver_port)
except OSError as e:
print('Socket error:', e.strerror)
self.report({'ERROR'}, 'This port is already in use!')
return {'CANCELLED'}
receiver_enabled = True
# If animation is currently playing, stop it
if context.screen.is_animation_playing:
bpy.ops.screen.animation_play()
# Clear current live data
clear_animations()
# Save the scene
state_manager.save_scene()
# Register this classes modal operator in Blenders event handling system and execute it at the specified fps
context.window_manager.modal_handler_add(self)
timer = context.window_manager.event_timer_add(1 / context.scene.rsl_receiver_fps, window=bpy.context.window)
return {'RUNNING_MODAL'}
def cancel(self, context):
ReceiverStart.force_disable()
ui_refresh_all()
return {'CANCELLED'}
@classmethod
def force_disable(cls):
global receiver_enabled, receiver, timer
receiver_enabled = False
receiver.stop()
bpy.context.window_manager.event_timer_remove(timer)
# If the recording is still running, let it load the scene afterwards with a delay
if bpy.context.scene.rsl_recording:
bpy.context.scene.rsl_recording = False
thread = Thread(target=load_scene_later, args=[])
thread.start()
else:
state_manager.load_scene()
def load_scene_later():
time.sleep(0.04)
state_manager.load_scene()
class ReceiverStop(bpy.types.Operator):
bl_idname = "rsl.receiver_stop"
bl_label = "Stop Receiver"
bl_description = "Stop receiving data from Rokoko Studio"
bl_options = {'INTERNAL'}
def execute(self, context):
global receiver_enabled
receiver_enabled = False
return {'FINISHED'}