public static void SetManager(PhysicalDisplay physicalDisplay, PhysicalDisplayManager oldManager, PhysicalDisplayManager newManager, string undoName = "Set Manager") { //the SetDirty calls might not be necessary... Undo.SetCurrentGroupName(undoName); //remove from old manager if (oldManager) { Undo.RecordObject(oldManager, "Remove Display"); oldManager.RemoveDisplay(physicalDisplay); EditorUtility.SetDirty(oldManager); } //set manager on display Undo.RecordObject(physicalDisplay, "Set New Manager"); physicalDisplay.manager = newManager; EditorUtility.SetDirty(physicalDisplay); //add to new manager if (newManager) { Undo.RecordObject(newManager, "Add Display"); newManager.AddDisplay(physicalDisplay); EditorUtility.SetDirty(newManager); } Undo.CollapseUndoOperations(Undo.GetCurrentGroup()); }
public bool AddDisplay(PhysicalDisplay physicalDisplay) { if (!displays.Contains(physicalDisplay)) { displays.Add(physicalDisplay); return(true); } else { return(false); } }
void Start() { PhysicalDisplay disp = this.display = gameObject.GetComponent <PhysicalDisplay>(); disp.transform.localPosition = disp.transform.localPosition + disp.transform.right.normalized * (rightBlend - leftBlend) * disp.halfWidth() * 0.5f + disp.transform.up.normalized * (topBlend - bottomBlend) * disp.halfHeight() * 0.5f; Vector2 shift = new Vector2((leftBlend + rightBlend) * disp.halfWidth(), (bottomBlend + topBlend) * disp.halfHeight()); disp.width += shift.x; disp.height += shift.y; }
void Update() { if (!initialized) { if (GetComponent <PhysicalDisplay>().Initialized()) { LoadCalibrations(); SetupPostProcessing(); initialized = true; } } else { PhysicalDisplay display = GetComponent <PhysicalDisplay>(); } }
void LoadSettingsChildren_h(GameObject it = null) { if (it == null) { it = gameObject; } for (int i = 0; i < it.transform.childCount; i++) { GameObject child = it.transform.GetChild(i).gameObject; PhysicalDisplay physicalDisplay = GetComponent <PhysicalDisplay>(); if (physicalDisplay) { physicalDisplay.TryToDeSerialize(settingsToLoad); } LoadSettingsChildren_h(child); } }
/// <summary> /// Recursively searches child tree for PhysicalDisplays and PhysicalDisplayManagers and adds them to the provided lists. /// </summary> /// <param name="it">Start iterating from</param> /// <param name="displays">List of displays to add to</param> /// <param name="managers">List of managers to add to</param> private static void IterateAllRelevantChildren(GameObject it, List <PhysicalDisplay> displays, List <PhysicalDisplayManager> managers) { for (int i = 0; i < it.transform.childCount; i++) { GameObject child = it.transform.GetChild(i).gameObject; PhysicalDisplay pd = child.GetComponent <PhysicalDisplay>(); if (pd) { displays.Add(pd); } PhysicalDisplayManager pdm = child.GetComponent <PhysicalDisplayManager>(); if (pdm) { managers.Add(pdm); } IterateAllRelevantChildren(child, displays, managers); } }
void OnDrawGizmosSelected() { #if UNITY_EDITOR if (EditorApplication.isPlaying) { return; } #endif PhysicalDisplay disp = GetComponent <PhysicalDisplay>(); if (leftBlend != 0) { Gizmos.color = Color.red; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(-1.0f - leftBlend, 1.0f)), disp.ScreenspaceToWorld(new Vector2(-1.0f - leftBlend, -1.0f))); Gizmos.color = Color.blue; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(-1.0f + leftBlend, 1.0f)), disp.ScreenspaceToWorld(new Vector2(-1.0f + leftBlend, -1.0f))); } if (topBlend != 0) { Gizmos.color = Color.red; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(-1.0f, 1.0f + topBlend)), disp.ScreenspaceToWorld(new Vector2(1.0f, 1.0f + topBlend))); Gizmos.color = Color.blue; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(-1.0f, 1.0f - topBlend)), disp.ScreenspaceToWorld(new Vector2(1.0f, 1.0f - topBlend))); } if (rightBlend != 0) { Gizmos.color = Color.red; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(1.0f + rightBlend, 1.0f)), disp.ScreenspaceToWorld(new Vector2(1.0f + rightBlend, -1.0f))); Gizmos.color = Color.blue; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(1.0f - rightBlend, 1.0f)), disp.ScreenspaceToWorld(new Vector2(1.0f - rightBlend, -1.0f))); } if (bottomBlend != 0) { Gizmos.color = Color.red; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(-1.0f, -1.0f - bottomBlend)), disp.ScreenspaceToWorld(new Vector2(1.0f, -1.0f - bottomBlend))); Gizmos.color = Color.blue; Gizmos.DrawLine(disp.ScreenspaceToWorld(new Vector2(-1.0f, -1.0f + bottomBlend)), disp.ScreenspaceToWorld(new Vector2(1.0f, -1.0f + bottomBlend))); } }
/// <summary> /// helper function to assign this manager to all its children /// </summary> /// <param name="it">initial object to recursively iterate through</param> void AssignManagerChildren_h(GameObject it = null) { if (it == null) { it = gameObject; } for (int i = 0; i < it.transform.childCount; i++) { GameObject child = it.transform.GetChild(i).gameObject; PhysicalDisplay disp = child.GetComponent <PhysicalDisplay>(); if (disp != null) { if (disp.manager != null) { disp.manager.displays.Remove(disp); } RemoveDisplay(disp); disp.manager = this; AddDisplay(disp); } AssignManagerChildren_h(child); } }
public override void OnInspectorGUI() { serializedObject.Update(); //draw manager SerializedProperty manager = serializedObject.FindProperty(nameof(PhysicalDisplay.manager)); //cache original manager in case it changes PhysicalDisplayManager oldManager = manager.objectReferenceValue as PhysicalDisplayManager; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(manager); bool managerChanged = EditorGUI.EndChangeCheck(); PhysicalDisplayManager newManager = manager.objectReferenceValue as PhysicalDisplayManager; //draw machine name (only if there is no manager) SerializedProperty oldMachineName = serializedObject.FindProperty(nameof(PhysicalDisplay.oldMachineName)); SerializedProperty machineNameAsset = serializedObject.FindProperty(nameof(PhysicalDisplay.machineNameAsset)); if (!newManager) { MachineName.DrawDeprecatedMachineName(oldMachineName, machineNameAsset, "Machine Name"); } //draw display width, height SerializedProperty width = serializedObject.FindProperty(nameof(PhysicalDisplay.width)); SerializedProperty height = serializedObject.FindProperty(nameof(PhysicalDisplay.height)); EditorGUILayout.PropertyField(width); EditorGUILayout.PropertyField(height); //draw head configuration SerializedProperty head = serializedObject.FindProperty(nameof(PhysicalDisplay.head)); EditorGUILayout.PropertyField(head); //draw XR camera settings toggle SerializedProperty useXRCameras = serializedObject.FindProperty(nameof(PhysicalDisplay.useXRCameras)); GUIContent useXRCameras_content = new GUIContent(text: "Use XR Cameras (Quad Buffer)", tooltip: "Whether the cameras associated with this display should output to an XR device (such as headset or quad-buffered stereo 3D display).\n" + "If you do post processing on the cameras (such as a PhysicalDisplayCalibration) set this to false.\n" + "This is probably also unnecessary if using a Dual-Pipe 3D display."); EditorGUILayout.PropertyField(useXRCameras, useXRCameras_content); //draw render texture settings toggle SerializedProperty useRenderTextures = serializedObject.FindProperty(nameof(PhysicalDisplay.useRenderTextures)); GUIContent useRenderTextures_content = new GUIContent(text: "Use Render Textures", tooltip: "Render to render textures instead of screen, for post processing"); EditorGUILayout.PropertyField(useRenderTextures, useRenderTextures_content); //draw render texture settings if render textures are enabled SerializedProperty renderTextureSize = serializedObject.FindProperty(nameof(PhysicalDisplay.renderTextureSize)); if (useRenderTextures.boolValue) { EditorGUILayout.PropertyField(renderTextureSize); } //draw exclusive fullscreen toggle if render textures are disabled and there is no manager SerializedProperty exclusiveFullscreen = serializedObject.FindProperty(nameof(PhysicalDisplay.exclusiveFullscreen)); SerializedProperty display = serializedObject.FindProperty(nameof(PhysicalDisplay.display)); if (!useRenderTextures.boolValue && !newManager) { GUIContent exclusiveFullscreen_content = new GUIContent(text: "Use Specific Display"); EditorGUILayout.PropertyField(exclusiveFullscreen, exclusiveFullscreen_content); //draw display if exclusive fullscreen is enabled if (exclusiveFullscreen.boolValue) { EditorGUILayout.PropertyField(display); } } //force exclusive fullscreen mode off if there is a manager if (newManager && exclusiveFullscreen.boolValue) { exclusiveFullscreen.boolValue = false; } //draw 3D settings SerializedProperty is3D = serializedObject.FindProperty(nameof(PhysicalDisplay.is3D)); SerializedProperty dualPipe = serializedObject.FindProperty(nameof(PhysicalDisplay.dualPipe)); SerializedProperty dualInstance = serializedObject.FindProperty(nameof(PhysicalDisplay.dualInstance)); SerializedProperty windowBounds = serializedObject.FindProperty(nameof(PhysicalDisplay.windowBounds)); EditorGUILayout.PropertyField(is3D); if (is3D.boolValue) { //draw dual pipe toggle EditorGUILayout.PropertyField(dualPipe); if (dualPipe.boolValue) { //draw dual pipe settings SerializedProperty leftViewport = serializedObject.FindProperty(nameof(PhysicalDisplay.leftViewport)); SerializedProperty rightViewport = serializedObject.FindProperty(nameof(PhysicalDisplay.rightViewport)); EditorGUILayout.PropertyField(dualInstance); if (!exclusiveFullscreen.boolValue && !dualInstance.boolValue) { //3D, dual pipe, and single instance EditorGUILayout.PropertyField(windowBounds); } EditorGUILayout.PropertyField(leftViewport); EditorGUILayout.PropertyField(rightViewport); } else { //draw window settings EditorGUILayout.PropertyField(windowBounds); if (dualInstance.boolValue) { dualInstance.boolValue = false; } } } else { //draw window settings EditorGUILayout.PropertyField(windowBounds); if (dualPipe.boolValue) { dualPipe.boolValue = false; } if (dualInstance.boolValue) { dualInstance.boolValue = false; } } //draw settings toggle SerializedProperty loadSettingsAtRuntime = serializedObject.FindProperty(nameof(PhysicalDisplay.loadSettingsAtRuntime)); SerializedProperty serializedLocation = serializedObject.FindProperty(nameof(PhysicalDisplay.serializedLocation)); EditorGUILayout.PropertyField(loadSettingsAtRuntime); if (loadSettingsAtRuntime.boolValue) { EditorGUILayout.PropertyField(serializedLocation); } //done with serialized properties serializedObject.ApplyModifiedProperties(); //update manager if it changed PhysicalDisplay physicalDisplay = target as PhysicalDisplay; if (managerChanged) { PhysicalDisplayManager.SetManager(physicalDisplay, oldManager, newManager); } //JSON buttons if (GUILayout.Button("Export Display Settings to JSON")) { string path = EditorUtility.SaveFilePanel("Export Settings", "./", "settings.json", "json"); if (!string.IsNullOrEmpty(path)) { physicalDisplay.TryToSerialize(path); } } if (GUILayout.Button("Import Display Settings from JSON")) { string path = EditorUtility.SaveFilePanel("Import Settings", "./", "settings.json", "json"); if (!string.IsNullOrEmpty(path)) { physicalDisplay.TryToDeSerialize(path); } } }
/// <summary> /// Waits for all displays to be initialized, then repositions camera viewports and/or sets up post processing /// </summary> void Update() { if (!_initialized) { bool displaysInitialized = true; for (int i = 0; i < displays.Count; i++) { if (!displays[i].gameObject.activeSelf) { continue; } if (displays[i].enabled && !displays[i].Initialized()) { displaysInitialized = false; break; } PhysicalDisplayCalibration cali = displays[i].gameObject.GetComponent <PhysicalDisplayCalibration>(); if (cali != null && !cali.Initialized()) { displaysInitialized = false; break; } } //wait until every other display is initialized if (displaysInitialized) { for (int i = 0; i < displays.Count; i++) { PhysicalDisplay display = displays[i]; PhysicalDisplayCalibration cali = display.gameObject.GetComponent <PhysicalDisplayCalibration>(); if (cali == null) { if (!display.useRenderTextures) { if (display.dualPipe) { Vector2Int windowSpaceOffset = display.dualInstance ? new Vector2Int(0, 0) : new Vector2Int(display.windowBounds.x, display.windowBounds.y); display.leftCam.pixelRect = new Rect( windowSpaceOffset.x + display.leftViewport.x, windowSpaceOffset.y + display.leftViewport.y, display.leftViewport.width, display.leftViewport.height); display.rightCam.pixelRect = new Rect( windowSpaceOffset.x + display.rightViewport.x, windowSpaceOffset.y + display.rightViewport.y, display.rightViewport.width, display.rightViewport.height); } else { //if stereo blit is enabled, only update the viewport of the center cam (in the future perhaps consolidate this logic with useRenderTextures) if (display.centerCam != null && display.centerCam.GetComponent <StereoBlit>() != null) { display.centerCam.pixelRect = new Rect(display.windowBounds.x, display.windowBounds.y, display.windowBounds.width, display.windowBounds.height); } else { foreach (Camera cam in display.GetAllCameras()) { Debug.Log("Manager [" + name + "] set Camera [" + cam.name + "] viewport to <" + display.windowBounds.x + ", " + display.windowBounds.y + ", " + display.windowBounds.width + ", " + display.windowBounds.height + ">"); cam.pixelRect = new Rect(display.windowBounds.x, display.windowBounds.y, display.windowBounds.width, display.windowBounds.height); } } } } } else { //special case for PhysicalDisplayCalibration //Debug.Log("Display:"); foreach (Camera cam in cali.postCams) { Rect r = new Rect(display.windowBounds.x, display.windowBounds.y, display.windowBounds.width, display.windowBounds.height); //Debug.Log("Set cam " + cam.name + " to " + r); cam.pixelRect = r; } } } _initialized = true; } } }
public override void OnInspectorGUI() { serializedObject.Update(); //draw machine name SerializedProperty oldMachineName = serializedObject.FindProperty(nameof(PhysicalDisplayManager.oldMachineName)); SerializedProperty machineNameAsset = serializedObject.FindProperty(nameof(PhysicalDisplayManager.machineNameAsset)); MachineName.DrawDeprecatedMachineName(oldMachineName, machineNameAsset, "Machine Name"); //draw display settings SerializedProperty fullscreen = serializedObject.FindProperty(nameof(PhysicalDisplayManager.fullscreen)); EditorGUILayout.PropertyField(fullscreen); if (fullscreen.boolValue) { SerializedProperty displayNumber = serializedObject.FindProperty(nameof(PhysicalDisplayManager.displayNumber)); EditorGUILayout.PropertyField(displayNumber); } SerializedProperty displayResolution = serializedObject.FindProperty(nameof(PhysicalDisplayManager.displayResolution)); EditorGUILayout.PropertyField(displayResolution); serializedObject.ApplyModifiedProperties(); //draw buttons PhysicalDisplayManager physicalDisplayManager = target as PhysicalDisplayManager; if (GUILayout.Button("Assign Children To This Manager")) { foreach (Transform child in physicalDisplayManager.transform) { PhysicalDisplay childPD = child.GetComponent <PhysicalDisplay>(); if (childPD) { SetManager(childPD, childPD.manager, physicalDisplayManager, undoName: "Assign Children to Manager"); } } } //draw displays GUILayout.Label("Associated Displays:"); for (int i = 0; i < physicalDisplayManager.displays.Count; i++) { PhysicalDisplay pd = physicalDisplayManager.displays[i]; pd = EditorGUILayout.ObjectField(pd, typeof(PhysicalDisplay), true) as PhysicalDisplay; //remove any displays that are null if (!pd) { Undo.SetCurrentGroupName("Remove Display"); PhysicalDisplay physicalDisplay = physicalDisplayManager.displays[i]; Undo.RecordObject(physicalDisplay, string.Empty); if (physicalDisplay.manager == physicalDisplayManager) { physicalDisplay.manager = null; EditorUtility.SetDirty(physicalDisplay); } Undo.RecordObject(physicalDisplayManager, string.Empty); physicalDisplayManager.displays.RemoveAt(i); EditorUtility.SetDirty(physicalDisplayManager); Undo.CollapseUndoOperations(Undo.GetCurrentGroup()); i--; } } //draw field to add displays PhysicalDisplay addedPD = EditorGUILayout.ObjectField("Add Display", null, typeof(PhysicalDisplay), true) as PhysicalDisplay; if (addedPD) { SetManager(addedPD, addedPD.manager, physicalDisplayManager, undoName: "Add Display"); } }
public bool RemoveDisplay(PhysicalDisplay physicalDisplay) { return(displays.Remove(physicalDisplay)); }
void SetupPostProcessing() { PhysicalDisplay display = GetComponent <PhysicalDisplay>(); GameObject staticParent = new GameObject("Post Holder For: " + gameObject.name); // Apply multiplier factor on all vertices int numVertices = this.dewarpMeshPositions.verts.Length; Vector3[] verts = this.dewarpMeshPositions.verts; for (int i = 0; i < numVertices; i++) { verts[i] *= GetMultiplierFactor(); } bool stereo = true; if (this.GetDisplay().is3D) { if (this.GetDisplay().leftCam != null) { this.displayCalibrations.Add(HeadCamera.LEFT, new Dewarp(gameObject.name, this.postProcessMaterial, dewarpMeshPositions, this.GetDisplay().leftTex)); this.RemovePostProcessingFromHeadCamera(this.GetDisplay().leftCam); } else { stereo = false; } if (this.GetDisplay().rightCam != null) { this.displayCalibrations.Add(HeadCamera.RIGHT, new Dewarp(gameObject.name, this.postProcessMaterial, dewarpMeshPositions, this.GetDisplay().rightTex)); this.RemovePostProcessingFromHeadCamera(this.GetDisplay().rightCam); } else { stereo = false; } } else { stereo = false; this.displayCalibrations.Add(HeadCamera.CENTER, new Dewarp(gameObject.name, this.postProcessMaterial, dewarpMeshPositions, this.GetDisplay().centerTex)); this.RemovePostProcessingFromHeadCamera(this.GetDisplay().centerCam); } this.SetDewarpPositions(stereo); foreach (var displayCalibration in this.displayCalibrations) { GameObject obj = displayCalibration.Value.GetDewarpGameObject(); obj.layer = this.postProcessLayer; obj.transform.parent = staticParent.transform; } { camChild = new GameObject("Calibration Cam (Left)"); camChild.transform.parent = staticParent.transform; Camera postCam = camChild.AddComponent <Camera>(); postCam.transform.localPosition = globalPostOffset + new Vector3(stereo ? -displayRatio * 2.0f : 0.0f, 0.0f, -1.0f); postCam.stereoTargetEye = StereoTargetEyeMask.Left; this.SetPostCameraProperties(postCam); postCams.Add(postCam); } { GameObject calibrationCamera = new GameObject("Calibration Cam (Right)"); calibrationCamera.transform.parent = staticParent.transform; Camera postCam = calibrationCamera.AddComponent <Camera>(); postCam.transform.localPosition = globalPostOffset + new Vector3(stereo ? displayRatio * 2.0f : 0.0f, 0.0f, -1.0f); postCam.stereoTargetEye = StereoTargetEyeMask.Right; this.SetPostCameraProperties(postCam); postCams.Add(postCam); } globalPostOffset = globalPostOffset + new Vector3(10, 10, 10); }