From 2242b4d56e9549310df21cff76a524528b92cac5 Mon Sep 17 00:00:00 2001 From: Sebastian Pape <Sebastian.Pape@rwth-aachen.de> Date: Thu, 17 Oct 2019 13:11:32 +0200 Subject: [PATCH] Added support for two screen mode --- LaunchConfig/twoscreen.cfg | 215 ++++++++++++++++++ .../Private/NDisplayLaunchButton.cpp | 24 +- .../Public/NDisplayLaunchButtonSettings.h | 15 ++ 3 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 LaunchConfig/twoscreen.cfg diff --git a/LaunchConfig/twoscreen.cfg b/LaunchConfig/twoscreen.cfg new file mode 100644 index 0000000..47d81cc --- /dev/null +++ b/LaunchConfig/twoscreen.cfg @@ -0,0 +1,215 @@ +##################################################################### +# nDisplay config file for aixCAVE +##################################################################### + +##################################################################### +# Config info +#******************************************************************** +# This is a config file header. +# +# Properties: +# version - specifies the version of the configuration file (UE4.xx) +#******************************************************************** +[info] version=22 + +##################################################################### +# Cluster nodes +#******************************************************************** +# Cluster node is an application instance. It's allowed to use +# multiple instances on the same PC. Sometimes its necessary. +# +# Properties: +# id - Unique node name +# window - Window ID +# addr - Network address (IPv4 only) +# master - Specifies if current node is master; default is 'false' +# port_cs - Cluster Synchronization port (required on master node only) +# port_ss - Swap Synchronization port (required on master node only) +# port_ce - Cluster Events port (required on master node only) +# +# Optional properties: +# eye_swap - Swap eyes for this node; default is 'false' +# sound - turns on/off sound for this application instance; default is 'false' +#******************************************************************** +[cluster_node] id=node_left addr=127.0.0.1 window=wnd_left port_cs=41001 port_ss=41002 port_ce=41003 master=true sound=true +[cluster_node] id=node_right addr=127.0.0.1 window=wnd_right + +##################################################################### +# Application windows +#******************************************************************** +# The window entitty defines properties of application's game window. +# +# Properties: +# id - Unique window name +# fullscreen - Fullscreen or windowed mode +# winx - X location +# winy - Y location +# resx - Width +# resy - Height +# viewports - Array of viewports +#******************************************************************** + +[window] id=wnd_left viewports=vp_left +[window] id=wnd_right viewports=vp_right + +##################################################################### +# Projection screens +#******************************************************************** +# Projection screen is a rectangle which determines the camera frustum. +# Usually the projection screen has the same dimensions as an output +# display but in some cases it may differ. +# +# Properties: +# id - unique projection screen name +# loc - relative location to the parent component. Location is relative +# to the VR root if no parent specified. The pivot is a screen's +# center and the values are in meters. +# rot - relative rotation to the parent component. Rotation is relative +# to the VR root if no parent specified. The pivot is a screen's +# center and the values are in degrees. +# size - width (X) and height (Y) of the screen. Values are in meters. +# +# Optional properties: +# parent - ID of parent component in VR hierarchy; default is VR root. +# tracker_id - ID of tracking device; no tracking by default. +# tracker_ch - ID of tracking device's channel; no tracking by default. +#******************************************************************** + +[screen] id=screen_left loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=2.0,Y=2.0" parent=loc_left +[screen] id=screen_right loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" size="X=2.0,Y=2.0" parent=loc_right + +##################################################################### +# Viewports +#******************************************************************** +# Viewport is a rectangle area of game window where rendered frame is +# mapped. Usually the viewport starts at 0:0 and has the same size as +# its parent window but in some cases these settings may differ. +# +# Properties: +# id - unique viewport name +# x - X coordinate of viewport's top left corner +# y - Y coordinate of viewport's top left corner +# width - width of viewport in pixels +# height - height of viewport in pixels +#******************************************************************** + +[viewport] id=vp_left screen=screen_left x=0 y=0 width=480 height=480 +[viewport] id=vp_right screen=screen_right x=0 y=0 width=480 height=480 + +##################################################################### +# Cameras +#******************************************************************** +# Camera is a predefined point frome where the stereoscopic view built. +# It's possible to define multiple cameras and swith the active one +# during runtime. You're free to attach any camera to a tracking device +# for head tracking. Consider a camera as a viewer's head. +# +# Properties: +# id - unique camera name +# loc - relative location to the parent component. Location is relative +# to the VR root if no parent specified. +# rot - relative rotation to the parent component. Rotation is relative +# to the VR root if no parent specified. +# +# Optional properties: +# parent - ID of parent component in VR hierarchy; default is VR root. +# tracker_id - ID of tracking device; no tracking by default. +# tracker_ch - ID of tracking device's channel; no tracking by default. +#******************************************************************** + +[camera] id=camera_dynamic loc="X=0,Y=0,Z=0" parent=shutter_glasses + +##################################################################### +# Scene nodes (hierarchy transforms) +#******************************************************************** +# Scene node is an actor component which is basically a transformation +# matrix. Scene nodes can be helpful to build a component hierarchy, to +# define some special places (like a socket) within VR space. +# +# It might be difficult to understand what VR space origin is. Consider +# it as a point in space where VR space starts. Any componenent listed +# in this config file is relative to its parent or this origin. +# +# Properties: +# id - unique scene node name +# loc - relative location to the parent component. Location is relative +# to the VR root if no parent specified. +# rot - relative rotation to the parent component. Rotation is relative +# to the VR root if no parent specified. +# +# Optional properties: +# parent - ID of parent component in VR hierarchy; default is VR root. +# tracker_id - ID of tracking device; no tracking by default. +# tracker_ch - ID of tracking device's channel; no tracking by default. +#******************************************************************** + +[scene_node] id=cave_origin loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" +[scene_node] id=cave_center loc="X=0,Y=0,Z=1.65" rot="P=0,Y=0,R=0" parent=cave_origin +[scene_node] id=flystick loc="X=0,Y=0,Z=0" rot="P=0,Y=0,R=0" parent=cave_origin +[scene_node] id=shutter_glasses loc="X=0,Y=0,Z=1.65" rot="P=0,Y=0,R=0" parent=cave_origin + + +[scene_node] id=loc_left loc="X=2.0,Y=-1.0,Z=0.01" rot="P=0,Y=0,R=0" parent=cave_center +[scene_node] id=loc_right loc="X=2.0,Y=1.0,Z=0.01" rot="P=0,Y=0,R=0" parent=cave_center + +##################################################################### +# Input devices +#******************************************************************** +# Input devices are VRPN devices. The nDisplay supports the following +# types: analog, button and tracker. Many of physical input devices +# can be connected via VRPN. +# +# Properties: +# id - nique device name +# type - VRPN type (analog, button or tracker). +# addr - address of a VRPN server which handles this particular device. +# The value must match the following format: DEVICENAME@SERVER_ADDRESS +# where DEVICENAME is a VRPN name of this device and SERVER_ADDRESS +# is IPv4 address of VRPN server. +# loc - relative location to the parent component. Location is relative +# to the VR root if no parent specified. +# rot - relative rotation to the parent component. Rotation is relative +# to the VR root if no parent specified. +# +# front (tracker only) - mapping of a tracking system axis to X axis of VR origin +# right (tracker only) - mapping of a tracking system axis to Y axis of VR origin +# up (tracker only) - mapping of a tracking system axis to Z axis of VR origin +# * The following values are allowed for axes mapping: X, -X, Y, -Y, Z, -Z +# +# Optional properties: +# remap - VRPN device channel remapping. Value format is: "from0:to0,from1:to1,...,fromN:toN". +# For example: remap="0:3,1:4,5:2" +#******************************************************************** + +##################################################################### +# Stereoscopic settings +#******************************************************************** +# Properties: +# eye_dist - interoccular distance in meters +[stereo] eye_dist=0.064 +##################################################################### +# General settings +#******************************************************************** +# Properties: +# swap_sync_policy - swap synchronization policy +# - 0 - no synchronization +# - 1 - software swap synchronization +# - 2 - NV swap lock (Nvidia cards only, OpenGL only) +[general] swap_sync_policy=1 + +##################################################################### +# Network settings +#******************************************************************** +# Optional properties: +# cln_conn_tries_amount - how many times a client tries to connect to a server +# cln_conn_retry_delay - delay before next client connection try (milliseconds) +# game_start_timeout - timeout before all data is loaded and game started (milliseconds) +# barrier_wait_timeout - barrier timeout for both game and render threads (milliseconds) +[network] cln_conn_tries_amount=300 cln_conn_retry_delay=1000 game_start_timeout=60000 barrier_wait_timeout=60000 + +##################################################################### +# Custom arguments +#******************************************************************** +# Any custom arguments available in runtime can be specified here. +# Format: ARG_NAME=ARG_VAL +[custom] Hardware_Platform=TwoScreen diff --git a/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp b/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp index 5b89b28..f6da583 100644 --- a/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp +++ b/Source/NDisplayLaunchButton/Private/NDisplayLaunchButton.cpp @@ -86,7 +86,7 @@ void FNDisplayLaunchButtonModule::PluginButtonClicked() const int Num_Nodes = 5; FString Windows_Node_Specific_Commands[Num_Nodes] = { - "dc_node=node_floor WinX=720 WinY=300 ResX=480 ResY=480" + ((Settings->MiniCAVELogToProjectDir) ? (" -log ABSLOG=" + FPaths::ProjectDir() + "\\MiniCaveMulti.log") : "") + " " + Settings->MiniCAVEAdditionalLaunchParametersMaster, + "dc_node=node_floor WinX=720 WinY=300 ResX=480 ResY=480" + ((Settings->MiniCAVELogToProjectDir) ? (" -log ABSLOG=" + FPaths::ProjectDir() + "\\MiniCave.log") : "") + " " + Settings->MiniCAVEAdditionalLaunchParametersMaster, "dc_node=node_front WinX=720 WinY=0 ResX=480 ResY=300", "dc_node=node_left WinX=420 WinY=300 ResX=300 ResY=480", "dc_node=node_right WinX=1200 WinY=300 ResX=300 ResY=480", @@ -98,7 +98,27 @@ void FNDisplayLaunchButtonModule::PluginButtonClicked() { Processes[i] = FPlatformProcess::CreateProc(*EditorExecutable, *(Parameters + " " + Windows_Node_Specific_Commands[i]), true, false, false, nullptr, 0, nullptr, nullptr); } - FPlatformProcess::WaitForProc(Processes[Num_Nodes - 1]); //wait for only one of them + FPlatformProcess::WaitForProc(Processes[0]); //wait for only one of them + } + + if (Settings->LaunchType == ButtonLaunchType_TWO_SCREEN) + { + FString Config = IPluginManager::Get().FindPlugin("NDisplayLaunchButton")->GetBaseDir() + "/LaunchConfig/twoscreen.cfg"; + FString EditorExecutable = "UE4Editor.exe"; + FString Parameters = "\"" + FPaths::GetProjectFilePath() + "\" -game dc_cfg=\"" + Config + "\" " + Settings->TwoScreenLaunchParameters; + + const int Num_Nodes = 2; + FString Windows_Node_Specific_Commands[Num_Nodes] = { + "dc_node=node_left WinX=200 WinY=200 ResX=480 ResY=480" + ((Settings->TwoScreenLogToProjectDir) ? (" -log ABSLOG=" + FPaths::ProjectDir() + "\\TwoScreenL.log") : "") + " " + Settings->MiniCAVEAdditionalLaunchParametersMaster, + "dc_node=node_right WinX=682 WinY=200 ResX=480 ResY=480 -log ABSLOG=" + FPaths::ProjectDir() + "\\TwoScreenR.log" + }; + + FProcHandle Processes[Num_Nodes]; + for (int i = 0; i < Num_Nodes; i++) + { + Processes[i] = FPlatformProcess::CreateProc(*EditorExecutable, *(Parameters + " " + Windows_Node_Specific_Commands[i]), true, false, false, nullptr, 0, nullptr, nullptr); + } + FPlatformProcess::WaitForProc(Processes[0]); //wait for only one of them } if (Settings->LaunchType == ButtonLaunchType_CAVE) diff --git a/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h b/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h index fbded7a..90e10af 100644 --- a/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h +++ b/Source/NDisplayLaunchButton/Public/NDisplayLaunchButtonSettings.h @@ -19,6 +19,7 @@ enum ButtonLaunchType { ButtonLaunchType_NONE UMETA(DisplayName = "Nothing"), ButtonLaunchType_MiniCAVE UMETA(DisplayName = "MiniCAVE"), + ButtonLaunchType_TWO_SCREEN UMETA(DisplayName = "Two Screen"), ButtonLaunchType_CAVE UMETA(DisplayName = "CAVE"), ButtonLaunchType_ROLV UMETA(DisplayName = "ROLV") }; @@ -32,6 +33,16 @@ public: UPROPERTY(EditAnywhere, config, Category = "General", meta = (DisplayName = "Start ")) TEnumAsByte<ButtonLaunchType> LaunchType = ButtonLaunchType_MiniCAVE; + /* + * TwoScreen Options + */ + UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen", meta = (DisplayName = "Launch Parameters")) + FString TwoScreenLaunchParameters = "-dc_cluster -dc_dev_mono -windowed -fixedseed -notexturestreaming -opengl4"; + UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen", meta = (DisplayName = "Additioanl Launch Parameters for Master")) + FString TwoScreenAdditionalLaunchParametersMaster = ""; + UPROPERTY(EditAnywhere, config, Category = "General|TwoScreen", meta = (DisplayName = "Write Log to Project Directory")) + bool TwoScreenLogToProjectDir = true; + /* * Mini CAVE Options */ @@ -89,6 +100,10 @@ public: const bool ParentVal = Super::CanEditChange(InProperty); //TODO: This Code is not executed for all FFilePath Properties. Check if this works in 4.23 with the EditCondition Parser and remove this method + + PROPERTY_CONDITION_CHECK(TwoScreenLaunchParameters, LaunchType == ButtonLaunchType_TWO_SCREEN) + PROPERTY_CONDITION_CHECK(TwoScreenAdditionalLaunchParametersMaster, LaunchType == ButtonLaunchType_TWO_SCREEN) + PROPERTY_CONDITION_CHECK(TwoScreenLogToProjectDir, LaunchType == ButtonLaunchType_TWO_SCREEN) PROPERTY_CONDITION_CHECK(MiniCAVELaunchParameters, LaunchType == ButtonLaunchType_MiniCAVE) PROPERTY_CONDITION_CHECK(MiniCAVEAdditionalLaunchParametersMaster, LaunchType == ButtonLaunchType_MiniCAVE) -- GitLab