namespace DrawXXL { using System; using UnityEngine; public class UtilitiesDXXL_Quaternion { static InternalDXXL_Line localTurnAxisLine_inGlobalSpaceUnits = new InternalDXXL_Line(); public static void QuaternionRotation_local(Quaternion quaternionToDraw, Vector3 posWhereToDraw, Color color_ofTurnAxis, float lineWidth, string text, float length_ofUpAndForwardVectors_local, Vector3 customVectorToRotate_local, float durationInSec, bool hiddenByNearerObjects, bool isLocal, Transform parentTransform) { if (DXXLWrapperForUntiysBuildInDrawLines.CheckIfDrawingIsCurrentlySkipped()) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(lineWidth, "lineWidth")) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(length_ofUpAndForwardVectors_local, "length_ofUpAndForwardVectors")) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(quaternionToDraw.x, "quaternion.x")) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(quaternionToDraw.y, "quaternion.y")) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(quaternionToDraw.z, "quaternion.z")) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidFloats(quaternionToDraw.w, "quaternion.w")) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(posWhereToDraw, "posWhereToDraw")) { return; } if (UtilitiesDXXL_Log.ErrorLogForInvalidVectors(customVectorToRotate_local, "customVectorToRotate")) { return; } if (UtilitiesDXXL_Math.QuaternionIsApproxNormalized(quaternionToDraw) == false) { float quaternionMagnitude = Mathf.Sqrt(quaternionToDraw.x * quaternionToDraw.x + quaternionToDraw.y * quaternionToDraw.y + quaternionToDraw.z * quaternionToDraw.z + quaternionToDraw.w * quaternionToDraw.w); UtilitiesDXXL_DrawBasics.PointFallback(posWhereToDraw, "[ Invalid quaternion: quaternion is not normalized, but has magnitude = " + quaternionMagnitude + "]
" + text, color_ofTurnAxis, lineWidth, durationInSec, hiddenByNearerObjects); return; } color_ofTurnAxis = UtilitiesDXXL_Colors.OverwriteDefaultColor(color_ofTurnAxis); Quaternion rotation_ofLocalSpace = (parentTransform == null) ? Quaternion.identity : parentTransform.rotation; Quaternion quaternion_local = quaternionToDraw; bool rotation_ofLocalSpace_isIdentity = (UtilitiesDXXL_Math.IsDefaultInvalidQuaternion(rotation_ofLocalSpace) || UtilitiesDXXL_Math.IsQuaternionIdentity(rotation_ofLocalSpace)); quaternion_local.ToAngleAxis(out float localTurnAngleDeg, out Vector3 localTurnAxis_inLocalSpace); if (localTurnAngleDeg > 180.0f) { //-> "ToAngleAxis()" return an angle between 0 and 360 (probably because it internally uses 'acos'), though the common communication on quaternions is that they can represent a span "from -180 to +180". localTurnAngleDeg = localTurnAngleDeg - 360.0f; } float abs_localTurnAngleDeg = Mathf.Abs(localTurnAngleDeg); Vector3 localTurnAxis_inLocalSpace_normalized = UtilitiesDXXL_Math.GetNormalized_afterScalingIntoRegionOfFloatPrecicion(localTurnAxis_inLocalSpace); if (UtilitiesDXXL_Math.ApproximatelyZero(localTurnAxis_inLocalSpace_normalized)) { //Unity seems to fallback to "Quaternion.identiy" in this case UtilitiesDXXL_DrawBasics.PointFallback(posWhereToDraw, "[ Quaternion with invalid turn axis (length = 0)]
" + text, color_ofTurnAxis, lineWidth, durationInSec, hiddenByNearerObjects); return; } //Note that "normalized in local space" is the same as "normalized in global space", because scale_ofSpaces is not used here: Vector3 localTurnAxis_expressedInGlobalSpaceUnits_normalized = rotation_ofLocalSpace_isIdentity ? localTurnAxis_inLocalSpace_normalized : (rotation_ofLocalSpace * localTurnAxis_inLocalSpace_normalized); bool localQuaternion_isIdentity = UtilitiesDXXL_Math.IsQuaternionIdentity(quaternion_local); bool drawCustomVector = !UtilitiesDXXL_Math.ApproximatelyZero(customVectorToRotate_local); //grey dashed line: float halfLength_ofDashedLine = 10.0f; Color color_ofDashedLine = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(Color.white, 0.4f); Line_fadeableAnimSpeed.InternalDraw(posWhereToDraw - localTurnAxis_expressedInGlobalSpaceUnits_normalized * halfLength_ofDashedLine, posWhereToDraw + localTurnAxis_expressedInGlobalSpaceUnits_normalized * halfLength_ofDashedLine, color_ofDashedLine, 0.0f, null, DrawBasics.LineStyle.dashedLong, 5.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); //turn axis: lineWidth = Mathf.Max(lineWidth, 0.008f); string textAtTurnAxis; if (localQuaternion_isIdentity) { if (isLocal) { textAtTurnAxis = "This localquaternion is identity

= no rotation,
x,y,z,w: ( " + quaternion_local.x + " , " + quaternion_local.y + " , " + quaternion_local.z + " , " + quaternion_local.w + " )

" + text; } else { textAtTurnAxis = "This quaternion is identity

= no rotation,
x,y,z,w: ( " + quaternion_local.x + " , " + quaternion_local.y + " , " + quaternion_local.z + " , " + quaternion_local.w + " )

" + text; } } else { if (isLocal) { textAtTurnAxis = "localQuaternion turn axis

x,y,z,w: ( " + quaternion_local.x + " , " + quaternion_local.y + " , " + quaternion_local.z + " , " + quaternion_local.w + " )
localaxis vector: ( " + localTurnAxis_inLocalSpace_normalized.x + " , " + localTurnAxis_inLocalSpace_normalized.y + " , " + localTurnAxis_inLocalSpace_normalized.z + " )
" + text; } else { textAtTurnAxis = "Quaternion turn axis

x,y,z,w: ( " + quaternion_local.x + " , " + quaternion_local.y + " , " + quaternion_local.z + " , " + quaternion_local.w + " )
axis vector: ( " + localTurnAxis_inLocalSpace_normalized.x + " , " + localTurnAxis_inLocalSpace_normalized.y + " , " + localTurnAxis_inLocalSpace_normalized.z + " )
" + text; } } UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.relativeToLineLength); DrawBasics.Vector(posWhereToDraw - localTurnAxis_expressedInGlobalSpaceUnits_normalized, posWhereToDraw + localTurnAxis_expressedInGlobalSpaceUnits_normalized, color_ofTurnAxis, lineWidth, textAtTurnAxis, 0.11f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); DrawShapes.Sphere(posWhereToDraw, 2.0f * lineWidth, color_ofTurnAxis, localTurnAxis_expressedInGlobalSpaceUnits_normalized, default(Vector3), 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); if (localQuaternion_isIdentity == false) { //turn angle visualizer at turnAxisEnd: Vector3 aVectorPerpTo_localAxisExpressedInLocalUnits_normalized = UtilitiesDXXL_Math.Get_aNormalizedVector_perpToGivenVector(localTurnAxis_inLocalSpace_normalized); Vector3 aVectorPerpTo_localAxisExpressedInGlobalUnits_normalized = rotation_ofLocalSpace * aVectorPerpTo_localAxisExpressedInLocalUnits_normalized; Vector3 centerOfTurnAngleVisualizer_inGlobalSpace = posWhereToDraw - localTurnAxis_expressedInGlobalSpaceUnits_normalized; if (abs_localTurnAngleDeg < 0.5f) { UtilitiesDXXL_Text.Write(" turn angle: " + localTurnAngleDeg + "°", centerOfTurnAngleVisualizer_inGlobalSpace, color_ofTurnAxis, 0.02f, aVectorPerpTo_localAxisExpressedInGlobalUnits_normalized, -localTurnAxis_expressedInGlobalSpaceUnits_normalized, DrawText.TextAnchorDXXL.UpperLeft, DrawBasics.LineStyle.invisible, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, durationInSec, hiddenByNearerObjects, false, false, true); } else { float radiusOfTurnAngleVisualizer = 0.1f; Color color_turnAxisLowestAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofTurnAxis, 0.25f); DrawShapes.Circle(centerOfTurnAngleVisualizer_inGlobalSpace, radiusOfTurnAngleVisualizer, color_turnAxisLowestAlpha, localTurnAxis_expressedInGlobalSpaceUnits_normalized, aVectorPerpTo_localAxisExpressedInGlobalUnits_normalized, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); Vector3 centerOfTurnAngleVisualizer_to_startOfTurnAngleVisualizer_inLocalSpace = aVectorPerpTo_localAxisExpressedInLocalUnits_normalized * radiusOfTurnAngleVisualizer; Vector3 centerOfTurnAngleVisualizer_to_startOfTurnAngleVisualizer_inGlobalSpace = rotation_ofLocalSpace * centerOfTurnAngleVisualizer_to_startOfTurnAngleVisualizer_inLocalSpace; Vector3 centerOfTurnAngleVisualizer_to_endOfTurnAngleVisualizer_inLocalSpace = quaternion_local * centerOfTurnAngleVisualizer_to_startOfTurnAngleVisualizer_inLocalSpace; Vector3 centerOfTurnAngleVisualizer_to_endOfTurnAngleVisualizer_inGlobalSpace = rotation_ofLocalSpace * centerOfTurnAngleVisualizer_to_endOfTurnAngleVisualizer_inLocalSpace; Vector3 startOfTurnAngleVisualizer_inGlobalSpace = centerOfTurnAngleVisualizer_inGlobalSpace + centerOfTurnAngleVisualizer_to_startOfTurnAngleVisualizer_inGlobalSpace; Vector3 endOfTurnAxisTurnVisualizer_inGlobalSpace = centerOfTurnAngleVisualizer_inGlobalSpace + centerOfTurnAngleVisualizer_to_endOfTurnAngleVisualizer_inGlobalSpace; Color color_turnAxisLowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofTurnAxis, 0.5f); Line_fadeableAnimSpeed.InternalDraw(centerOfTurnAngleVisualizer_inGlobalSpace, startOfTurnAngleVisualizer_inGlobalSpace, color_turnAxisLowAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); Line_fadeableAnimSpeed.InternalDraw(centerOfTurnAngleVisualizer_inGlobalSpace, endOfTurnAxisTurnVisualizer_inGlobalSpace, color_turnAxisLowAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); DrawShapes.Sphere(centerOfTurnAngleVisualizer_inGlobalSpace, 1.3f * lineWidth, color_ofTurnAxis, localTurnAxis_expressedInGlobalSpaceUnits_normalized, default(Vector3), 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); DrawBasics.VectorCircled(startOfTurnAngleVisualizer_inGlobalSpace, centerOfTurnAngleVisualizer_inGlobalSpace, localTurnAxis_expressedInGlobalSpaceUnits_normalized, localTurnAngleDeg, color_ofTurnAxis, 0.3f * lineWidth, null, 0.05f, false, false, true, 0.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); string angleText = "" + localTurnAngleDeg + "°"; Color color_ofAngleText = UtilitiesDXXL_Colors.GetSimilarColorWithAdjustableOtherBrightnessValue(color_ofTurnAxis, 0.2f); Vector3 startPos_ofText = centerOfTurnAngleVisualizer_inGlobalSpace + centerOfTurnAngleVisualizer_to_startOfTurnAngleVisualizer_inGlobalSpace * 1.15f; Vector3 turnAxis_ofText = (localTurnAngleDeg < 0.0f) ? localTurnAxis_expressedInGlobalSpaceUnits_normalized : (-localTurnAxis_expressedInGlobalSpaceUnits_normalized); //-> prevent text from starting to away from circledArrow float size_ofTurnAngleVisualizerText = 0.28f * radiusOfTurnAngleVisualizer; UtilitiesDXXL_Text.WriteOnCircle(angleText, startPos_ofText, centerOfTurnAngleVisualizer_inGlobalSpace, turnAxis_ofText, color_ofAngleText, size_ofTurnAngleVisualizerText, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, 0.0f, true, durationInSec, hiddenByNearerObjects); } } //"forward" + "upward" + "custom" BEFORE rotation: Vector3 forward_unturnedInLocalSpace_inLocalSpaceUnits_normalized = Vector3.forward; Vector3 up_unturnedInLocalSpace_inLocalSpaceUnits_normalized = Vector3.up; Vector3 forward_unturnedInLocalSpace_expressedInGlobalSpaceUnits_normalized = rotation_ofLocalSpace * forward_unturnedInLocalSpace_inLocalSpaceUnits_normalized; Vector3 up_unturnedInLocalSpace_expressedInGlobalSpaceUnits_normalized = rotation_ofLocalSpace * up_unturnedInLocalSpace_inLocalSpaceUnits_normalized; float length_ofUpAndForwardVectors_global = (parentTransform == null) ? length_ofUpAndForwardVectors_local : (parentTransform.lossyScale.x * length_ofUpAndForwardVectors_local); Vector3 forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled = forward_unturnedInLocalSpace_inLocalSpaceUnits_normalized * length_ofUpAndForwardVectors_global; Vector3 up_unturnedInLocalSpace_inLocalSpaceUnits_scaled = up_unturnedInLocalSpace_inLocalSpaceUnits_normalized * length_ofUpAndForwardVectors_global; Vector3 forward_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled = rotation_ofLocalSpace * forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled; Vector3 up_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled = rotation_ofLocalSpace * up_unturnedInLocalSpace_inLocalSpaceUnits_scaled; Vector3 endPos_ofUnturnedLocalForwardVector_inGlobalSpace = posWhereToDraw + forward_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled; Vector3 endPos_ofUnturnedLocalUpwardVector_inGlobalSpace = posWhereToDraw + up_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled; Vector3 customVectorToRotate_local_butAlreadyScaledSoLengthFitsGlobalUnits = default; Vector3 customVector_unturnedInLocalSpace_expressedInGlobalSpaceUnits; if (parentTransform == null) { customVector_unturnedInLocalSpace_expressedInGlobalSpaceUnits = customVectorToRotate_local; } else { customVectorToRotate_local_butAlreadyScaledSoLengthFitsGlobalUnits = Vector3.Scale(parentTransform.lossyScale, customVectorToRotate_local); customVector_unturnedInLocalSpace_expressedInGlobalSpaceUnits = rotation_ofLocalSpace * customVectorToRotate_local_butAlreadyScaledSoLengthFitsGlobalUnits; } Vector3 endPos_ofUnturnedLocalCustomVector_inGlobalSpace = posWhereToDraw + customVector_unturnedInLocalSpace_expressedInGlobalSpaceUnits; Color color_forwardLowAlpha = default; Color color_forwardLowestAlpha = default; Color color_upLowAlpha = default; Color color_upLowestAlpha = default; Color color_customLowAlpha = default; Color color_customLowestAlpha = default; Color colorOfCustomRotatedVector = Color.yellow; bool drawUpAndForwardVectors = !UtilitiesDXXL_Math.ApproximatelyZero(length_ofUpAndForwardVectors_local); if (drawUpAndForwardVectors) { color_forwardLowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.8f); color_forwardLowestAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.blue_zAxisAlpha1, 0.6f); color_upLowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.8f); color_upLowestAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(UtilitiesDXXL_Colors.green_yAxisAlpha1, 0.3f); Color color_forwardDarkened = UtilitiesDXXL_Colors.Get_color_darkenedFromGivenColor(UtilitiesDXXL_Colors.blue_zAxisAlpha1, 2.5f); Color color_upDarkened = UtilitiesDXXL_Colors.Get_color_darkenedFromGivenColor(UtilitiesDXXL_Colors.green_yAxisAlpha1, 3.7f); string text_atUnrotatedForwardVector; string text_atUnrotatedUpVector; if (localQuaternion_isIdentity) { text_atUnrotatedForwardVector = isLocal ? ("Vector3.forward

unrotated
=after rotation
localx = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
localy = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
localz = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + "") : ("Vector3.forward

unrotated
=after rotation
x = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
y = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
z = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + ""); text_atUnrotatedUpVector = isLocal ? ("Vector3.up

unrotated
=after rotation
localx = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
localy = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
localz = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + "") : ("Vector3.up

unrotated
=after rotation
x = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
y = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
z = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + ""); } else { text_atUnrotatedForwardVector = isLocal ? ("Vector3.forward

unrotated (=identity)
localx = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
localy = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
localz = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + "") : ("Vector3.forward

unrotated (=identity)
x = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
y = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
z = " + forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + ""); text_atUnrotatedUpVector = isLocal ? ("Vector3.up

unrotated (=identity)
localx = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
localy = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
localz = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + "") : ("Vector3.up

unrotated (=identity)
x = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
y = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
z = " + up_unturnedInLocalSpace_inLocalSpaceUnits_scaled.z + ""); } UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); DrawBasics.Vector(posWhereToDraw, endPos_ofUnturnedLocalForwardVector_inGlobalSpace, color_forwardDarkened, 0.0f, text_atUnrotatedForwardVector, 0.09f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); DrawBasics.Vector(posWhereToDraw, endPos_ofUnturnedLocalUpwardVector_inGlobalSpace, color_upDarkened, 0.0f, text_atUnrotatedUpVector, 0.09f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); //dashed axis extention of unrotated forward/up: float lengthOfDashedExtention = 2.0f; string text_atZAxis = isLocal ? (" localz axis ") : (" z axis "); string text_atYAxis = isLocal ? (" localy axis ") : (" y axis "); Line_fadeableAnimSpeed.InternalDraw(endPos_ofUnturnedLocalForwardVector_inGlobalSpace, endPos_ofUnturnedLocalForwardVector_inGlobalSpace + forward_unturnedInLocalSpace_expressedInGlobalSpaceUnits_normalized * lengthOfDashedExtention, color_forwardLowestAlpha, 0.0f, text_atZAxis, DrawBasics.LineStyle.dashedLong, 2.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); Line_fadeableAnimSpeed.InternalDraw(endPos_ofUnturnedLocalUpwardVector_inGlobalSpace, endPos_ofUnturnedLocalUpwardVector_inGlobalSpace + up_unturnedInLocalSpace_expressedInGlobalSpaceUnits_normalized * lengthOfDashedExtention, color_upLowestAlpha, 0.0f, text_atYAxis, DrawBasics.LineStyle.dashedLong, 2.0f, 0.0f, null, default, false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); Color color_of90DegSymbolBeforeRotation = Color.Lerp(color_forwardDarkened, color_upDarkened, 0.5f); Draw90DegSymbolToQuaternionVectorPair(color_of90DegSymbolBeforeRotation, posWhereToDraw, forward_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, up_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, durationInSec, hiddenByNearerObjects); DrawSquareArea_spannedByUpAndForward(false, posWhereToDraw, forward_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, up_unturnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, color_forwardDarkened, color_upDarkened, 0.25f, 0.1f, durationInSec, hiddenByNearerObjects); } float custom_magnitude = 0.0f; if (drawCustomVector) { custom_magnitude = customVector_unturnedInLocalSpace_expressedInGlobalSpaceUnits.magnitude; color_customLowAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfCustomRotatedVector, 0.8f); color_customLowestAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(colorOfCustomRotatedVector, 0.3f); if (custom_magnitude > lineWidth) { string text_atUnrotatedCustomVector; if (localQuaternion_isIdentity) { text_atUnrotatedCustomVector = isLocal ? ("customVector

unrotated
=after rotation
localx = " + customVectorToRotate_local.x + "
localy = " + customVectorToRotate_local.y + "
localz = " + customVectorToRotate_local.z + "") : ("customVector

unrotated
=after rotation
x = " + customVectorToRotate_local.x + "
y = " + customVectorToRotate_local.y + "
z = " + customVectorToRotate_local.z + ""); } else { text_atUnrotatedCustomVector = isLocal ? ("customVector

unrotated
localx = " + customVectorToRotate_local.x + "
localy = " + customVectorToRotate_local.y + "
localz = " + customVectorToRotate_local.z + "") : ("customVector

unrotated
x = " + customVectorToRotate_local.x + "
y = " + customVectorToRotate_local.y + "
z = " + customVectorToRotate_local.z + ""); } Color colorOfCustomRotatedVector_darkened = UtilitiesDXXL_Colors.Get_color_darkenedFromGivenColor(colorOfCustomRotatedVector, 3.5f); UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); DrawBasics.Vector(posWhereToDraw, endPos_ofUnturnedLocalCustomVector_inGlobalSpace, colorOfCustomRotatedVector_darkened, 0.0f, text_atUnrotatedCustomVector, 0.09f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); } } if (localQuaternion_isIdentity == false) { //"forward" + "upward" + "custom" AFTER rotation: if (drawUpAndForwardVectors) { Vector3 forward_turnedInLocalSpace_inLocalSpaceUnits_scaled = quaternion_local * forward_unturnedInLocalSpace_inLocalSpaceUnits_scaled; Vector3 up_turnedInLocalSpace_inLocalSpaceUnits_scaled = quaternion_local * up_unturnedInLocalSpace_inLocalSpaceUnits_scaled; Vector3 forward_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled = rotation_ofLocalSpace * forward_turnedInLocalSpace_inLocalSpaceUnits_scaled; Vector3 up_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled = rotation_ofLocalSpace * up_turnedInLocalSpace_inLocalSpaceUnits_scaled; string text_atRotatedForwardVector = isLocal ? ("Vector3.forward

after rotation
localx = " + forward_turnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
localy = " + forward_turnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
localz = " + forward_turnedInLocalSpace_inLocalSpaceUnits_scaled.z + "") : ("Vector3.forward

after rotation
x = " + forward_turnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
y = " + forward_turnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
z = " + forward_turnedInLocalSpace_inLocalSpaceUnits_scaled.z + ""); string text_atRotatedUpVector = isLocal ? ("Vector3.up

after rotation
localx = " + up_turnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
localy = " + up_turnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
localz = " + up_turnedInLocalSpace_inLocalSpaceUnits_scaled.z + "") : ("Vector3.up

after rotation
x = " + up_turnedInLocalSpace_inLocalSpaceUnits_scaled.x + "
y = " + up_turnedInLocalSpace_inLocalSpaceUnits_scaled.y + "
z = " + up_turnedInLocalSpace_inLocalSpaceUnits_scaled.z + ""); UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); DrawBasics.Vector(posWhereToDraw, posWhereToDraw + forward_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, color_forwardLowAlpha, 0.0f, text_atRotatedForwardVector, 0.09f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); DrawBasics.Vector(posWhereToDraw, posWhereToDraw + up_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, color_upLowAlpha, 0.0f, text_atRotatedUpVector, 0.09f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); Color color_of90DegSymbolAfterRotation = Color.Lerp(color_forwardLowAlpha, color_upLowAlpha, 0.5f); Draw90DegSymbolToQuaternionVectorPair(color_of90DegSymbolAfterRotation, posWhereToDraw, forward_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, up_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, durationInSec, hiddenByNearerObjects); DrawSquareArea_spannedByUpAndForward(true, posWhereToDraw, forward_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, up_turnedInLocalSpace_expressedInGlobalSpaceUnits_scaled, color_forwardLowAlpha, color_upLowAlpha, 0.25f, 0.1f, durationInSec, hiddenByNearerObjects); } if (drawCustomVector) { if (custom_magnitude > lineWidth) { Vector3 customVector_turnedInLocalSpace_inLocalSpaceUnits = quaternion_local * customVectorToRotate_local; string text_atRotatedCustomVector = isLocal ? ("customVector

after rotation
localx = " + customVector_turnedInLocalSpace_inLocalSpaceUnits.x + "
localy = " + customVector_turnedInLocalSpace_inLocalSpaceUnits.y + "
localz = " + customVector_turnedInLocalSpace_inLocalSpaceUnits.z + "") : ("customVector

after rotation
x = " + customVector_turnedInLocalSpace_inLocalSpaceUnits.x + "
y = " + customVector_turnedInLocalSpace_inLocalSpaceUnits.y + "
z = " + customVector_turnedInLocalSpace_inLocalSpaceUnits.z + ""); Vector3 customVector_turnedInLocalSpace_expressedInGlobalSpaceUnits; if (parentTransform == null) { customVector_turnedInLocalSpace_expressedInGlobalSpaceUnits = customVector_turnedInLocalSpace_inLocalSpaceUnits; } else { customVector_turnedInLocalSpace_expressedInGlobalSpaceUnits = rotation_ofLocalSpace * quaternion_local * customVectorToRotate_local_butAlreadyScaledSoLengthFitsGlobalUnits; } UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forStraightVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); DrawBasics.Vector(posWhereToDraw, posWhereToDraw + customVector_turnedInLocalSpace_expressedInGlobalSpaceUnits, color_customLowAlpha, 0.0f, text_atRotatedCustomVector, 0.09f, false, false, default(Vector3), false, 0.0f, false, 0.0f, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forStraightVectors(); } } //circles/circled vectors: localTurnAxisLine_inGlobalSpaceUnits.Recreate(posWhereToDraw, localTurnAxis_expressedInGlobalSpaceUnits_normalized, true); if (drawUpAndForwardVectors) { DrawCircleInclVector_forTurnedVector(posWhereToDraw, endPos_ofUnturnedLocalForwardVector_inGlobalSpace, localTurnAxis_expressedInGlobalSpaceUnits_normalized, localTurnAngleDeg, UtilitiesDXXL_Colors.blue_zAxisAlpha1, color_forwardLowestAlpha, lineWidth, durationInSec, hiddenByNearerObjects); DrawCircleInclVector_forTurnedVector(posWhereToDraw, endPos_ofUnturnedLocalUpwardVector_inGlobalSpace, localTurnAxis_expressedInGlobalSpaceUnits_normalized, localTurnAngleDeg, UtilitiesDXXL_Colors.green_yAxisAlpha1, color_upLowestAlpha, lineWidth, durationInSec, hiddenByNearerObjects); } if (drawCustomVector) { DrawCircleInclVector_forTurnedVector(posWhereToDraw, endPos_ofUnturnedLocalCustomVector_inGlobalSpace, localTurnAxis_expressedInGlobalSpaceUnits_normalized, localTurnAngleDeg, colorOfCustomRotatedVector, color_customLowestAlpha, lineWidth, durationInSec, hiddenByNearerObjects); } //"forward" + "upward" + "custom" startPosOfRotation: if (drawUpAndForwardVectors) { DrawShapes.Sphere(endPos_ofUnturnedLocalForwardVector_inGlobalSpace, 1.0f * lineWidth, UtilitiesDXXL_Colors.blue_zAxisAlpha1, forward_unturnedInLocalSpace_expressedInGlobalSpaceUnits_normalized, default(Vector3), 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); DrawShapes.Sphere(endPos_ofUnturnedLocalUpwardVector_inGlobalSpace, 1.0f * lineWidth, UtilitiesDXXL_Colors.green_yAxisAlpha1, up_unturnedInLocalSpace_expressedInGlobalSpaceUnits_normalized, default(Vector3), 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); } if (drawCustomVector) { DrawShapes.Sphere(endPos_ofUnturnedLocalCustomVector_inGlobalSpace, 1.0f * lineWidth, colorOfCustomRotatedVector, default(Vector3), default(Vector3), 0.0f, null, 8, false, DrawBasics.LineStyle.solid, 1.0f, false, false, durationInSec, hiddenByNearerObjects); } } } public static void Draw90DegSymbolToQuaternionVectorPair(Color color, Vector3 quaternionCenterPos, Vector3 forwardVector_scaled, Vector3 upVector_scaled, float durationInSec, bool hiddenByNearerObjects) { float relSizeOf90degSymbol = 0.05f; Vector3 deg90_vertexOn_forwardVector = quaternionCenterPos + forwardVector_scaled * relSizeOf90degSymbol; Vector3 deg90_vertexOn_upVector = quaternionCenterPos + upVector_scaled * relSizeOf90degSymbol; Vector3 deg90_vertexAtKink = quaternionCenterPos + forwardVector_scaled * relSizeOf90degSymbol + upVector_scaled * relSizeOf90degSymbol; Line_fadeableAnimSpeed.InternalDraw(deg90_vertexOn_forwardVector, deg90_vertexAtKink, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); Line_fadeableAnimSpeed.InternalDraw(deg90_vertexOn_upVector, deg90_vertexAtKink, color, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); } public static void DrawSquareArea_spannedByUpAndForward(bool weakenMostOuterGreenLine, Vector3 quaternionCenterPos, Vector3 forwardVector_scaled, Vector3 upVector_scaled, Color color_ofSpanningForwardVector, Color color_ofSpanningUpVector, float alphaFactor, float alphaFactor_weakenedOverdraw, float durationInSec, bool hiddenByNearerObjects) { int linesPerSide = 10; Color color_ofSpanningForwardVector_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofSpanningForwardVector, alphaFactor); Color color_ofSpanningUpVector_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofSpanningUpVector, alphaFactor); float lengthFactorBetweenLines = 1.0f / (float)linesPerSide; Vector3 startPos_ofCurrForwardParallelLine = default; Vector3 endPos_ofCurrForwardParallelLine = default; Vector3 startPos_ofCurrUpParallelLine = default; Vector3 endPos_ofCurrUpParallelLine = default; for (int i = 0; i < linesPerSide; i++) { startPos_ofCurrForwardParallelLine = quaternionCenterPos + upVector_scaled * (lengthFactorBetweenLines * (i + 1)); endPos_ofCurrForwardParallelLine = startPos_ofCurrForwardParallelLine + forwardVector_scaled; Line_fadeableAnimSpeed.InternalDraw(startPos_ofCurrForwardParallelLine, endPos_ofCurrForwardParallelLine, color_ofSpanningForwardVector_lowerAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); startPos_ofCurrUpParallelLine = quaternionCenterPos + forwardVector_scaled * (lengthFactorBetweenLines * (i + 1)); endPos_ofCurrUpParallelLine = startPos_ofCurrUpParallelLine + upVector_scaled; Line_fadeableAnimSpeed.InternalDraw(startPos_ofCurrUpParallelLine, endPos_ofCurrUpParallelLine, color_ofSpanningUpVector_lowerAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); } //most outer line has higher alpha (realised via this second overdraw): Line_fadeableAnimSpeed.InternalDraw(startPos_ofCurrForwardParallelLine, endPos_ofCurrForwardParallelLine, color_ofSpanningForwardVector_lowerAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); if (weakenMostOuterGreenLine) //case of quaternion: the green outer line of the turned sqaure appears slighly to dominant if the same strong overdraw alpha is used, therefore this weakening: { color_ofSpanningUpVector_lowerAlpha = UtilitiesDXXL_Colors.Get_color_butWithAdjustedAlpha(color_ofSpanningUpVector, alphaFactor_weakenedOverdraw); } Line_fadeableAnimSpeed.InternalDraw(startPos_ofCurrUpParallelLine, endPos_ofCurrUpParallelLine, color_ofSpanningUpVector_lowerAlpha, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, 0.0f, null, default(Vector3), false, 0.0f, 0.0f, 0.0f, durationInSec, hiddenByNearerObjects, false, false); } static void DrawCircleInclVector_forTurnedVector(Vector3 posWhereToDraw, Vector3 endPos_ofUnturnedVector_inGlobalSpaceUnits, Vector3 localTurnAxis_expressedInGlobalSpaceUnits_normalized, float turnAngleDeg, Color color_ofThickVectorCircled, Color color_ofThinFullCircle, float lineWidth, float durationInSec, bool hiddenByNearerObjects) { Vector3 plumbPos_ofUnturnedVectorOnTurnAxis_inGlobalSpaceUnits = localTurnAxisLine_inGlobalSpaceUnits.Get_perpProjectionOfPoint_ontoThisLine(endPos_ofUnturnedVector_inGlobalSpaceUnits); Vector3 fromPlumbPos_toUnturnedVectorsPeak_inGlobalSpaceUnits = endPos_ofUnturnedVector_inGlobalSpaceUnits - plumbPos_ofUnturnedVectorOnTurnAxis_inGlobalSpaceUnits; float radius = fromPlumbPos_toUnturnedVectorsPeak_inGlobalSpaceUnits.magnitude; if (radius > 0.01f) { DrawShapes.Circle(plumbPos_ofUnturnedVectorOnTurnAxis_inGlobalSpaceUnits, radius, color_ofThinFullCircle, localTurnAxis_expressedInGlobalSpaceUnits_normalized, fromPlumbPos_toUnturnedVectorsPeak_inGlobalSpaceUnits, 0.0f, null, DrawBasics.LineStyle.solid, 1.0f, DrawBasics.LineStyle.invisible, false, false, durationInSec, hiddenByNearerObjects); float abs_turnAngleDeg = Math.Abs(turnAngleDeg); if (abs_turnAngleDeg >= 0.5f) { UtilitiesDXXL_DrawBasics.Set_coneLength_interpretation_forCircledVectors_reversible(DrawBasics.LengthInterpretation.absoluteUnits); DrawBasics.VectorCircled(endPos_ofUnturnedVector_inGlobalSpaceUnits, posWhereToDraw, localTurnAxis_expressedInGlobalSpaceUnits_normalized, turnAngleDeg, color_ofThickVectorCircled, lineWidth, null, 0.11f, false, false, false, 0.0f, DrawText.TextAnchorCircledDXXL.LowerLeftOfFirstLine, durationInSec, hiddenByNearerObjects); UtilitiesDXXL_DrawBasics.Reverse_coneLength_interpretation_forCircledVectors(); } } } } }