444 lines
32 KiB
C#
444 lines
32 KiB
C#
namespace DrawXXL
|
|
{
|
|
using UnityEngine;
|
|
|
|
public class UtilitiesDXXL_TextDirAndUpCalculation
|
|
{
|
|
static InternalDXXL_Plane s_planeInWhichTextUpShouldLie = new InternalDXXL_Plane(); //doesn't have to contain the text, but can be parallel shifted
|
|
static InternalDXXL_Line intersectionLine_ofTwoPlanes = new InternalDXXL_Line();
|
|
static InternalDXXL_Plane aPlanePerpToTextDir = new InternalDXXL_Plane();
|
|
static InternalDXXL_Plane aPlanePerpToUpDir = new InternalDXXL_Plane();
|
|
|
|
public static void GetTextDirAndUpNormalized(out Vector3 textDir_normalized, out Vector3 textUp_normalized, Vector3 textDir_fromCaller, Vector3 textUp_fromCaller, Vector3 textPos, bool isFrom_Write2D, bool dirAndUp_areAlreadyGuaranteed_perpAndNormalized)
|
|
{
|
|
if (dirAndUp_areAlreadyGuaranteed_perpAndNormalized)
|
|
{
|
|
//-> calls from WriteScreenspace always arrive here
|
|
textDir_normalized = textDir_fromCaller;
|
|
textUp_normalized = textUp_fromCaller;
|
|
}
|
|
else
|
|
{
|
|
bool textDir_isUnspecified = UtilitiesDXXL_Math.IsDefaultVector(textDir_fromCaller);
|
|
bool textUp_isUnspecified = UtilitiesDXXL_Math.IsDefaultVector(textUp_fromCaller);
|
|
|
|
if (textDir_isUnspecified && textUp_isUnspecified)
|
|
{
|
|
//both "dir" and "up" are unspecified:
|
|
GetTextDirAndUpNormalized_withoutAnyUserSpecification(out textDir_normalized, out textUp_normalized, textPos, isFrom_Write2D);
|
|
}
|
|
else
|
|
{
|
|
if ((textDir_isUnspecified == false) && (textUp_isUnspecified == false))
|
|
{
|
|
//both "dir" and "up" are specified:
|
|
//-> "isFrom_Write2D" has no effect here, except for the fallback_caseTextAndUpAreParallel
|
|
//-> "textPos" has no effect here, except for the fallback_caseTextAndUpAreParallel
|
|
NormalizeAndForcePerp_userSpecifiedNonDefaultDirAndUp(out textDir_normalized, out textUp_normalized, textDir_fromCaller, textUp_fromCaller, textPos, isFrom_Write2D);
|
|
}
|
|
else
|
|
{
|
|
if (textUp_isUnspecified)
|
|
{
|
|
//"dir" is specified:
|
|
//"up" is unspecified:
|
|
GetTextDirAndUpNormalized_whileUserHas_specifiedDir_but_notSpecifiedUp(out textDir_normalized, out textUp_normalized, textDir_fromCaller, textPos, isFrom_Write2D);
|
|
}
|
|
else
|
|
{
|
|
// "dir" is unspecified:
|
|
// "up" is specified:
|
|
GetTextDirAndUpNormalized_whileUserHas_notSpecifiedDir_but_specifiedUp(out textDir_normalized, out textUp_normalized, textUp_fromCaller, textPos, isFrom_Write2D);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void GetTextDirAndUpNormalized_withoutAnyUserSpecification(out Vector3 textDir_normalized, out Vector3 textUp_normalized, Vector3 textPos, bool isFrom_Write2D)
|
|
{
|
|
if (isFrom_Write2D)
|
|
{
|
|
textDir_normalized = Vector3.right;
|
|
textUp_normalized = Vector3.up;
|
|
}
|
|
else
|
|
{
|
|
Vector3 observerCamForward_normalized;
|
|
Vector3 observerCamUp_normalized;
|
|
Vector3 observerCamRight_normalized;
|
|
Vector3 cam_to_lineCenter;
|
|
|
|
switch (DrawText.automaticTextOrientation)
|
|
{
|
|
case DrawText.AutomaticTextOrientation.screen:
|
|
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, textPos, Vector3.zero, null);
|
|
textDir_normalized = observerCamRight_normalized;
|
|
textUp_normalized = observerCamUp_normalized;
|
|
return;
|
|
case DrawText.AutomaticTextOrientation.screen_butVerticalInWorldSpace:
|
|
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, textPos, Vector3.zero, null);
|
|
UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetUpAndTextDir_withoutCallerSpecifiedPreference_independentFromTooShortLineDir_alignedVertical(out textUp_normalized, out textDir_normalized, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
|
|
return;
|
|
case DrawText.AutomaticTextOrientation.xyPlane:
|
|
textDir_normalized = Vector3.right;
|
|
textUp_normalized = Vector3.up;
|
|
return;
|
|
case DrawText.AutomaticTextOrientation.xzPlane:
|
|
textDir_normalized = Vector3.right;
|
|
textUp_normalized = Vector3.forward;
|
|
return;
|
|
case DrawText.AutomaticTextOrientation.zyPlane:
|
|
textDir_normalized = Vector3.forward;
|
|
textUp_normalized = Vector3.up;
|
|
return;
|
|
default:
|
|
Debug.LogError("DrawText.AutomaticTextOrientation of " + DrawText.automaticTextOrientation + " not implemented.");
|
|
textDir_normalized = Vector3.right;
|
|
textUp_normalized = Vector3.up;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void GetTextDirAndUpNormalized_whileUserHas_specifiedDir_but_notSpecifiedUp(out Vector3 textDir_normalized, out Vector3 textUp_normalized, Vector3 textDir_fromCaller, Vector3 textPos, bool isFrom_Write2D)
|
|
{
|
|
//-> may look unintuitive for perspective cameras
|
|
//-> the current implementation (explained with the example of "automaticTextOrientation==screen"):
|
|
//---> tries to put the upVector into the screenParallelPlane
|
|
//---> this is probably what the name "(automaticTextOrientation==)screen" implies: The dir cannot be forced into this plane, because it is user-specified, so let at least force everything else (=the upVector) into this plane, so that (since you cannot force EVERYTHING into this plane) at least as much as possible results inside this plane.
|
|
//---> But: this doesn't result in the maximum readabilty for the screen-viewpoint (and that may "actually" be the meaning of "(automaticTextOrientation==)screen": clearest, most-unwarped readabilty from screen-viewpoint)
|
|
//---> Because: The upVector_afterForcingIntoScreenPlane may come out es very parallel to the dirVector (when seen from the screen-viewpoint), so the text can be strongly sheared and therfore unreadable.
|
|
//-> A refactoring could try this:
|
|
//---> Use the upVector, that is not necessarily in the screenParallelPlane, but is perp_toDirVector "from the screen viewpoint perspective".
|
|
//---> The refactoring should keep in mind that for perspective cameras this "perp_toDirVector_fromScreenViewPoint"-direction is different depending wheather the textStartPosition or the textEndPosition is chosen as the point where the perpendicularity should be. (also: one pos could be in front of the camera, the other pos behind the camera)
|
|
|
|
textDir_fromCaller = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(textDir_fromCaller);
|
|
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, textPos, textDir_fromCaller, null);
|
|
InternalDXXL_Plane planeInWhichTextShouldLie_ifNoTextAndNoUpAreSpecified_normalIsNormalized = GetPlane_thatContainsTheText_accordingTo_DrawTextAutomaticTextOrientationSetting_ifNoTextAndNoUpAreSpecified(observerCamForward_normalized, false, isFrom_Write2D);
|
|
|
|
DrawBasics.AutomaticTextDirectionOfLines automaticTextDirectionOfLines_before = DrawBasics.automaticTextDirectionOfLines;
|
|
try
|
|
{
|
|
DrawBasics.automaticTextDirectionOfLines = DrawBasics.AutomaticTextDirectionOfLines.towardsLineEnd;
|
|
UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetUpAndTextDir_insideAmplitudePlane_forNonShortLine(out textUp_normalized, out textDir_normalized, out float lengthOfDrawnLine, out bool lengthOfDrawnLine_isFilled, textPos, textDir_fromCaller, planeInWhichTextShouldLie_ifNoTextAndNoUpAreSpecified_normalIsNormalized, true, false, null, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter, false);
|
|
}
|
|
catch
|
|
{
|
|
UtilitiesDXXL_Log.PrintErrorCode("23-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(textDir_fromCaller) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(textPos) + "-" + DrawText.automaticTextOrientation);
|
|
textDir_normalized = Vector3.right;
|
|
textUp_normalized = Vector3.up;
|
|
}
|
|
DrawBasics.automaticTextDirectionOfLines = automaticTextDirectionOfLines_before;
|
|
}
|
|
|
|
static void GetTextDirAndUpNormalized_whileUserHas_notSpecifiedDir_but_specifiedUp(out Vector3 textDir_normalized, out Vector3 textUp_normalized, Vector3 textUp_fromCaller, Vector3 textPos, bool isFrom_Write2D)
|
|
{
|
|
//-> amplitudeUpDir is specified
|
|
//-> AND
|
|
//-> amplitudePlane is specified
|
|
//This case is not yet implemented in "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetUpAndTextDir_accordingToSubCaseSpecification()":
|
|
//Note that amplitudeUpDir may or may not be inside the amplitudePlane
|
|
//The implementation here only cares for the case "textDir=undefinedShort"
|
|
|
|
//-> may look unintuitive for perspective cameras (see explanation in "GetTextDirAndUpNormalized_whileUserHas_specifiedDir_but_notSpecifiedUp")
|
|
|
|
textUp_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textUp_fromCaller);
|
|
aPlanePerpToUpDir.Recreate(Vector3.zero, textUp_normalized);
|
|
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, textPos, Vector3.zero, null);
|
|
InternalDXXL_Plane planeInWhichTextShouldLie_ifNoTextAndNoUpAreSpecified_normalIsNormalized = GetPlane_thatContainsTheText_accordingTo_DrawTextAutomaticTextOrientationSetting_ifNoTextAndNoUpAreSpecified(observerCamForward_normalized, true, isFrom_Write2D); //-> parameter forces normalizing: it's a seldom case, so no further optimizing, though also approxNormalized would be sufficient for the following parallelCheck
|
|
|
|
if (UtilitiesDXXL_Math.Check_ifTwoNormalizedVectorsAreApproxParallel_butCanHeadToDifferntDirs_padding(planeInWhichTextShouldLie_ifNoTextAndNoUpAreSpecified_normalIsNormalized.normalDir, aPlanePerpToUpDir.normalDir))
|
|
{
|
|
//user-specified upDir is perp to plane that "DrawText.automaticTextOrientation" specifies
|
|
//-> textDir cannot be obtained via intersection of the two planes
|
|
//-> EVERY textDir is valid, as long as it lies inside the (parallel)plane(s)
|
|
//-> EVERY dir inside the (parallel)plane(s) fulfils both criteria:
|
|
//---> is perp to upDir
|
|
//---> is inside the plane that is wanted by "DrawText.automaticTextOrientation"
|
|
//-> so, perpToUpPlane can be ignored, and the dirVector can be restricted by only the "DrawText.automaticTextOrientation"-wanted plane (the planes are parallel, meaning exchangable)
|
|
//-> fallback to "GetTextDirAndUpNormalized_withoutAnyUserSpecification()", but only for textDir. UpDir stays as user-specified
|
|
GetTextDirAndUpNormalized_withoutAnyUserSpecification(out textDir_normalized, out Vector3 unused_textUp_normalized, textPos, isFrom_Write2D);
|
|
}
|
|
else
|
|
{
|
|
InternalDXXL_Plane.Calc_intersectionLine_ofTwoPlanes(ref intersectionLine_ofTwoPlanes, planeInWhichTextShouldLie_ifNoTextAndNoUpAreSpecified_normalIsNormalized, aPlanePerpToUpDir);
|
|
|
|
DrawBasics.AutomaticTextDirectionOfLines automaticTextDirectionOfLines_before = DrawBasics.automaticTextDirectionOfLines;
|
|
try
|
|
{
|
|
DrawBasics.automaticTextDirectionOfLines = DrawBasics.AutomaticTextDirectionOfLines.leftToRightInScreen;
|
|
UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.FlipNormalizedTextDir_toBeNonMirroredReadable_forFixedAmplitudeUpDir(out textDir_normalized, intersectionLine_ofTwoPlanes.direction_normalized, textUp_normalized, cam_to_lineCenter);
|
|
}
|
|
catch
|
|
{
|
|
UtilitiesDXXL_Log.PrintErrorCode("24-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(intersectionLine_ofTwoPlanes.direction_normalized) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(textUp_normalized) + "-" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(cam_to_lineCenter) + DrawText.automaticTextOrientation);
|
|
textDir_normalized = Vector3.right; //may be parallel to 'textUp'
|
|
}
|
|
DrawBasics.automaticTextDirectionOfLines = automaticTextDirectionOfLines_before;
|
|
}
|
|
}
|
|
|
|
static InternalDXXL_Plane GetPlane_thatContainsTheText_accordingTo_DrawTextAutomaticTextOrientationSetting_ifNoTextAndNoUpAreSpecified(Vector3 observerCamForward_normalized, bool normalizePlaneNormal, bool isFrom_Write2D)
|
|
{
|
|
if (isFrom_Write2D)
|
|
{
|
|
return InternalDXXL_Plane.xyPlane_throughZeroOrigin;
|
|
}
|
|
else
|
|
{
|
|
switch (DrawText.automaticTextOrientation)
|
|
{
|
|
case DrawText.AutomaticTextOrientation.screen:
|
|
s_planeInWhichTextUpShouldLie.Recreate(Vector3.zero, observerCamForward_normalized); //the plane could also be perp to "cam_to_lineCenter", but some of the already unintuitive cases get worse then
|
|
return s_planeInWhichTextUpShouldLie;
|
|
case DrawText.AutomaticTextOrientation.screen_butVerticalInWorldSpace:
|
|
return GetPlane_thatContainsTheText_ifAutomaticTextOrientationSettingIs_screen_butVerticalInWorldSpace(observerCamForward_normalized, normalizePlaneNormal);
|
|
case DrawText.AutomaticTextOrientation.xyPlane:
|
|
return InternalDXXL_Plane.xyPlane_throughZeroOrigin;
|
|
case DrawText.AutomaticTextOrientation.xzPlane:
|
|
return InternalDXXL_Plane.horizPlane_throughZeroOrigin;
|
|
case DrawText.AutomaticTextOrientation.zyPlane:
|
|
return InternalDXXL_Plane.zyPlane_throughZeroOrigin;
|
|
default:
|
|
Debug.LogError("DrawText.AutomaticTextOrientation of " + DrawText.automaticTextOrientation + " not implemented.");
|
|
return InternalDXXL_Plane.xyPlane_throughZeroOrigin;
|
|
}
|
|
}
|
|
}
|
|
|
|
static InternalDXXL_Plane GetPlane_thatContainsTheText_ifAutomaticTextOrientationSettingIs_screen_butVerticalInWorldSpace(Vector3 observerCamForward_normalized, bool normalizePlaneNormal)
|
|
{
|
|
Vector3 normal_ofVertPlane_thatIsAlignedToObserverCam_potentiallyZero = InternalDXXL_Plane.horizPlane_throughZeroOrigin.Get_projectionOfVectorOntoPlane(observerCamForward_normalized); //the projection could also be made from "cam_to_lineCenter", but some of the already unintuitive cases get worse then
|
|
Vector3 normal_ofVertPlane_thatIsAlignedToObserverCam_lengthIsMinApprox1_butCanBeVeryLong = UtilitiesDXXL_Math.ScaleNonZeroVectorToApproxBiggerThanMinLength(normal_ofVertPlane_thatIsAlignedToObserverCam_potentiallyZero, 1.0f);
|
|
if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(normal_ofVertPlane_thatIsAlignedToObserverCam_lengthIsMinApprox1_butCanBeVeryLong))
|
|
{
|
|
//camera is looking along vertical y-axis
|
|
//-> fallback to draw inside horizPlane
|
|
return InternalDXXL_Plane.horizPlane_throughZeroOrigin;
|
|
}
|
|
else
|
|
{
|
|
if (normalizePlaneNormal)
|
|
{
|
|
normal_ofVertPlane_thatIsAlignedToObserverCam_lengthIsMinApprox1_butCanBeVeryLong = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(normal_ofVertPlane_thatIsAlignedToObserverCam_lengthIsMinApprox1_butCanBeVeryLong);
|
|
}
|
|
s_planeInWhichTextUpShouldLie.Recreate(Vector3.zero, normal_ofVertPlane_thatIsAlignedToObserverCam_lengthIsMinApprox1_butCanBeVeryLong);
|
|
return s_planeInWhichTextUpShouldLie;
|
|
}
|
|
}
|
|
|
|
static void NormalizeAndForcePerp_userSpecifiedNonDefaultDirAndUp(out Vector3 textDir_normalized, out Vector3 textUp_normalized, Vector3 textDir_fromCaller, Vector3 textUp_fromCaller, Vector3 textPos, bool isFrom_Write2D)
|
|
{
|
|
textDir_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textDir_fromCaller);
|
|
Vector3 textUp_fromCaller_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(textUp_fromCaller);
|
|
float absDotProduct_ofDirNormalized_andUpFromCallerNormalized = Mathf.Abs(Vector3.Dot(textDir_normalized, textUp_fromCaller_normalized));
|
|
if (absDotProduct_ofDirNormalized_andUpFromCallerNormalized < UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp)
|
|
{
|
|
//user-specified dir and up have already been perp:
|
|
textUp_normalized = textUp_fromCaller_normalized;
|
|
}
|
|
else
|
|
{
|
|
aPlanePerpToTextDir.Recreate(Vector3.zero, textDir_normalized);
|
|
Vector3 up_norNormalized = aPlanePerpToTextDir.Get_projectionOfVectorOntoPlane(textUp_fromCaller_normalized);
|
|
Vector3 up_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(up_norNormalized);
|
|
if (UtilitiesDXXL_Math.CheckIfNormalizationFailed_meaningLineStayedTooShort(up_normalized))
|
|
{
|
|
//Debug.Log("Ambiguous: 'textDir' (" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(textDir_fromCaller) + ") and 'textUp' (" + UtilitiesDXXL_Log.Get_vectorComponentsAsString(textUp_fromCaller) + ") are approximately parallel -> now using auto-obtained 'textUp' as fallback.");
|
|
GetTextDirAndUpNormalized_whileUserHas_specifiedDir_but_notSpecifiedUp(out textDir_normalized, out textUp_normalized, textDir_normalized, textPos, isFrom_Write2D);
|
|
}
|
|
else
|
|
{
|
|
textUp_normalized = up_normalized;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void TryAutoFlipScreenspaceTextToPreventUpsideDown(out DrawText.TextAnchorDXXL textAnchor_postFlip, out Vector3 textDir_worldSpace_normalized_postFlip, out Vector3 textUp_worldSpace_normalized_postFlip, DrawText.TextAnchorDXXL textAnchor_preFlip, Vector3 textDir_worldSpace_normalized_preFlip, Vector3 textUp_worldSpace_normalized_preFlip, bool autoFlipTextToPreventUpsideDown, Camera screenspaceCamera)
|
|
{
|
|
//"autoFlipTextToPreventUpsideDown" has a separate implementation here (compared to "UtilitiesDXXL_LineAmplitudeAndTextDirCalculation"), because it seems easier for the user to learn only the one bool instead of the whole "DrawBasics.automaticAlignmentEnums"
|
|
//Moreover: this does not flip "mirrorInversion" but "upsideDown"
|
|
|
|
if (autoFlipTextToPreventUpsideDown)
|
|
{
|
|
float dotProduct_ofTextUp_and_camUp = Vector3.Dot(textUp_worldSpace_normalized_preFlip, screenspaceCamera.transform.up);
|
|
float absDotProduct_ofTextUp_and_camUp = Mathf.Abs(dotProduct_ofTextUp_and_camUp);
|
|
bool textIsApproxVertInsideScreen = (absDotProduct_ofTextUp_and_camUp < UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.absDotProductResult_ofTwoApproxNormalizedVectors_belowWhichVectorsAreConsideredPerp);
|
|
if (textIsApproxVertInsideScreen)
|
|
{
|
|
textAnchor_postFlip = textAnchor_preFlip;
|
|
float dotProduct_ofTextDir_and_camUp = Vector3.Dot(textDir_worldSpace_normalized_preFlip, screenspaceCamera.transform.up);
|
|
if (dotProduct_ofTextDir_and_camUp > 0.0f)
|
|
{
|
|
textDir_worldSpace_normalized_postFlip = screenspaceCamera.transform.up;
|
|
textUp_worldSpace_normalized_postFlip = (-screenspaceCamera.transform.right);
|
|
}
|
|
else
|
|
{
|
|
textDir_worldSpace_normalized_postFlip = (-screenspaceCamera.transform.up);
|
|
textUp_worldSpace_normalized_postFlip = screenspaceCamera.transform.right;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dotProduct_ofTextUp_and_camUp < 0.0f)
|
|
{
|
|
textAnchor_postFlip = GetHorizMirroredTextAnchor(textAnchor_preFlip);
|
|
textDir_worldSpace_normalized_postFlip = (-textDir_worldSpace_normalized_preFlip);
|
|
textUp_worldSpace_normalized_postFlip = (-textUp_worldSpace_normalized_preFlip);
|
|
}
|
|
else
|
|
{
|
|
ReturnUnchangedScreenspaceTextSpecs(out textAnchor_postFlip, out textDir_worldSpace_normalized_postFlip, out textUp_worldSpace_normalized_postFlip, textAnchor_preFlip, textDir_worldSpace_normalized_preFlip, textUp_worldSpace_normalized_preFlip);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ReturnUnchangedScreenspaceTextSpecs(out textAnchor_postFlip, out textDir_worldSpace_normalized_postFlip, out textUp_worldSpace_normalized_postFlip, textAnchor_preFlip, textDir_worldSpace_normalized_preFlip, textUp_worldSpace_normalized_preFlip);
|
|
}
|
|
}
|
|
|
|
static void ReturnUnchangedScreenspaceTextSpecs(out DrawText.TextAnchorDXXL textAnchor_postFlip, out Vector3 textDir_worldSpace_normalized_postFlip, out Vector3 textUp_worldSpace_normalized_postFlip, DrawText.TextAnchorDXXL textAnchor_preFlip, Vector3 textDir_worldSpace_normalized_preFlip, Vector3 textUp_worldSpace_normalized_preFlip)
|
|
{
|
|
textAnchor_postFlip = textAnchor_preFlip;
|
|
textDir_worldSpace_normalized_postFlip = textDir_worldSpace_normalized_preFlip;
|
|
textUp_worldSpace_normalized_postFlip = textUp_worldSpace_normalized_preFlip;
|
|
}
|
|
|
|
public static void TryAutoFlipStraightTextToPreventMirrorInverted(out DrawText.TextAnchorDXXL textAnchor_postFlip, out Vector3 textDir_normalized_postFlip, out Vector3 textUp_normalized_postFlip, out Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, DrawText.TextAnchorDXXL textAnchor_preFlip, Vector3 textDir_normalized_preFlip, Vector3 textUp_normalized_preFlip, Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip, Vector3 textPos, bool autoFlipToPreventMirrorInverted)
|
|
{
|
|
if (autoFlipToPreventMirrorInverted)
|
|
{
|
|
bool textAppearsMirrorInvertedToObserverCam = CheckIf_textAppearsMirrorInvertedToObserverCam(textPos, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
if (textAppearsMirrorInvertedToObserverCam)
|
|
{
|
|
textAnchor_postFlip = GetHorizMirroredTextAnchor(textAnchor_preFlip);
|
|
textDir_normalized_postFlip = (-textDir_normalized_preFlip);
|
|
textUp_normalized_postFlip = textUp_normalized_preFlip;
|
|
forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip = (-forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
}
|
|
else
|
|
{
|
|
ReturnUnchangedTextSpecs_forStraightText(out textAnchor_postFlip, out textDir_normalized_postFlip, out textUp_normalized_postFlip, out forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, textAnchor_preFlip, textDir_normalized_preFlip, textUp_normalized_preFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ReturnUnchangedTextSpecs_forStraightText(out textAnchor_postFlip, out textDir_normalized_postFlip, out textUp_normalized_postFlip, out forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, textAnchor_preFlip, textDir_normalized_preFlip, textUp_normalized_preFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
}
|
|
}
|
|
|
|
static void ReturnUnchangedTextSpecs_forStraightText(out DrawText.TextAnchorDXXL textAnchor_postFlip, out Vector3 textDir_normalized_postFlip, out Vector3 textUp_normalized_postFlip, out Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, DrawText.TextAnchorDXXL textAnchor_preFlip, Vector3 textDir_normalized_preFlip, Vector3 textUp_normalized_preFlip, Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip)
|
|
{
|
|
textAnchor_postFlip = textAnchor_preFlip;
|
|
textDir_normalized_postFlip = textDir_normalized_preFlip;
|
|
textUp_normalized_postFlip = textUp_normalized_preFlip;
|
|
forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip = forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip;
|
|
}
|
|
|
|
public static void TryAutoFlipCircledTextToPreventMirrorInverted(out Vector3 initialTextDirNormalized_postFlip, out Vector3 initialTextUpNormalized_postFlip, out Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, Vector3 initialTextDirNormalized_preFlip, Vector3 initialTextUpNormalized_preFlip, Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip, Vector3 textPos, bool autoFlipToPreventMirrorInverted, float angleDegOfLongestLine)
|
|
{
|
|
if (autoFlipToPreventMirrorInverted)
|
|
{
|
|
bool textAppearsMirrorInvertedToObserverCam = CheckIf_textAppearsMirrorInvertedToObserverCam(textPos, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
if (textAppearsMirrorInvertedToObserverCam)
|
|
{
|
|
Quaternion rotation_fromInitialUp_aroundForwardPreFlip_toEndOfTextSegment = Quaternion.AngleAxis(-angleDegOfLongestLine, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
initialTextUpNormalized_postFlip = rotation_fromInitialUp_aroundForwardPreFlip_toEndOfTextSegment * initialTextUpNormalized_preFlip;
|
|
forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip = (-forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
initialTextDirNormalized_postFlip = Vector3.Cross(initialTextUpNormalized_postFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip);
|
|
}
|
|
else
|
|
{
|
|
ReturnUnchangedTextSpecs_forCircledText(out initialTextDirNormalized_postFlip, out initialTextUpNormalized_postFlip, out forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, initialTextDirNormalized_preFlip, initialTextUpNormalized_preFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ReturnUnchangedTextSpecs_forCircledText(out initialTextDirNormalized_postFlip, out initialTextUpNormalized_postFlip, out forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, initialTextDirNormalized_preFlip, initialTextUpNormalized_preFlip, forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip);
|
|
}
|
|
}
|
|
|
|
static void ReturnUnchangedTextSpecs_forCircledText(out Vector3 initialTextDirNormalized_postFlip, out Vector3 initialTextUpNormalized_postFlip, out Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip, Vector3 initialTextDirNormalized_preFlip, Vector3 initialTextUpNormalized_preFlip, Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip)
|
|
{
|
|
initialTextDirNormalized_postFlip = initialTextDirNormalized_preFlip;
|
|
initialTextUpNormalized_postFlip = initialTextUpNormalized_preFlip;
|
|
forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_postFlip = forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip;
|
|
}
|
|
|
|
static bool CheckIf_textAppearsMirrorInvertedToObserverCam(Vector3 textPos, Vector3 forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip)
|
|
{
|
|
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, textPos, Vector3.zero, null);
|
|
return UtilitiesDXXL_Math.Check_ifVectorsPointAwayFromEachOther_perpCountsAsPointingAwayFromEachOther(forward_isPerpReaderViewDirThatSeesTextUnmirrored_normalized_preFlip, cam_to_lineCenter);
|
|
}
|
|
|
|
public static bool ConvertQuaternionToTextDirAndUpVectors(out Vector3 textDir, out Vector3 textUp, Quaternion quaternion)
|
|
{
|
|
//returns "rotationIsValid"
|
|
if (UtilitiesDXXL_Math.IsDefaultInvalidQuaternion(quaternion))
|
|
{
|
|
//-> will use "automaticTextOrientation"
|
|
textDir = default(Vector3);
|
|
textUp = default(Vector3);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
textDir = quaternion * Vector3.right;
|
|
textUp = quaternion * Vector3.up;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static DrawText.TextAnchorDXXL GetHorizMirroredTextAnchor(DrawText.TextAnchorDXXL anchorToMirror)
|
|
{
|
|
switch (anchorToMirror)
|
|
{
|
|
case DrawText.TextAnchorDXXL.UpperLeft:
|
|
return DrawText.TextAnchorDXXL.UpperRight;
|
|
|
|
case DrawText.TextAnchorDXXL.UpperCenter:
|
|
return anchorToMirror;
|
|
|
|
case DrawText.TextAnchorDXXL.UpperRight:
|
|
return DrawText.TextAnchorDXXL.UpperLeft;
|
|
|
|
case DrawText.TextAnchorDXXL.MiddleLeft:
|
|
return DrawText.TextAnchorDXXL.MiddleRight;
|
|
|
|
case DrawText.TextAnchorDXXL.MiddleCenter:
|
|
return anchorToMirror;
|
|
|
|
case DrawText.TextAnchorDXXL.MiddleRight:
|
|
return DrawText.TextAnchorDXXL.MiddleLeft;
|
|
|
|
case DrawText.TextAnchorDXXL.LowerLeft:
|
|
return DrawText.TextAnchorDXXL.LowerRight;
|
|
|
|
case DrawText.TextAnchorDXXL.LowerCenter:
|
|
return anchorToMirror;
|
|
|
|
case DrawText.TextAnchorDXXL.LowerRight:
|
|
return DrawText.TextAnchorDXXL.LowerLeft;
|
|
|
|
case DrawText.TextAnchorDXXL.LowerLeftOfFirstLine:
|
|
return DrawText.TextAnchorDXXL.LowerRightOfFirstLine;
|
|
|
|
case DrawText.TextAnchorDXXL.LowerCenterOfFirstLine:
|
|
return anchorToMirror;
|
|
|
|
case DrawText.TextAnchorDXXL.LowerRightOfFirstLine:
|
|
return DrawText.TextAnchorDXXL.LowerLeftOfFirstLine;
|
|
|
|
default:
|
|
Debug.LogError("TextAnchorExt of '" + anchorToMirror + "' not found. TextAnchorHorizMirroring not supported.");
|
|
return anchorToMirror;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|