Net.Like.Xue.Tokyo/Assets/Plugins/Draw XXL/scripts/internal utilities/UtilitiesDXXL_ObserverCamer...

220 lines
15 KiB
C#

namespace DrawXXL
{
using UnityEngine;
public class UtilitiesDXXL_ObserverCamera
{
#if UNITY_EDITOR
static bool obtainmentOf_sceneViewCam_hasFailed;
#endif
static bool obtainmentOf_gameViewCam_hasFailed;
public static void GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, Vector3 lineStartPos, Vector3 line_startToEnd, Camera cameraFrom_DrawScreenspaceCall)
{
#if UNITY_EDITOR
obtainmentOf_sceneViewCam_hasFailed = false;
#endif
obtainmentOf_gameViewCam_hasFailed = false;
if (cameraFrom_DrawScreenspaceCall != null)
{
observerCamForward_normalized = cameraFrom_DrawScreenspaceCall.transform.forward;
observerCamUp_normalized = cameraFrom_DrawScreenspaceCall.transform.up;
observerCamRight_normalized = cameraFrom_DrawScreenspaceCall.transform.right;
cam_to_lineCenter = cameraFrom_DrawScreenspaceCall.transform.forward;
}
else
{
if (DrawBasics.cameraForAutomaticOrientation == DrawBasics.CameraForAutomaticOrientation.sceneViewCamera)
{
GetObserverCamSpecs_fromSceneViewCam(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
}
else
{
GetObserverCamSpecs_fromGameViewCam(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
}
}
}
public static void GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_observedPosition, Vector3 observedPosition, DrawBasics.CameraForAutomaticOrientation observerCamera)
{
//-> This overload doesn't use the global setting of "DrawBasics.cameraForAutomaticOrientation" but the wanted observer camera can be explicitly defined
#if UNITY_EDITOR
obtainmentOf_sceneViewCam_hasFailed = false;
#endif
obtainmentOf_gameViewCam_hasFailed = false;
if (observerCamera == DrawBasics.CameraForAutomaticOrientation.sceneViewCamera)
{
GetObserverCamSpecs_fromSceneViewCam(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, observedPosition, Vector3.zero);
}
else
{
GetObserverCamSpecs_fromGameViewCam(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_observedPosition, observedPosition, Vector3.zero);
}
}
static void GetObserverCamSpecs_fromSceneViewCam(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, Vector3 lineStartPos, Vector3 line_startToEnd)
{
#if UNITY_EDITOR
if (obtainmentOf_sceneViewCam_hasFailed == false)
{
//known issue: In some cases after startPlayMode the "lastActiveSceneView" is not null, but delivers default values that don't represent it's actual position/rotation
//-> It seems to occur, when the sceneView-tab is not part of the main Unity Window but is in a separate window e.g. on a separate screen
//-> It is fixed as soon as the scene view gets selected
if (UnityEditor.SceneView.lastActiveSceneView != null)
{
GetObserverCamSpecs_fromNonNullLastActiveSceneViewCam(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
}
else
{
if (UnityEditor.SceneView.currentDrawingSceneView != null)
{
GetObserverCamSpecs_fromNonNullCam(UnityEditor.SceneView.currentDrawingSceneView.camera, out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
//LogCamSpecsToConsole("sceneView-currentDrawing", observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
}
else
{
obtainmentOf_sceneViewCam_hasFailed = true;
//string textSuffix_thatCommunicatesTheFallbackToGameViewCameras = null;
//if (obtainmentOf_gameViewCam_hasFailed == false) { textSuffix_thatCommunicatesTheFallbackToGameViewCameras = " -> Now trying fallback to Game view camera."; }
//Debug.Log("Draw XXL: automaticTextDirectionOfLines: No Scene view camera was found" + textSuffix_thatCommunicatesTheFallbackToGameViewCameras);
GetObserverCamSpecs_fromGameViewCam(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
}
}
}
else
{
ErrorLog_forNoSceneViewAndNoGameViewCameraFound();
GetFallbackObserverCamSpecs_forNoCamFound(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter);
}
#else
GetFallbackObserverCamSpecs_forNoCamFound(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter);
#endif
}
static void GetObserverCamSpecs_fromNonNullLastActiveSceneViewCam(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, Vector3 lineStartPos, Vector3 line_startToEnd)
{
#if UNITY_EDITOR
if (SceneViewCamHasUninitializedPosAndRotAfterStartingPlayMode(UnityEditor.SceneView.lastActiveSceneView.camera))
{
//(the described problem is not always reproducible, sometimes it works correctly also without this workaround)
///Problem, if
//-> the opened Unity editor has more than one scene view tabs
//-> one of the tabs is docked somewhere in the main window, but hidden, because an other tab of the dock is selected
//-> the other scene view tab is not in the main window but e.g. on a separate screen
//-> then OnStartPlaymode the hidden scene view of the main window gets selected as "lastActiveSceneView"
//-> this now selected scene view tab doesn't deliver the correct values of his camera transform, but unitialized default values (probably because it is hidden/not seen)
//-> the other scene view tab on the other monitor is prominently seen by the user, but the automatic text alignment appears wrong there, because the default pos/rot of hidden scene view's camera is used.
//-> the problem is fixed as soon as the user selects the prominent scene view on the other monitor.
//-> this block tries to avoid the necessity for the user to select to prominent scene view by automatically falling back to it's values
//-> this workaround may get confused if more than two scene view tabs are present
//-> this workaround has the problem, that if a scene view camera is "intentionally" placed at the default pos/rot, then it will forceSelect the other scene view. This is probalby a negligibly seldom case.
for (int i = 0; i < UnityEditor.SceneView.sceneViews.Count; i++)
{
UnityEditor.SceneView currentlyChecked_sceneView = (UnityEditor.SceneView)UnityEditor.SceneView.sceneViews[i];
if (currentlyChecked_sceneView != null)
{
if (currentlyChecked_sceneView.camera != null)
{
if (SceneViewCamHasUninitializedPosAndRotAfterStartingPlayMode(currentlyChecked_sceneView.camera) == false)
{
GetObserverCamSpecs_fromNonNullCam(currentlyChecked_sceneView.camera, out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
//LogCamSpecsToConsole("sceneView-nonDefaultFromList i_" + i + " / " + UnityEditor.SceneView.sceneViews.Count, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
return;
}
}
}
}
}
GetObserverCamSpecs_fromNonNullCam(UnityEditor.SceneView.lastActiveSceneView.camera, out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
//LogCamSpecsToConsole("sceneView-lastActive", observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
#else
GetFallbackObserverCamSpecs_forNoCamFound(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter);
#endif
}
static bool SceneViewCamHasUninitializedPosAndRotAfterStartingPlayMode(Camera nonNullCamera_toCheck)
{
return (UtilitiesDXXL_Math.IsDefaultVector(nonNullCamera_toCheck.transform.position) && UtilitiesDXXL_Math.IsQuaternionIdentity(nonNullCamera_toCheck.transform.rotation));
}
static void GetObserverCamSpecs_fromGameViewCam(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, Vector3 lineStartPos, Vector3 line_startToEnd)
{
if (obtainmentOf_gameViewCam_hasFailed == false)
{
UtilitiesDXXL_Screenspace.GetAutomaticCameraForDrawing(out Camera automaticallyFoundCamera, "DrawALine", true);
if (automaticallyFoundCamera != null)
{
GetObserverCamSpecs_fromNonNullCam(automaticallyFoundCamera, out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
//LogCamSpecsToConsole("gameView", observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
}
else
{
obtainmentOf_gameViewCam_hasFailed = true;
//string textSuffix_thatCommunicatesTheFallbackToSceneViewCameras = null;
//if (obtainmentOf_sceneViewCam_hasFailed == false) { textSuffix_thatCommunicatesTheFallbackToSceneViewCameras = " -> Now trying fallback to Scene view camera."; }
//Debug.Log("Draw XXL: automaticTextDirectionOfLines: The Game view camera could not be found." + textSuffix_thatCommunicatesTheFallbackToSceneViewCameras);
GetObserverCamSpecs_fromSceneViewCam(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, lineStartPos, line_startToEnd);
}
}
else
{
ErrorLog_forNoSceneViewAndNoGameViewCameraFound();
GetFallbackObserverCamSpecs_forNoCamFound(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter);
}
}
static void GetObserverCamSpecs_fromNonNullCam(Camera nonNullCamera_fromWhichToGetTheSpecs, out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, Vector3 lineStartPos, Vector3 line_startToEnd)
{
observerCamForward_normalized = nonNullCamera_fromWhichToGetTheSpecs.transform.forward;
observerCamUp_normalized = nonNullCamera_fromWhichToGetTheSpecs.transform.up;
observerCamRight_normalized = nonNullCamera_fromWhichToGetTheSpecs.transform.right;
//Note: "cam_to_lineCenter" might be 0 in seldom cases. The using code handles this already.
if (nonNullCamera_fromWhichToGetTheSpecs.orthographic)
{
//"cam_to_lineCenter" is strictly speaking a misnomer in orthographic mode. "camPlane_to_lineCenter" would be more fitting. Anyway: The rest of the class expects "cam.tranform.forward" in this orthographic case.
cam_to_lineCenter = nonNullCamera_fromWhichToGetTheSpecs.transform.forward;
}
else
{
Vector3 lineCenter = GetLineCenter(lineStartPos, line_startToEnd);
cam_to_lineCenter = lineCenter - nonNullCamera_fromWhichToGetTheSpecs.transform.position;
}
}
static Vector3 GetLineCenter(Vector3 lineStartPos, Vector3 line_startToEnd)
{
return (lineStartPos + 0.5f * line_startToEnd);
}
static void ErrorLog_forNoSceneViewAndNoGameViewCameraFound()
{
Debug.LogError("Draw XXL: Neither a Scene view camera nor a Game view camera was found -> automaticTextDirectionOfLines is not possible.");
}
static void GetFallbackObserverCamSpecs_forNoCamFound(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter)
{
observerCamForward_normalized = Vector3.forward;
observerCamUp_normalized = Vector3.up;
observerCamRight_normalized = Vector3.right;
cam_to_lineCenter = Vector3.forward;
//LogCamSpecsToConsole("noCamFound", observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
}
static void LogCamSpecsToConsole(string source, Vector3 observerCamForward_normalized, Vector3 observerCamUp_normalized, Vector3 observerCamRight_normalized, Vector3 cam_to_lineCenter)
{
Debug.Log("Observer camera specs: source: " + source + " observerCamForward_normalized: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(observerCamForward_normalized) + " observerCamUp_normalized: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(observerCamUp_normalized) + " observerCamRight_normalized: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(observerCamRight_normalized) + " cam_to_lineCenter: " + UtilitiesDXXL_Log.Get_vectorComponentsAsString(cam_to_lineCenter));
}
}
}