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

192 lines
14 KiB
C#

namespace DrawXXL
{
using UnityEngine;
public class UtilitiesDXXL_FlatShapesNormaAndUpCalculation
{
static InternalDXXL_Plane s_planeInWhichTextUpShouldLie = new InternalDXXL_Plane(); //doesn't have to contain the text, but can be parallel shifted
public static void GetNormalAndUpInsidePlane(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 upInsideFlatPlane_normalized, Vector3 normal_fromCaller, Vector3 upInsideFlatPlane_fromCaller, Vector3 shapePos)
{
//most callers don't care whether the normal points towardsCam or awayFromIt.
//Exception: 'UtilitiesDXXL_DrawBasics.Icon()':
//The normal of an icon is actually pointing towards the observer
//Therefore the userDelivered normal gets flipped so it is a "forward (e.g.ofTheDefaulXYPlane)"
//And this is what 'UtilitiesDXXL_DrawBasics.Icon()' expects: a "forward (e.g.ofTheDefaulXYPlane)"
//This function here cares for this expectation and delivers this "forward (e.g.ofTheDefaulXYPlane)" (except for the "GetNormalAndUp_whileUserHas_notSpecifiedNormal_but_specifiedUp"-thread, where the flipInversion is undefined)
bool normal_isUnspecified = UtilitiesDXXL_Math.IsDefaultVector(normal_fromCaller);
bool upInsideFlatPlane_isUnspecified = UtilitiesDXXL_Math.IsDefaultVector(upInsideFlatPlane_fromCaller);
if (normal_isUnspecified && upInsideFlatPlane_isUnspecified)
{
//both "normal" and "up" are unspecified:
GetNormalAndUp_withoutAnyUserSpecification(out normal_final_notGuaranteedNormalized, out upInsideFlatPlane_normalized, shapePos);
}
else
{
if ((normal_isUnspecified == false) && (upInsideFlatPlane_isUnspecified == false))
{
//both "normal" and "up" are specified:
NormalizeAndForcePerp_userSpecifiedNonDefaultNormalAndUp(out normal_final_notGuaranteedNormalized, out upInsideFlatPlane_normalized, normal_fromCaller, upInsideFlatPlane_fromCaller);
}
else
{
if (upInsideFlatPlane_isUnspecified)
{
//"normal" is specified:
//"up" is unspecified:
GetNormalAndUp_whileUserHas_specifiedNormal_but_notSpecifiedUp(out normal_final_notGuaranteedNormalized, out upInsideFlatPlane_normalized, normal_fromCaller);
}
else
{
// "normal" is unspecified:
// "up" is specified:
GetNormalAndUp_whileUserHas_notSpecifiedNormal_but_specifiedUp(out normal_final_notGuaranteedNormalized, out upInsideFlatPlane_normalized, upInsideFlatPlane_fromCaller, shapePos);
}
}
}
}
static void GetNormalAndUp_withoutAnyUserSpecification(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 upInsideFlatPlane_normalized, Vector3 shapePos)
{
Vector3 observerCamForward_normalized;
Vector3 observerCamUp_normalized;
Vector3 observerCamRight_normalized;
Vector3 cam_to_lineCenter;
switch (DrawShapes.automaticOrientationOfFlatShapes)
{
case DrawShapes.AutomaticOrientationOfFlatShapes.screen:
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, shapePos, Vector3.zero, null);
normal_final_notGuaranteedNormalized = observerCamForward_normalized;
//normal_final_notGuaranteedNormalized = cam_to_lineCenter; //-> seems to make no difference
upInsideFlatPlane_normalized = observerCamUp_normalized;
return;
case DrawShapes.AutomaticOrientationOfFlatShapes.screen_butVerticalInWorldSpace:
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out observerCamForward_normalized, out observerCamUp_normalized, out observerCamRight_normalized, out cam_to_lineCenter, shapePos, Vector3.zero, null);
UtilitiesDXXL_LineAmplitudeAndTextDirCalculation.GetUpAndTextDir_withoutCallerSpecifiedPreference_independentFromTooShortLineDir_alignedVertical(out Vector3 textUp_normalized, out Vector3 textDir_normalized, observerCamForward_normalized, observerCamUp_normalized, observerCamRight_normalized, cam_to_lineCenter);
normal_final_notGuaranteedNormalized = Vector3.Cross(textDir_normalized, textUp_normalized);
upInsideFlatPlane_normalized = textUp_normalized;
return;
case DrawShapes.AutomaticOrientationOfFlatShapes.xyPlane:
normal_final_notGuaranteedNormalized = Vector3.forward;
upInsideFlatPlane_normalized = Vector3.up;
return;
case DrawShapes.AutomaticOrientationOfFlatShapes.xzPlane:
normal_final_notGuaranteedNormalized = Vector3.down;
upInsideFlatPlane_normalized = Vector3.forward;
return;
case DrawShapes.AutomaticOrientationOfFlatShapes.zyPlane:
normal_final_notGuaranteedNormalized = Vector3.right;
upInsideFlatPlane_normalized = Vector3.up;
return;
default:
Debug.LogError("DrawShapes.automaticOrientationOfFlatShapes of " + DrawShapes.automaticOrientationOfFlatShapes + " not implemented.");
normal_final_notGuaranteedNormalized = Vector3.forward;
upInsideFlatPlane_normalized = Vector3.up;
return;
}
}
static void GetNormalAndUp_whileUserHas_specifiedNormal_but_notSpecifiedUp(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 upInsideFlatPlane_normalized, Vector3 normal_fromCaller)
{
NormalizeAndForcePerp_userSpecifiedNonDefaultNormalAndUp(out normal_final_notGuaranteedNormalized, out upInsideFlatPlane_normalized, normal_fromCaller, Vector3.up);
}
static InternalDXXL_Plane s_planeInWhichNormalShouldLie = new InternalDXXL_Plane();
static void GetNormalAndUp_whileUserHas_notSpecifiedNormal_but_specifiedUp(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 upInsideFlatPlane_normalized, Vector3 upInsideFlatPlane_fromCaller, Vector3 shapePos)
{
upInsideFlatPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(upInsideFlatPlane_fromCaller);
s_planeInWhichNormalShouldLie.Recreate(Vector3.zero, upInsideFlatPlane_normalized);
UtilitiesDXXL_ObserverCamera.GetObserverCamSpecs(out Vector3 observerCamForward_normalized, out Vector3 observerCamUp_normalized, out Vector3 observerCamRight_normalized, out Vector3 cam_to_lineCenter, shapePos, Vector3.zero, null);
InternalDXXL_Plane flatPlane_theWouldContainTheShape_accordingTo_DrawShapesAutomaticOrientationOfFlatShapesSetting = GetFlatPlane_thatContainsTheShape_accordingTo_DrawShapesAutomaticOrientationOfFlatShapesSetting(observerCamForward_normalized, false);
Vector3 normalFromAutomaticOrientation_projectedOnto_planeInWhichNormalShouldLie = s_planeInWhichNormalShouldLie.Get_projectionOfVectorOntoPlane(flatPlane_theWouldContainTheShape_accordingTo_DrawShapesAutomaticOrientationOfFlatShapesSetting.normalDir);
normalFromAutomaticOrientation_projectedOnto_planeInWhichNormalShouldLie = UtilitiesDXXL_Math.ScaleNonZeroVectorIntoRegionOfFloatPrecision(normalFromAutomaticOrientation_projectedOnto_planeInWhichNormalShouldLie);
if (UtilitiesDXXL_Math.CheckIfScaleToFloatPrecisionRegionFailed_meaningLineStayedTooShort(normalFromAutomaticOrientation_projectedOnto_planeInWhichNormalShouldLie))
{
//-> "upInsideFlatPlane_fromCaller" is perp to the wanted planeNormal (e.g. alongCamViewDir):
normal_final_notGuaranteedNormalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(upInsideFlatPlane_normalized);
}
else
{
normal_final_notGuaranteedNormalized = normalFromAutomaticOrientation_projectedOnto_planeInWhichNormalShouldLie;
}
}
static InternalDXXL_Plane GetFlatPlane_thatContainsTheShape_accordingTo_DrawShapesAutomaticOrientationOfFlatShapesSetting(Vector3 observerCamForward_normalized, bool normalizePlaneNormal)
{
switch (DrawShapes.automaticOrientationOfFlatShapes)
{
case DrawShapes.AutomaticOrientationOfFlatShapes.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 DrawShapes.AutomaticOrientationOfFlatShapes.screen_butVerticalInWorldSpace:
return GetFlatPlane_ifAutomaticTextOrientationSettingIs_screen_butVerticalInWorldSpace(observerCamForward_normalized, normalizePlaneNormal);
case DrawShapes.AutomaticOrientationOfFlatShapes.xyPlane:
return InternalDXXL_Plane.xyPlane_throughZeroOrigin;
case DrawShapes.AutomaticOrientationOfFlatShapes.xzPlane:
return InternalDXXL_Plane.horizPlane_throughZeroOrigin;
case DrawShapes.AutomaticOrientationOfFlatShapes.zyPlane:
return InternalDXXL_Plane.zyPlane_throughZeroOrigin;
default:
Debug.LogError("DrawShapes.automaticOrientationOfFlatShapes of " + DrawShapes.automaticOrientationOfFlatShapes + " not implemented.");
return InternalDXXL_Plane.xyPlane_throughZeroOrigin;
}
}
static InternalDXXL_Plane GetFlatPlane_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
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 InternalDXXL_Plane aPlane_parallelToPolygonPlane = new InternalDXXL_Plane();
static void NormalizeAndForcePerp_userSpecifiedNonDefaultNormalAndUp(out Vector3 normal_final_notGuaranteedNormalized, out Vector3 upInsideFlatPlane_normalized, Vector3 normal_fromCaller, Vector3 upInsideFlatPlane_fromCaller)
{
aPlane_parallelToPolygonPlane.Recreate(Vector3.zero, normal_fromCaller);
normal_final_notGuaranteedNormalized = aPlane_parallelToPolygonPlane.normalDir; //-> is now treated with "ScaleNonZeroVectorIntoRegionOfFloatPrecision" (whhich happens inside the plane.Recreate())
upInsideFlatPlane_fromCaller = UtilitiesDXXL_Shapes.ForceVectorPerpToOtherVector(upInsideFlatPlane_fromCaller, aPlane_parallelToPolygonPlane);
if (UtilitiesDXXL_Math.Check_ifTwoVectorsAreApproxParallel_butCanHeadToDifferntDirs_DXXL(upInsideFlatPlane_fromCaller, normal_final_notGuaranteedNormalized))
{
upInsideFlatPlane_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(normal_final_notGuaranteedNormalized, aPlane_parallelToPolygonPlane);
}
else
{
upInsideFlatPlane_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(upInsideFlatPlane_fromCaller);
}
}
public static Quaternion GetQuaternion(Quaternion quaternion_fromCaller, Vector3 position_ofDrawnShape)
{
if (UtilitiesDXXL_Math.IsDefaultInvalidQuaternion(quaternion_fromCaller))
{
GetNormalAndUpInsidePlane(out Vector3 forward_final_notGuaranteedNormalized, out Vector3 upInsideIconPlane_normalized, default(Vector3), default(Vector3), position_ofDrawnShape);
return Quaternion.LookRotation(forward_final_notGuaranteedNormalized, upInsideIconPlane_normalized);
}
else
{
return quaternion_fromCaller;
}
}
}
}